module ColorText {
    export class ColorText extends Base.BasicGroup {

        Elements: any;
        PREFIX: any;
        SourceText: any[];
        PalleteColors: any[];

        numberOfChecked: any;
        numberOfCorrectChars: any;

        color: any;

        constructor(game, name, x, y, json) {
            super(game, name, x, y, json);
        }

        preload() {
            super.preload();
            this.game.load.onLoadComplete.addOnce(this.create, this);
            this.PREFIX = this.Elements.TaskPrefix;
            this.loadGraphics();
            this.game.load.start();
        }
        loadGraphics() {

            for (var i = 0; i < this.Elements.Graphics.length; i++)
                this.game.load.image(this.PREFIX + this.Elements.Graphics[i].key, this.Elements.Graphics[i].src);
        }

        create() {
            if (this.json.isStandalone) {
                super.create();
            }
            EU.createStaticElements(this);
            EU.createSelectableElements(this);
            EU.createFillElements(this);
            this.numberOfChecked = 0;
            this.createSourceText();
            this.createTextToFind();
            this.color = "red";
            if(this.Elements.Colors.length > 1)
            this.createColorPallete(); 
        }

        init(json) {
            super.init(json);
            this.Elements = json.GameData;
        }

        createColorPallete() {
            this.PalleteColors = [];
            for (var i = 0; i < this.Elements.Colors.length; i++) {
                var el = this.drawRect(this.Elements.Colors[i], 100, 40);
                el.anchor.x = 0.5;
                el.anchor.y = 0.5;
                el.alpha = 0.7;
                el.name = this.Elements.Colors[i];
                if (i == 0) {
                    el.scale.x = 1.2;
                    el.scale.y = 1.2;
                    el.alpha = 1;
                    this.color = el.name;
                }
                el.position.set(this.Elements.PalletePosition.x, this.Elements.PalletePosition.y + i * 50);
                el.inputEnabled = true;
                el.events.onInputOver.add(this.onColorOver, this);
                el.events.onInputOut.add(this.onColorOut, this);
                el.events.onInputDown.add(this.onColorClicked, this);
                this.PalleteColors.push(el);
                this.addChild(el);
            }
        }

        private clearColorSelection() {
            for (var i = 0; i < this.PalleteColors.length; i++) {
                this.PalleteColors[i].scale.x = 1;
                this.PalleteColors[i].scale.y = 1;
                this.PalleteColors[i].alpha = 0.7;
            }
        }

        private onColorClicked(el: Phaser.Sprite, pointer) {
            this.clearColorSelection();
            if (el.scale.x == 1) {

                el.scale.x = 1.2;
                el.scale.y = 1.2;
                el.alpha = 1;

                this.color = el.name;
            }
            else {
                el.scale.x = 1;
                el.scale.y = 1;
                el.alpha = 0.7;
            }

        }

        private onColorOver(el: Phaser.Sprite, pointer) {
            if (el.scale.x == 1) {
                el.alpha = 0.5;
            }
        }

        private onColorOut(el: Phaser.Sprite, pointer) {
            if (el.scale.x == 1) {
                el.alpha = 0.7;
            }
        }

        drawRect(color, width, height) {
            var drawnObject;
            //var width = 100; // example;
            //var height = 40; // example;
            var bmd = this.game.add.bitmapData(width, height);
            bmd.ctx.beginPath();
            bmd.ctx.moveTo(10, 0);
            bmd.ctx.lineTo(width - 10, 0);
            bmd.ctx.quadraticCurveTo(width, 0, width, 10);
            bmd.ctx.lineTo(width, height - 10);
            bmd.ctx.quadraticCurveTo(width, height, width - 10, height);
            bmd.ctx.lineTo(10, height);
            bmd.ctx.quadraticCurveTo(0, height, 0, height - 10);
            bmd.ctx.lineTo(0, 10);
            bmd.ctx.quadraticCurveTo(0, 0, 10, 0);
            bmd.ctx.stroke();
            bmd.ctx.fillStyle = color;
            bmd.ctx.fill();
            bmd.ctx.stroke();
            return this.game.add.sprite(0, 0, bmd);
        }

        createTextToFind() {
            for (var k = 0; k < this.Elements.SourceText.length; k++) {
                this.SourceText[k].toFind = this.Elements.SourceText[k].TextToFind;
            }
        }

