declare var DEBUG;
module EU {

    export function generatePositions(startPos, elementWidth, margin, amount) {
        var ret = [];

        for (var i = 0; i < amount; i++) {
            var t = startPos + i * (elementWidth + margin);
            ret.push(t);
        }

        return ret;
    }
    export function Log(message) {
        if (DEBUG)
            console.log(message);
    }

    export function shuffleArray(arr) {
        var t = arr.length;
        var temp = generateUniqueRandoms(0, t, t);
        var ret = [];
        for (var i = 0; i < t; i++) {
            ret.push(arr[temp[i]]);
        }
        return ret;
    }

    export function generateGridPositions(cols, rows, width, height, marginX, marginY, startPosX, startPosY, upDown) {
        var xPos = generatePositions(startPosX, width, marginX, cols);
        var yPos = generatePositions(startPosY, height, marginY, rows);

        var ret = [];
        var xLen = xPos.length;
        var yLen = yPos.length;

        if (upDown) {
            for (var i = 0; i < xLen; i++) {
                for (var j = 0; j < yLen; j++) {
                    var t = { x: xPos[i], y: yPos[j] };
                    ret.push(t);
                }
            }
        } else {
            for (var i = 0; i < yLen; i++) {
                for (var j = 0; j < xLen; j++) {
                    var t = { x: xPos[j], y: yPos[i] };
                    ret.push(t);
                }
            }
        }

        return ret;
    }
    export function setGameCompletion(context, value: number) {
        context.gameCompletion = value;
    }
    export function generateUniqueRandoms(min, max, amount) {
        var ret = [];
        if ((amount > max - min || max < min) && min !== 0) {
            return undefined;
        }

        for (var i = 0; i < amount; i++) {
            var maxIterations = 0;
            var s = min + Math.floor(Math.random() * max);
            while ($.inArray(s, ret) !== -1 && maxIterations < 500) {
                s = min + Math.floor(Math.random() * max);
                maxIterations++;
            }
            ret.push(s);
        }

        return ret;
    }

    //Aby funkcja dzialala struktura jsona musi sie ladować do Elements
    //Static Elements musza mieć strukture:
    //
    //"StaticElements": {
    //            "el": [
    //                {"type": "text", "text" "blabla", "key": "01", "sound": "sciezka do pliku", "pos": {"x": 0, "y": 0}}    //type może być text, image, sound
    //                                                                                                                        //jeżeli chcemy text to musimy dodać "text": "blabla"  
    //                                                                                                                        //jeżeli chcemy sound to musimy "sound": "sciezka do pliku"
    //                                                                                                                        //jeżeli chcemy image to musimy "key": "key zdogny z gfx" 
    //            ],
    //           "Options": {
    //                  "Just": {"x": "center", "y": "top"},                                            "x" - right, left lub center,   "y" - top, bottom, center
    //                  "Style": { font: "normal 70pt Arial", fill: "black" },                          // styl fontu jezeli text
    //               
    //            }


