/// @name libGMmath
/// @prefix mathis_
/// @version 1.0.0

var libGMmath = (function() {
    var me = {
        ready: false,
        next_id: 0,
        results: {},
        events: [],
        average_time: 0,
        event_skill_selected: false,
        event_session_ready: false,
        event_skill_changed: false,
        event_progress_closed: false,
        event_available_standards_closed: false,
        event_average_time_change: false,
        event_question_resized: false,
        event_choices_resized: false,
        data_question: "",
        data_choices: ""
    };

    /// @export initialize(str:game_dom_id,str:api_key,int:debug) : int
    me.initialize = function (game_dom_id, api_key, debug) {
        me.api = MathGamesAPI.getInstance({
            wrapper: document.getElementById(game_dom_id),
            api_key: api_key,
            debug: (debug > 0)
        });
        
        me.api.on("SKILL_SELECTED", function() { me.event_skill_selected = true; });
        me.api.on("SESSION_READY", function() { me.event_session_ready = true; });
        me.api.on("SKILL_CHANGED", function() { me.event_skill_changed = true; });
        me.api.on("PROGRESS_CLOSED", function() { me.event_progress_closed = true; });
        me.api.on("AVAILABLE_STANDARDS_CLOSED", function() { me.event_available_standards_closed = true; });
        me.api.on("AVERAGE_TIME_CHANGE", function(t) { me.event_average_time_change = true; me.average_time = t; });
    };
    
    /// @export selectSkill(str:pool_key) : int
    me.selectSkill = function(pool_key) {
        me.api.selectSkill({pool_key:pool_key});
        me.event_skill_selected = false;
    };
    
    /// @export startSession() : int
    me.startSession = function() {
        me.api.startSession();
        me.event_session_ready = false;
    }
    
    /// @export showProgress() : int
    me.showProgress = function() {
        me.api.showProgress();
        me.event_progress_closed = false;
    }
    
    /// @export showAvailableStandards() : int
    me.showAvailableStandards = function() {
        me.api.showAvailableStandards();
        me.event_available_standards_closed = false;
    }
    
    /// @export endSession() : int
    me.endSession = function() {
        me.api.endSession();
    }
    
    /// @export eventSkillSelected() : int
    me.eventSkillSelected = function() {
        var a = me.event_skill_selected;
        me.event_skill_selected = false;
        return a; 
    }
    
    /// @export eventSessionReady() : int
    me.eventSessionReady = function() {
        var a = me.event_session_ready;
        me.event_session_ready = false;
        return a; 
    }
    
    /// @export eventSkillChanged() : int
    me.eventSkillChanged = function() {
        var a = me.event_skill_changed;
        me.event_skill_changed = false;
        return a; 
    }
    
    /// @export eventProgressClosed() : int
    me.eventProgressClosed = function() {
        var a = me.event_progress_closed;
        me.event_progress_closed = false;
        return a;
    }
    
    /// @export eventAvailableStandardsClosed() : int
    me.eventAvailableStandardsClosed = function() {
        var a = me.event_available_standards_closed;
        me.event_available_standards_closed = false;
        return a;
    }
    
    /// @export eventAverageTimeChanged() : int
    me.eventAverageTimeChanged = function() {
        var a = me.event_average_time_change;
        me.event_average_time_change = false;
        return a;
    }
    
    /// @export eventQuestionResized() : int
    me.eventQuestionResized = function() {
        var a = me.event_question_resized;
        me.event_question_resized = false;
        return a; 
    }
    
    /// @export eventChoicesResized() : int
    me.eventChoicesResized = function() {
        var a = me.event_choices_resized;
        me.event_choices_resized = false;
        return a; 
    }
    
    /// @export averageTime() : int
    me.averageTime = function() {
        return me.average_time;
    }
    
    function parse_colour(col) {
        var bigint = parseInt(col, 16);
        var r = (bigint >> 24) & 255;
        var g = (bigint >> 16) & 255;
        var b = (bigint >> 8) & 255;
        var a = (bigint & 255) / 255.0;
        return [r, g, b, a];
    }

    /// @export getQuestion(str:hex_colour, str:hex_colour_opt1, str:hex_colour_opt2, str:hex_colour_opt3, str:hex_colour_opt4)
    me.getQuestion = function(mcol, acol1, acol2, acol3, acol4) {
        mcol = parse_colour(mcol);
        acol1 = parse_colour(acol1);
        acol2 = parse_colour(acol2);
        acol3 = parse_colour(acol3);
        acol4 = parse_colour(acol4);
        
        var q = me.api.getQuestion({ colors: { question: mcol, choices: [acol1, acol2, acol3, acol4]}});
        me.data_question = q.display;
        me.data_choices = q.choices;
    }
    
    /// @export getQuestionData()
    me.getQuestionData = function() { return me.data_question; }
    
    /// @export getQuestionNumChoices()
    me.getQuestionNumChoices = function() { return me.data_choices.length; }
    
    /// @export getQuestionChoiceData(int:num)
    me.getQuestionChoiceData = function(num) { return me.data_choices[num]; }
    
    /// @export answerQuestion(int:choice)
    me.answerQuestion = function choice(num)
    {
        return me.api.answerQuestion(num);
    }
    
    
    /// Tools to determine with/height from datastring
    
    function getPngDimensions(base64) {
      const header = atob(base64.slice(0, 50)).slice(16,24)
      const uint8 = Uint8Array.from(header, c => c.charCodeAt(0))
      const dataView = new DataView(uint8.buffer)

      return {
        width: dataView.getInt32(0),
        height: dataView.getInt32(4)
      }
    }
    
    function resizedataURL(datas, wantedWidth, wantedHeight){
        return new Promise(async function(resolve,reject){
            var img = document.createElement('img');
            img.onload = function()
            {        
                var canvas = document.createElement('canvas');
                var ctx = canvas.getContext('2d');

                canvas.width = wantedWidth;
                canvas.height = wantedHeight;
                ctx.drawImage(this, 0, 0, wantedWidth, wantedHeight);
                var dataURI = canvas.toDataURL();
                resolve(dataURI);
            };
            img.src = datas;

        })
    }
    
    /// @export resizeQuestionData(int:minwidth, int:maxwidth)
    me.resizeQuestionData = function(minwidth, maxwidth) { 
        async function doit()
        {
            var imgurl = me.data_question;
            var size = getPngDimensions(imgurl.split(',')[1]);
            var width = size.width;
            var height = size.height;
            
            for(var i = 0; i < 100; i++)
            {
                if (width > maxwidth)
                {
                    width /= 2.0;
                    height /= 2.0;
                }
                else if (width < minwidth)
                {
                    width *= 1.5;
                    height *= 1.5;
                }
                else
                {
                    break;
                }
            }
            
            var data = await resizedataURL(imgurl, width, height);
            me.data_question = data;
            me.event_question_resized = true;
        }
        doit();
    }
    
    /// @export resizeChoicesData(int:minwidth, int:maxwidth)
    me.resizeChoicesData = function(minwidth, maxwidth) { 
        async function doit()
        {
            var width = 0;
            
            for (var j = 0; j < me.data_choices.length; j++)
            {
                var imgurl = me.data_choices[j]; 
                var size = getPngDimensions(imgurl.split(',')[1]);
                width = Math.max(size.width, width);
            }
            
            var w = width;
            
            for(var i = 0; i < 100; i++)
            {
                if (width > maxwidth)
                {
                    width /= 2.0;
                }
                else if (width < minwidth)
                {
                    width *= 1.5;
                }
                else
                {
                    break;
                }
            }
            
            var scale = (1.0 * width) / w;
            
            for (var j = 0; j < me.data_choices.length; j++)
            {
                var imgurl = me.data_choices[j]; 
                var size = getPngDimensions(imgurl.split(',')[1]);
                me.data_choices[j] = await resizedataURL(imgurl, scale * size.width, scale * size.height);
            }
            me.event_choices_resized = true;
        }
        doit();
    }
    
    
    return me;
}());