        createSourceText() {
            this.SourceText = [];
            for (var k = 0; k < this.Elements.SourceText.length; k++) {
                var Text = [];
                var verses = this.Elements.SourceText[k].Text.split("@");
                var posX = this.Elements.SourceText[k].Position.x;
                var posY = this.Elements.SourceText[k].Position.y;
                var style = this.Elements.SourceText[k].Style;
                var counter = 0;
                for (var i = 0; i < verses.length; i++) {
                    var words = verses[i].split("");
                    words.push(' ');
                    counter++;
                    var el = this.game.add.text(0, 0, words[0], style);
                    var versePosY = posY + i * el.height;
                    el.position.set(posX, versePosY);
                    el.inputEnabled = true;
                    el.events.onInputOver.add(this.onInputOver, this);
                    el.events.onInputOut.add(this.onInputOut, this);
                    if (this.Elements.MarkType == "crossable") {
                        el.events.onInputDown.add(this.onWordClickedCrossable, this);
                    }
                    else {
                        el.events.onInputDown.add(this.onWordClicked, this);
                    };
                    el.name = "unchecked";
                    if (el.text == ' ') el.name = "space";
                    Text.push(el);
                    //this.SourceText[k].push(el);
                    this.addChild(el);
                    for (var j = 1; j < words.length; j++) {
                        el = this.game.add.text(0, 0, words[j], style);
                        el.position.set(
                            Text[counter - 1].position.x +
                            Text[counter - 1].width,
                            versePosY
                            );
                        el.inputEnabled = true;
                        el.events.onInputOver.add(this.onInputOver, this);
                        el.events.onInputOut.add(this.onInputOut, this);
                        if (this.Elements.MarkType == "crossable") {
                            el.events.onInputDown.add(this.onWordClickedCrossable, this);
                        }
                        else {
                            el.events.onInputDown.add(this.onWordClicked, this);
                        };
                        el.name = "unchecked";
                        if (el.text == ' ') el.name = "space";
                        Text.push(el);
                        this.addChild(el);
                        counter++;
                    }
                }
                this.SourceText.push({ "Text": Text, "toFind": null });
            }
        }
        //input

        private onInputOver(el: Phaser.Text, pointer) {
            el.alpha = 0.5;
        }

        private onInputOut(el: Phaser.Text, pointer) {
            el.alpha = 1.0;
        }

        private onWordClicked(el: Phaser.Text, pointer) {
            if (el.text != " ") {
                if (el.name == "unchecked") {
                    el.setShadow(el.height / 25, el.height / 25, this.color);
                    this.numberOfChecked++;
                    el.name = "checked" + this.color;
                    if (this.Elements.MarkWholeWords == true) this.markWholeWords();
                }
                else {
                    el.setShadow(0, 0, "black");
                    this.numberOfChecked--;
                    el.name = "unchecked";
                    if (this.Elements.MarkWholeWords == true) this.unmarkWholeWords();
                } 
                this.checkIfEverythingIsCorrect();
            }
        }


        private onWordClickedCrossable(el: Phaser.Text, pointer) {
            if (el.text != " ") {
                if (el.name == "unchecked") {
                    this.numberOfChecked++;
                    el.name = "checked" + this.color;
                    if (this.Elements.MarkWholeWords == true) {
                        this.markWholeWordsCrossable();
                    }
                    else {
                        el.addChild(EU.drawLine(this.color,
                            -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, el.height / 10));
                    }

                }
                else {
                    this.numberOfChecked--;
                    el.name = "unchecked";
                    if (this.Elements.MarkWholeWords == true) {
                        this.unmarkWholeWordsCrossable();
                        el.removeChildren();
                    }
                    else {
                        el.removeChildren();
                    }
                }
                this.checkIfEverythingIsCorrect();
            }
        }

        private unmarkWholeWords() {
            for (var i = 0; i < this.SourceText.length; i++) {
                for (var j = 0; j < this.SourceText[i].Text.length; j++) {
                    if (this.SourceText[i].Text[j].name == "unchecked") {
                        var k = -1;
                        while (j + k >= 0 && this.SourceText[i].Text[j + k].name != "space" ) {
                            if (this.SourceText[i].Text[j + k].name != "unchecked") {
                                this.SourceText[i].Text[j + k].setShadow(0, 0, "black");
                                this.numberOfChecked--;
                                this.SourceText[i].Text[j + k].name = "unchecked";
                            }
                            k--;
                        }
                        k = 1;
                        while (j + k < this.SourceText[i].Text.length - 1 && this.SourceText[i].Text[j + k].name != "space") {
                            if (this.SourceText[i].Text[j + k].name != "unchecked") {
                                this.SourceText[i].Text[j + k].setShadow(0, 0, "black");
                                this.numberOfChecked--;
                                this.SourceText[i].Text[j + k].name = "unchecked";
                            }
                            k++;
                         }
                        j += k;
                    }
                }
            }
        }