    export function createStaticSounds(game) {
        if (game.GameData.StaticSounds)
            for (var i = 0; i < game.GameData.StaticSounds.el.length; i++) {
                var el;
                el = game.game.add.sprite(0, 0, "speaker");
                el.inputEnabled = true;
                el.name = game.GameData.StaticSounds.el[i].sound;
                el.events.onInputUp.add(EU.soundButtonDown, game);
                var posX = game.GameData.StaticSounds.el[i].pos.x;
                var posY = game.GameData.StaticSounds.el[i].pos.y;
                if (game.GameData.StaticSounds.Options.Just) {
                    switch (game.GameData.StaticSounds.Options.Just.x) {
                        case "center":
                            posX += (Global.Main.mainContainerDims.wd - 120) / 2;
                            el.anchor.x = 0.5;
                            break;
                        case "right":
                            posX += Global.Main.mainContainerDims.wd - 120;
                            el.anchor.x = 1;
                            break;
                    }
                    switch (game.Elements.StaticElements.Options.Just.y) {
                        case "center":
                            posY += (Global.Main.mainContainerDims.hg - 65) / 2;
                            el.anchor.y = 0.5;
                            break;
                        case "bottom":
                            posY += Global.Main.mainContainerDims.hg - 65;
                            el.anchor.y = 1;
                            break;
                    }
                }
                el.position.set(posX, posY);
                game.addChild(el);
            }
    }

   
    export function createStaticElements(game) {
        if (game.Elements.StaticElements)
            for (var i = 0; i < game.Elements.StaticElements.el.length; i++) {
                var el;
                switch (game.Elements.StaticElements.el[i].type) {
                    case "image":
                        el = game.game.add.image(0, 0, game.PREFIX + game.Elements.StaticElements.el[i].key);
                        break;
                    case "text":
                        el = game.game.add.text(0, 0, game.Elements.StaticElements.el[i].text, game.Elements.StaticElements.Options.Style);
                        break;
                    case "sound":
                        el = game.game.add.sprite(0, 0, "speaker");
                        el.inputEnabled = true;
                        el.name = game.Elements.StaticElements.el[i].sound;
                        el.events.onInputUp.add(EU.soundButtonDown, game);
                        break;
                }
                var posX = game.Elements.StaticElements.el[i].pos.x;
                var posY = game.Elements.StaticElements.el[i].pos.y;
                if (game.Elements.StaticElements.Options.Just) {
                    switch (game.Elements.StaticElements.Options.Just.x) {
                        case "center":
                            posX += (Global.Main.mainContainerDims.wd - 120) / 2;
                            el.anchor.x = 0.5;
                            break;
                        case "right":
                            posX += Global.Main.mainContainerDims.wd - 120;
                            el.anchor.x = 1;
                            break;
                    }
                    switch (game.Elements.StaticElements.Options.Just.y) {
                        case "center":
                            posY += (Global.Main.mainContainerDims.hg - 65) / 2;
                            el.anchor.y = 0.5;
                            break;
                        case "bottom":
                            posY += Global.Main.mainContainerDims.hg - 65;
                            el.anchor.y = 1;
                            break;
                    }
                }
                el.position.set(posX, posY);
                game.addChild(el);
            }
    }

    export function soundButtonDown(button) {
        Global.Main.PlayMusic(new Audio(button.name));
    }




    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    //Function for creation of selectable elements - same req as createStaticElements


    //"SelectableElements":
    //{
    //
    //        "el": [
    //
    //            { "type": "text", "text": "Fajny tekst do zaznaczenia", 
    //              "pos": { "x": 0, "y": 0 }, 
    //               "correct": true },                     - new param - true if must be clicked
    //
    //        ],
    //
    //      "Options": {
    //            "Style": { font: "normal 60pt Arial", fill: "blue" },
    //            "Just": { "x": "center", "y": "top" }
    //
    //            "TextInputOverHandle": "",
    //            "TextInputOutHandle": "",
    //            "ImageInputOverHandle": "",
    //            "ImageInputOutHandle": "",
    //
    //
    //            "TextInputDownHandle": "",                - specifing type of function to handle clicks on TXT elements - adding cases in function EU.appendInputHandlersText
    //            "ImageInputDownHandle": "",               - specifing type of function to handle clicks on IMG elements - adding cases in function EU.appendInputHandlersImage
    //
    //        },
    //
    //    },
    export function createSelectableElements(game) {
        if (game.Elements.SelectableElements)
            for (var i = 0; i < game.Elements.SelectableElements.el.length; i++) {
                var el;
                switch (game.Elements.SelectableElements.el[i].type) {
                    case "image":
                        el = game.game.add.image(0, 0, game.PREFIX + game.Elements.SelectableElements.el[i].key);
                        this.appendInputHandlersImage(el, game);
                        break;
                    case "text":
                        el = game.game.add.text(0, 0, game.Elements.SelectableElements.el[i].text, game.Elements.SelectableElements.Options.Style);
                        this.appendInputHandlersText(el, game);
                        break;
                }
                el.name = "unchecked";
                var posX = game.Elements.SelectableElements.el[i].pos.x;
                var posY = game.Elements.SelectableElements.el[i].pos.y;
                if (game.Elements.SelectableElements.Options.Just) {
                    switch (game.Elements.SelectableElements.Options.Just.x) {
                        case "center":
                            posX += (Global.Main.mainContainerDims.wd - 120) / 2;
                            el.anchor.x = 0.5;
                            break;
                        case "right":
                            posX += Global.Main.mainContainerDims.wd - 120;
                            el.anchor.x = 1;
                            break;
                    }
                    switch (game.Elements.SelectableElements.Options.Just.y) {
                        case "center":
                            posY += (Global.Main.mainContainerDims.hg - 65) / 2;
                            el.anchor.y = 0.5;
                            break;
                        case "bottom":
                            posY += Global.Main.mainContainerDims.hg - 65;
                            el.anchor.y = 1;
                            break;
                    }
                }
                el.position.set(posX, posY);
                game.Elements.SelectableElements.el[i].name = el;
                game.addChild(el);
            }

    }



    //      Must add here case for handlers you want to use  for texts
    export function appendInputHandlersText(el, game) {
        el.inputEnabled = true;

        switch (game.Elements.SelectableElements.Options.TextInputOverHandle) {
            default:
                el.events.onInputOver.add(this.onInputOver, game);
        }

        switch (game.Elements.SelectableElements.Options.TextInputOutHandle) {
            default:
                el.events.onInputOut.add(this.onInputOut, game);
        }

        switch (game.Elements.SelectableElements.Options.TextInputDownHandle) {
            case "rect":
                el.events.onInputDown.add(this.onRectDown, { "game": game });
                break;
            case "underline":
                el.events.onInputDown.add(this.onUnderlineDown, { "game": game });
                break;
            case "crossing":
                el.events.onInputDown.add(this.onCrossingDown, { "game": game });
                break;
            case "shadow":
                el.events.onInputDown.add(this.onShadowDown, { "game": game });
                break;
            default:
                el.events.onInputDown.add(this.onInputDown, { "game": game });
        }
    }


    //      Must add here case for handlers you want to use  for IMGs
    export function appendInputHandlersImage(el, game) {
        el.inputEnabled = true;

        switch (game.Elements.SelectableElements.Options.ImageInputOverHandle) {
            default:
                el.events.onInputOver.add(this.onInputOver, game);
        }
        switch (game.Elements.SelectableElements.Options.ImageInputOutHandle) {
            default:
                el.events.onInputOut.add(this.onInputOut, game);
        }
        switch (game.Elements.SelectableElements.Options.ImageInputDownHandle) {
            case "rect":
                el.events.onInputDown.add(this.onRectDown, { "game": game });
                break;
            case "underline":
                el.events.onInputDown.add(this.onUnderlineDown, { "game": game });
                break;
            case "crossing":
                el.events.onInputDown.add(this.onCrossingDown, { "game": game });
                break;
            default:
                el.events.onInputDown.add(this.onInputDown, { "game": game });
        }
    }

    ////////////////////////////////////
    /// HANDLERS here
    ////////////////////////////////////
    export function onInputOver(el: Phaser.Image, pointer) {
        el.alpha = 0.5;
    }

    export function onInputOut(el: Phaser.Image, pointer) {
        el.alpha = 1.0;
    }

    export function onInputDown(el: Phaser.Image, pointer) {
        if (el.name == "unchecked") {
            el.name = "checked";
            el.scale.set(1.1, 1.1);
        }
        else {
            el.name = "unchecked";
            el.scale.set(1, 1);
            el.tint = 0xFFFFFF;
        }
        this.game.checkIfEverythingIsCorrect();
    }

    export function onShadowDown(el: Phaser.Text, pointer) {
        if (el.name == "unchecked") {
            el.name = "checked";
            el.scale.set(1.1, 1.1);
            el.setShadow(el.height / 20, el.height / 20, "green");
        }
        else {
            el.name = "unchecked";
            el.scale.set(1, 1);
            el.setShadow(0, 0, "black");
        }
        this.game.checkIfEverythingIsCorrect();
    }


    export function onCrossingDown(el: Phaser.Image, pointer) {
        if (el.name == "unchecked") {
            el.name = "checked";
            el.addChild(drawLine("red",
                -el.anchor.x * el.width,
                -el.anchor.y * el.height,
                el.width - el.width * el.anchor.x,
                el.height - el.anchor.y * el.height,
                this.game,12));
        }
        else {
            el.name = "unchecked";
            el.removeChildren();
        }
        this.game.checkIfEverythingIsCorrect();
    }