        private markWholeWords() {
            for (var i = 0; i < this.SourceText.length; i++) {
                for (var j = 0; j < this.SourceText[i].Text.length; j++) {
                    if (this.SourceText[i].Text[j].name == "checked" + this.color) {
                        var k = -1;
                        while (j + k >= 0 && this.SourceText[i].Text[j + k].name != "space") {
                            if (this.SourceText[i].Text[j + k].name != "checked" + this.SourceText[i].Text[j].shadowColor) {
                                this.SourceText[i].Text[j + k].setShadow(this.SourceText[i].Text[j + k].height / 25, this.SourceText[i].Text[j + k].height / 25, this.SourceText[i].Text[j].shadowColor);
                                this.numberOfChecked++;
                                this.SourceText[i].Text[j + k].name = this.SourceText[i].Text[j].name;
                            }
                            k--;
                        }
                        k = 1;
                        while (j + k < this.SourceText[i].Text.length - 1 && this.SourceText[i].Text[j + k].name != "space") {
                            if (this.SourceText[i].Text[j + k].name != "checked" + this.SourceText[i].Text[j].shadowColor) {
                                this.SourceText[i].Text[j + k].setShadow(this.SourceText[i].Text[j + k].height / 25, this.SourceText[i].Text[j + k].height / 25, this.SourceText[i].Text[j].shadowColor);
                                this.numberOfChecked++;
                                this.SourceText[i].Text[j + k].name = this.SourceText[i].Text[j].name;
                            }
                            k++;
                        }
                        j += k;
                    }
                }
            }
        }

        private markWholeWordsCrossable() {
            for (var i = 0; i < this.SourceText.length; i++) {
                for (var j = 0; j < this.SourceText[i].Text.length; j++) {
                    if (this.SourceText[i].Text[j].name == "checked" + this.color) {
                        var k = -1;
                        var width = this.SourceText[i].Text[j].width;
                        var widthleft = 0;
                        var widthright = 0;
                        while (j + k >= 0 && this.SourceText[i].Text[j + k].name != "space") {
                            if (this.SourceText[i].Text[j + k].name != "checked" + this.color) {
                                this.numberOfChecked++;
                                this.SourceText[i].Text[j + k].name = this.SourceText[i].Text[j].name;
                            }
                            width += this.SourceText[i].Text[j + k].width;
                            widthleft += this.SourceText[i].Text[j + k].width;
                            k--;
                        }
                        k = 1;
                        while (j + k < this.SourceText[i].Text.length - 1 && this.SourceText[i].Text[j + k].name != "space") {
                            if (this.SourceText[i].Text[j + k].name != "checked" + this.color) {
                                this.numberOfChecked++;
                                this.SourceText[i].Text[j + k].name = this.SourceText[i].Text[j].name;
                            }
                            
                            width += this.SourceText[i].Text[j + k].width;
                            widthright += this.SourceText[i].Text[j + k].width;
                            k++;
                        }
                        if (this.SourceText[i].Text[j].name == "checked" + this.color) {
                            this.SourceText[i].Text[j].removeChildren();
                            this.SourceText[i].Text[j].addChild(EU.drawLine(this.color,
                                -widthleft - this.SourceText[i].Text[j].anchor.x * this.SourceText[i].Text[j].width,
                                - this.SourceText[i].Text[j].anchor.y * this.SourceText[i].Text[j].height,
                                widthright + (1-this.SourceText[i].Text[j].anchor.x) * this.SourceText[i].Text[j].width,
                                this.SourceText[i].Text[j].height - this.SourceText[i].Text[j].anchor.y * this.SourceText[i].Text[j].height,
                                this, this.SourceText[i].Text[j].height / 10));
                        }
                        j += k;
                    }
                }
            }
        }

        private unmarkWholeWordsCrossable() {
            for (var i = 0; i < this.SourceText.length; i++) {
                for (var j = 0; j < this.SourceText[i].Text.length; j++) {
                    if (this.SourceText[i].Text[j].name == "unchecked") {
                        var k = -1;
                        while (j + k >= 0 && this.SourceText[i].Text[j + k].name != "space") {
                            if (this.SourceText[i].Text[j + k].name != "unchecked") {
                                this.SourceText[i].Text[j + k].removeChildren();
                                this.numberOfChecked--;
                                this.SourceText[i].Text[j + k].name = "unchecked";
                            }
                            k--;
                        }
                        k = 1;
                        while (j + k < this.SourceText[i].Text.length - 1 && this.SourceText[i].Text[j + k].name != "space") {
                            if (this.SourceText[i].Text[j + k].name != "unchecked") {
                                this.SourceText[i].Text[j + k].removeChildren();
                                this.numberOfChecked--;
                                this.SourceText[i].Text[j + k].name = "unchecked";
                            }
                            k++;
                        }
                        j += k;
                    }
                }
            }
        }