    export function onUnderlineDown(el: Phaser.Image, pointer) {
        if (el.name == "unchecked") {
            el.name = "checked";
            el.addChild(drawLine("red",
                -el.anchor.x * el.width,
                el.height - el.anchor.y * el.height,
                el.width - el.width * el.anchor.x,
                el.height - el.anchor.y * el.height,
                this.game,12));
        }
        else {
            el.name = "unchecked";
            el.removeChildren();
        }
        this.game.checkIfEverythingIsCorrect();
    }



    export function onRectDown(el: Phaser.Image, pointer) {
        if (el.name == "unchecked") {
            el.name = "checked";
            var rect = drawRect("red", 1.1 * el.width, 1.1 * el.height, el.height/5 , 8, this.game);
            rect.position.set(-1.1 * el.anchor.x * el.width, -1.1 *el.anchor.y * el.height)
            el.addChild(rect);
            
        }
        else {
            el.name = "unchecked";
            el.removeChildren();
        }
        this.game.checkIfEverythingIsCorrect();
    }
    
    export function drawLine(color,x1, y1, x2, y2, game,lineWidth) {
        
        var lineLength = Phaser.Math.distance(x1, y1, x2, y2);
        var lineAngle = Phaser.Math.angleBetween(x1, y1, x2, y2);
        var bmd = game.game.add.bitmapData(lineLength, lineWidth);
        bmd.ctx.beginPath();
        bmd.ctx.strokeStyle = color;
        bmd.ctx.stroke();
        var line = game.game.add.sprite(x1, y1, bmd);
        line.anchor.y = 0.5;
        line.smoothed = true;
        line.angle = Phaser.Math.radToDeg(lineAngle);
        bmd.ctx.beginPath();
        bmd.ctx.moveTo(0, lineWidth / 2);
        bmd.ctx.lineTo(lineLength, lineWidth / 2);
        bmd.ctx.lineWidth = lineWidth;
        bmd.ctx.stroke();
        bmd.ctx.closePath();
        bmd.render();
        return line;
    }

    export function drawRect(color, width, height, roundness, thickness, game) {
        
        //var width = 100; // example;
        //var height = 40; // example;
        var bmd = game.game.add.bitmapData(width, height);
        bmd.ctx.beginPath();
        bmd.ctx.moveTo(roundness, 0);
        bmd.ctx.lineTo(width - roundness, 0);
        bmd.ctx.quadraticCurveTo(width, 0, width, roundness);
        bmd.ctx.lineTo(width, height - roundness);
        bmd.ctx.quadraticCurveTo(width, height, width - roundness, height);
        bmd.ctx.lineTo(roundness, height);
        bmd.ctx.quadraticCurveTo(0, height, 0, height - roundness);
        bmd.ctx.lineTo(0, roundness);
        bmd.ctx.quadraticCurveTo(0, 0, roundness, 0);
        bmd.ctx.stroke();
        bmd.ctx.strokeStyle = color;
        bmd.ctx.lineWidth = thickness;
        //bmd.ctx.fillStyle = color;
        //bmd.ctx.fill();
        bmd.ctx.stroke();
        return game.game.add.sprite(0, 0, bmd);
    }

    ///////////////////////////////////////////////////
    ///// Function for checking logic if correct elemenets are marked as clicked and vice versa
    export function checkIfSelectablesAreCorrect(game) {
        if (game.Elements.SelectableElements)
        for (var i = 0; i < game.Elements.SelectableElements.el.length; i++) {
            if ((game.Elements.SelectableElements.el[i].name.name == "checked" && game.Elements.SelectableElements.el[i].correct == true) ||
                (game.Elements.SelectableElements.el[i].name.name == "unchecked" && game.Elements.SelectableElements.el[i].correct == false)) {
            }
            else {
                return false;
            }
        }
        return true;
    }

   
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    //////////////////          FILLELEMENTS
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


    // Function for creating fill Elements - the same requ as for Selectable elements
    var KBoard: KB.Keyboard;
    export function createFillElements(game) {
       
        if (game.Elements.FillElements) {
            var BoxSize = 8 / 5 * game.Elements.FillElements.Options.CharacterSize;
            var LetterAmountmultipler = 70 * (game.Elements.FillElements.Options.MaxCharacters / 2);
            var inputBoxStyle = { "font": null, "fill": "black" };
            inputBoxStyle.font = "normal " + game.Elements.FillElements.Options.CharacterSize + "pt Arial";
            var bmd = game.game.add.bitmapData(LetterAmountmultipler, BoxSize);
            bmd.ctx.rect(0, 0, LetterAmountmultipler, BoxSize);
            bmd.ctx.fillStyle = '#cdcdcd';
            bmd.ctx.fill();
            for (var i = 0; i < game.Elements.FillElements.el.length; i++) {
                var posX = game.Elements.FillElements.el[i].pos.x;
                var posY = game.Elements.FillElements.el[i].pos.y;
                var box = game.game.add.sprite(0, 0, bmd);
                //box.anchor.set(0.5, 0.5);
                box.alpha = 0.5;
                box.width = LetterAmountmultipler;
                var item = game.game.add.text(0, 0, "?", inputBoxStyle);
                //item.anchor.set(0.5, 0.5);
                item.father = box;
                box.text = item;
                box.inputEnabled = true;
                game.Elements.FillElements.el[i].name = item;
                box.events.onInputUp.add(showKeyboard, { "game": game, "KB": KBoard});
                game.addChild(box);
                game.addChild(item);
                if (game.Elements.FillElements.Options.Just) {
                    switch (game.Elements.FillElements.Options.Just.x) {
                        case "center":
                            posX += (Global.Main.mainContainerDims.wd - 120) / 2;
                            box.anchor.x = 0.5;
                            item.anchor.x = 0.5;
                            break;
                        case "right":
                            posX += Global.Main.mainContainerDims.wd - 120;
                            box.anchor.x = 1;
                            item.anchor.x = 1;
                            break;
                    }
                    switch (game.Elements.FillElements.Options.Just.y) {
                        case "center":
                            posY += (Global.Main.mainContainerDims.hg - 65) / 2;
                            box.anchor.y = 0.5;
                            item.anchor.y = 0.5;
                            break;
                        case "bottom":
                            posY += Global.Main.mainContainerDims.hg - 65;
                            box.anchor.y = 1;
                            item.anchor.y = 1;
                            break;
                    }
                }
                box.position.set(posX, posY);
                item.position.set(posX, posY); 
            }
        }
    }

    //function for initialization of keyboard
    export function keyboardInit(game, button) {
        KBoard = new KB.Keyboard(game.game, game.Elements.FillElements.Options.AcceptedCharacters, 500, 0, true);
        if (game.Elements.FillElements.Options.AcceptedCharacters.length >= 2) {
            
            KBoard.initialize(game.Elements.FillElements.Options.AcceptedCharacters, "key", "key");
        }
        else {
            KBoard.initialize("qwertyuiop" + KBoard.arrSeparator + "asdfghjkl" + KBoard.arrSeparator + "zxcvbnm^& .,", "key", "key");
        }       
        KBoard.scale.setTo(0.5, 0.5);
        KBoard.alive = false;
        KBoard.fixedToCamera = true;
        KBoard.maxLetters = game.Elements.FillElements.Options.MaxCharacters;
        game.game.add.existing(KBoard);
    }
 
    //Checking if keyboard exists and showing it
    export function showKeyboard(button) {
        if (KBoard == undefined) {
            keyboardInit(this.game, button);
        } 
        KBoard.controller = button.text;
        KBoard.RootController = this.game;
        KBoard.navClick();
        EU.Log(KBoard);
    }

    export function killKeyboard() {
        if (KBoard != undefined) {
            KBoard.destroy(false, false);
            KBoard = undefined;
        }
    }

    //logic - same principles as in Selectable Elements
    export function checkIfFillsAreCorrect(game) {
        if (game.Elements.FillElements) {
            killKeyboard();
            for (var i = 0; i < game.Elements.FillElements.el.length; i++) {
                if (game.Elements.FillElements.el[i].name.text != game.Elements.FillElements.el[i].Answer)
                    return false;
            }
        }
        return true; 
    }

    //////////////////////////////////////////////////////////////////////////////////////////////////////
    //ANGIELSKI
    //////////////////////////////////////////////////////////////////////////////////////////////////////
    export var groups: any;    /////////////// kontener na słownik
    export var usedWords: any;

    export function loadVocabulary(game) {
        usedWords = [];
        groups = game.Elements.Groups;

    }












}