        private findIndexes(source, toFind) {
            var result = [];
            for (var i = 0; i < source.length; i++) {
                if (source.substring(i, i + toFind.length) == toFind) {
                    result.push(i);
                }
            }
            return result;
        }

        private checkIfEverythingIsCorrect() {
            EU.Log("Points: " + this.calculatePlayerPoints()+ "/" + this.calculateMaxPoints());
            EU.Log("Checked: " + this.numberOfChecked + "/" + this.numberOfCorrectChars);
            if (this.calculatePlayerPoints() == this.calculateMaxPoints() && this.numberOfChecked == this.numberOfCorrectChars &&
                EU.checkIfFillsAreCorrect(this) && EU.checkIfSelectablesAreCorrect(this))
            {
                EU.setGameCompletion(this.parent, 1);
                EU.Log("Correct!!!");
                return true;
            }
            EU.setGameCompletion(this.parent, 0);
            return false;
        }

        private calculateMaxPoints() {
            this.numberOfCorrectChars = 0;
            var points = 0;
            for (var i = 0; i < this.Elements.SourceText.length; i++) {
                for (var j = 0; j < this.SourceText[i].toFind.length; j++) {
                    for (var z = 0; z < this.SourceText[i].toFind[j].Text.length; z++) {
                        var indexes = this.findIndexes(this.Elements.SourceText[i].Text, this.SourceText[i].toFind[j].Text[z]);
                        points += indexes.length;
                        for (var k = 0; k < indexes.length; k++) {
                            for (var l = 0; l < this.SourceText[i].toFind[j].Text[z].length; l++) {
                                if (this.SourceText[i].Text[indexes[k] + l].name != "space")
                                    this.numberOfCorrectChars++;
                            }
                        }
                    }
                }
            }
            return points;
        }

        private calculatePlayerPoints() {
            var points = 0;
            for (var i = 0; i < this.Elements.SourceText.length; i++) {
                for (var j = 0; j < this.SourceText[i].toFind.length; j++) {
                    for (var z = 0; z < this.SourceText[i].toFind[j].Text.length; z++) {
                        var indexes = this.findIndexes(this.Elements.SourceText[i].Text, this.SourceText[i].toFind[j].Text[z]);
                        for (var k = 0; k < indexes.length; k++) {
                            var allCharChecked = true;
                            for (var l = 0; l < this.SourceText[i].toFind[j].Text[z].length; l++) {

                                if (this.SourceText[i].Text[indexes[k] + l].name != ("checked" + this.SourceText[i].toFind[j].Color)
                                    && this.SourceText[i].Text[indexes[k] + l].name != "space" ) {
                                    allCharChecked = false;
                                }
                            }
                            if (allCharChecked) points++;
                        }
                    }
                }
            }
            return points;
        }
    }
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////            FORMAT JSONA           ////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//    JSON = {
//              completeText: "caly tekst do wyswietlenia",
//              searched: [["znak lub wyraz", (true/false || true szuka znaku lub wyrazu oddzielonego spacjami, kropka, myslnikiem lub cudzyslowiem; false szuka podciągu)], [], []]    
//           }
/*


{
    "attrs": ["TestGroupName", {
        "GameType": GameTypes.ColorText,
        "description": "4. Zaznacz czerwonym kolorem dwuznaki, a niebieskim samogłoski w zdaniu:",
        "Lector": "ZIP_spr_I_10_4.mp3",
        "MaxPoints": 1, "isStandalone": false, "isFirst": false, "GameData": {
            "TaskPrefix": "Zad10",
            "Graphics":
            [

            ],
            "StaticElements":
            "el" :
            [
            ],
            "Options": {
            }
            
            "Colors": ["red", "blue"],
            "PalletePosition": { "x": 1400, "y": 100 },
            "SourceText":
            [
                {
                    "Text": "Rozpoczniemy wakacje, kiedy skończy się szkoła.",
                    "Position": { "x": 300, "y": 300 },
                    "Style": { font: "40px Arial", fill: 'black' },
                    "TextToFind":
                    [
                        {
                            "Color": "blue",
                            "Text": ["a", "o", "i", "e", "y", "ę", "ą", "ó", "u"]
                        },

                        {
                            "Color": "red",
                            "Text": ["sz", "cz", "ch", "rz", "dź", "dz", "dż"]
                        },
                    ]
                },
            ],
        }
    }]
},
*/