module Connect {

    var colors = ["blue", "red", "green", "orange", "yellow", "pink", "magenta", "purple", "darkred", "lightseagreen"];

    export class Connect extends Base.BasicGroup {

        Elements: any;
        GAME_TYPE: any;
        drawingsAreAnswers: any;
        PREFIX: any;
        shadow: any[];
        drawings: any[];
        answers: any[];
        connections: any[];
        usedColors: any[];
        bmd: any;
        line: 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();
            }
            this.GAME_TYPE = this.Elements.GameType;
            this.drawingsAreAnswers = this.Elements.DrawingsAreAnswers;
            this.createStaticElements();

            this.createDrawings();
            this.createAnswers();
        }


        createStaticElements() {
            if (this.Elements.StaticElements)
            for (var i = 0; i < this.Elements.StaticElements.length; i++) {
                var el = this.game.add.image(this.Elements.StaticElements[i].pos.x, this.Elements.StaticElements[i].pos.y, this.PREFIX + this.Elements.StaticElements[i].key);
                this.addChild(el);
            }

        }

        createDrawings() {
            this.shadow = [];
            this.drawings = [];
            this.connections = [];
            for (var i = 0; i < this.Elements.Drawings.el.length; i++) {
                var el = this.game.add.image(this.Elements.Drawings.el[i].pos.x, this.Elements.Drawings.el[i].pos.y, this.PREFIX + this.Elements.Drawings.el[i].key);
                var shad = this.game.add.image(this.Elements.Drawings.el[i].pos.x + 3, this.Elements.Drawings.el[i].pos.y + 10, this.PREFIX + this.Elements.Drawings.el[i].key);
                shad.alpha = 0;
                shad.tint = 0x000000;
                shad.inputEnabled = true;
                el.inputEnabled = true;
                el.events.onInputOver.add(this.onInputOver, this);
                el.events.onInputOut.add(this.onInputOut, this);
                if (this.drawingsAreAnswers) {
                    el.events.onInputDown.add(this.onDrawingAnswerClicked, this);
                }
                else {
                    el.events.onInputDown.add(this.onDrawingClicked, this);
                }
                this.drawings.push({
                    "el": el,
                    "val": this.Elements.Drawings.el[i].val,
                    "lineStyleX": this.Elements.Drawings.el[i].lineStyleX,
                    "lineStyleY": this.Elements.Drawings.el[i].lineStyleY
                });
                this.shadow.push(shad);
                this.addChild(shad);
                this.addChild(el);
            }
        }

        createAnswers() {
            this.answers = [];
            for (var i = 0; i < this.Elements.Answers.el.length; i++) {
                var el = this.game.add.image(this.Elements.Answers.el[i].pos.x, this.Elements.Answers.el[i].pos.y, this.PREFIX + this.Elements.Answers.el[i].key);
                el.inputEnabled = true;
                el.events.onInputDown.add(this.createConnectionOnClick, this);
                this.answers.push({
                    "el": el,
                    "val": this.Elements.Answers.el[i].val,
                    "lineStyleX": this.Elements.Answers.el[i].lineStyleX,
                    "lineStyleY": this.Elements.Answers.el[i].lineStyleY
                });
                this.addChild(el);
            }   
        }



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

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

        private onDrawingClicked(el: Phaser.Sprite, pointer) {
            var elementIndex = this.getElementIndex(el, this.drawings);
            if ((this.GAME_TYPE == "ManyToMany" || this.GAME_TYPE == "OneToMany" || !this.checkIfDrawingHasConnection(elementIndex))) {
                if (!this.checkIfDrawingMarked()) {
                    this.shadow[elementIndex].alpha = 0.3;
                }
                else {
                    this.shadow[elementIndex].alpha = 0;
                }
            }
        }

        private onDrawingAnswerClicked(el: Phaser.Sprite, pointer) {
            var elementIndex = this.getElementIndex(el, this.drawings);
            if ((this.GAME_TYPE == "ManyToMany" || this.GAME_TYPE == "OneToMany") || (!this.checkIfDrawingHasConnection(elementIndex) && !this.checkIfAnswerHasConnection(elementIndex))) {
                if (!this.checkIfDrawingMarked()) {
                    this.shadow[elementIndex].alpha = 0.3;
                }
                else {
                    this.shadow[elementIndex].alpha = 0;
                }
            }
            if (this.shadow[elementIndex].alpha == 0 && (!this.checkIfDrawingHasConnection(elementIndex) && !this.checkIfAnswerHasConnection(elementIndex)) && this.checkIfDrawingMarked()) {

                this.createConnectionIfDaA(el, this.checkIfDrawingMarked().index, elementIndex);
            }
        }

        private onConnectionClicked(el: Phaser.Sprite, pointer) {
            for (var i = 0; i < this.connections.length; i++) {
                if (this.connections[i].img == el) {
                    el.destroy();
                    this.connections.splice(i, 1);
                }
            }
        }

        private createConnectionOnClick(el: Phaser.Sprite, pointer) {
            var answerIndex = this.getElementIndex(el, this.answers);
            this.createConnection(el, answerIndex);
        }


        private createConnection(element, answerIndex) {
            if (this.GAME_TYPE == "ManyToOne" || this.GAME_TYPE == "ManyToMany" || !this.checkIfAnswerHasConnection(answerIndex)) {
                var img;
                if (img = this.checkIfDrawingMarked()) {
                    var connection = {
                        DrawingIndex: null,
                        AnswerIndex: null,
                        img: null
                    }
                    connection['DrawingIndex'] = img.index;
                    connection['AnswerIndex'] = answerIndex;
                    this.addConnectionToArray(connection, this.connections, this.drawings, this.answers);
                    EU.Log(this.checkIfConnectionIsCorrect(connection, this.drawings, this.answers));
                    this.clearMarkedDrawings();
                    this.debugPoints();
                    this.checkIfEverythingIsCorrect();
                }
            }
        }

        private createConnectionIfDaA(element, answerIndex, drawingIndex) {
            var connection = {
                DrawingIndex: drawingIndex,
                AnswerIndex: answerIndex,
                img: null
            }
            this.addConnectionToArray(connection, this.connections, this.drawings, this.drawings);
            EU.Log(this.checkIfConnectionIsCorrect(connection, this.drawings, this.drawings));
            this.clearMarkedDrawings();
            this.debugPoints();
            this.checkIfEverythingIsCorrect();

        }

        private clearMarkedDrawings() {
            for (var i = 0; i < this.shadow.length; i++) {
                this.shadow[i].alpha = 0;
            }
        }

        private getElementIndex(element, array) {
            for (var i = 0; i < array.length; i++) {
                if (array[i].el.key == element.key)
                    return i;
            }
        }

        private randomColor() {
            return Phaser.Math.getRandom(colors, 0, colors.length);
        }

        private addConnectionToArray(connection, array, drawings, answers) {
            for (var i = 0; i < array.length; i++) {
                if (connection.DrawingIndex == array[i].DrawingIndex && connection.AnswerIndex == array[i].AnswerIndex) {
                    return false;
                }
            }
            connection['img'] = this.drawStyledConnection(drawings[connection.DrawingIndex], answers[connection.AnswerIndex]);
            array.push(connection);
            //EU.Log(connection.DrawingIndex + " + " + connection.AnswerIndex);
            return true;
        }

        private drawStyledConnection(drawing, answer) {
            var x1, y1, x2, y2;
            y1 = drawing.el.y + drawing.el.height / 2 + drawing.lineStyleY / 200 * drawing.el.height;
            y2 = answer.el.y + answer.el.height / 2 + answer.lineStyleY / 200 * answer.el.height;
            x1 = drawing.el.x + drawing.el.width / 2 + drawing.lineStyleX / 200 * drawing.el.width;
            x2 = answer.el.x + answer.el.width / 2 + answer.lineStyleX / 200 * answer.el.width;;
            //EU.Log(x1 + " " + y1 + " " + x2 + " " + y2);
            return this.drawConnection(x1, y1, x2, y2);
        }

        private drawConnection(x1, y1, x2, y2) {
            var lineWidth = 12;
            var lineLength = Phaser.Math.distance(x1, y1, x2, y2);
            var lineAngle = Phaser.Math.angleBetween(x1, y1, x2, y2);
            this.bmd = this.game.add.bitmapData(lineLength, lineWidth);
            this.bmd.ctx.beginPath();
            this.bmd.ctx.strokeStyle = this.randomColor();
            this.bmd.ctx.stroke();
            this.line = this.game.add.sprite(x1, y1, this.bmd);
            this.line.anchor.y = 0.5;
            this.line.smoothed = true;
            this.line.angle = Phaser.Math.radToDeg(lineAngle);
            this.line.inputEnabled = true;
            this.line.events.onInputOver.add(this.onInputOver, this);
            this.line.events.onInputOut.add(this.onInputOut, this);
            this.line.events.onInputDown.add(this.onConnectionClicked, this);
            this.addChild(this.line);
            this.bmd.ctx.beginPath();
            this.bmd.ctx.moveTo(0, lineWidth / 2);
            this.bmd.ctx.lineTo(lineLength, lineWidth / 2);
            this.bmd.ctx.lineWidth = lineWidth;
            this.bmd.ctx.stroke();
            this.bmd.ctx.closePath();
            this.bmd.render();
            //EU.Log("done");
            return this.line;
        }

        private checkIfDrawingMarked() {
            for (var i = 0; i < this.shadow.length; i++) {
                if (this.shadow[i].alpha == 0.3) {
                    var temp = {
                        index: i,
                        el: this.shadow[i]
                    }
                    return temp;
                }
            }
        }

        private checkIfAnswerHasConnection(answerIndex) {
            for (var i = 0; i < this.connections.length; i++) {
                if (this.connections[i].AnswerIndex == answerIndex) {
                    return true;
                }
            }
            return false;
        }

        private checkIfDrawingHasConnection(drawingIndex) {
            for (var i = 0; i < this.connections.length; i++) {
                if (this.connections[i].DrawingIndex == drawingIndex) {
                    return true;
                }
            }
            return false;
        }

        private checkIfConnectionIsCorrect(connection, drawings, answers) {
            if (answers[connection.AnswerIndex].val == drawings[connection.DrawingIndex].val) {
                return true;
            }
            return false;
        }

        private checkIfEverythingIsCorrect() {
            if (this.calculateMaxPoints() == this.calculatePlayerPoints() && this.connections.length == this.calculatePlayerPoints()) {
                EU.setGameCompletion(this.parent, 1);
                EU.Log("Everyting Correct!!!");
                return true;
            }
            EU.setGameCompletion(this.parent, 0);
            return false;
        }

        private calculatePlayerPoints() {
            var points = 0;
            if (this.drawingsAreAnswers) {
                for (var i = 0; i < this.connections.length; i++) {
                    if (this.checkIfConnectionIsCorrect(this.connections[i], this.drawings, this.drawings)) {
                        points++;
                    }
                }
            }
            else {
                for (var i = 0; i < this.connections.length; i++) {
                    if (this.checkIfConnectionIsCorrect(this.connections[i], this.drawings, this.answers)) {
                        points++;
                    }
                }
            }
            return points;
        }

        private calculateMaxPoints() {
            var points = 0;
            if (this.drawingsAreAnswers) {
                for (var i = 0; i < this.drawings.length; i++) {
                    for (var j = i+1; j < this.drawings.length; j++) {
                        if (this.drawings[i].val == this.drawings[j].val) {
                            points++;
                            if (this.GAME_TYPE == "OneToOne" || this.GAME_TYPE == "ManyToOne") break;
                        }
                    }
                }
  
            }
            else {
                for (var i = 0; i < this.drawings.length; i++) {
                    for (var j = 0; j < this.answers.length; j++) {
                        if (this.drawings[i].val == this.answers[j].val) {
                            points++;
                            if (this.GAME_TYPE == "OneToOne" || this.GAME_TYPE == "ManyToOne") break;
                        }
                    }
                }
            }
        
            return points;
        }

        private debugConnections() {
            for (var i = 0; i < this.connections.length; i++) {
                EU.Log(this.connections[i].DrawingIndex + " " + this.connections.length);
            }
        }

        private debugPoints() {
            var playerPoints = this.calculatePlayerPoints();
            var maxPoints = this.calculateMaxPoints();
            EU.Log("NumberOfConnections: " + this.connections.length + " Correct: " + playerPoints + " MaxCorrect: " + maxPoints);
        }

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

        }
    }
}

            
         
      
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////            FORMAT JSONA           ////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
//var data = [{
//    "alias": GameTypes.TestGroup, "attrs": ["TestGroupName", {
//        "description": "1. Połącz ze soba", "isStandalone": false, "isFirst": true, "GameData": {
//
//            "GameType": "OneToOne",                                                                       //okresla typ gry - mozliwe do wyboru "OneToOne", "OneToMany", "ManyToOne", "ManyToMany"
//                                                                                                          //OneToOne - pasuje jeden rysunek do jednej odpowiedzi, 
//                                                                                                          //OneToMany - moze pasowac wiele rysunkow do jednej odpowiedzi,
//                                                                                                          //ManyToOne - może pasowac jeden rysunek do wielu odpowiedzi,
//                                                                                                          //ManyToMany - może pasować wiele rysunków do wielu odpowiedzi, 
//            "TaskPrefix": "Zad8",                                                                         //prefix do numeru zadania - rozstrzyga konflikty zwiazane z powtarzaniem sie wartosci "key"
//           
//            "DrawingsAreAnswers": true,                                                                   //flaga definiująca czy rysunki są jednoczesnie odpowiedziami 
//                                                                                                          // !!! jezeli wlaczono to definiujemy tylko rysunki - Drawings
//
//
//
//            "Graphics":                                                                                   //lista grafik do wyswietlenia okreslona przez klucz
//            [
//                { "src": "Graphics/Exams/MW_I_3/zad3/MW_spr_I_3_zad3_01.png", "key": "01" },              
//                { "src": "Graphics/Exams/MW_I_3/zad3/MW_spr_I_3_zad3_02.png", "key": "02" },
//                { "src": "Graphics/Exams/MW_I_3/zad3/MW_spr_I_3_zad3_03.png", "key": "03" },
//                { "src": "Graphics/Exams/MW_I_3/zad3/MW_spr_I_3_zad3_dzialanie1.png", "key": "04" },
//                { "src": "Graphics/Exams/MW_I_3/zad3/MW_spr_I_3_zad3_dzialanie2.png", "key": "05" },
//                { "src": "Graphics/Exams/MW_I_3/zad3/MW_spr_I_3_zad3_dzialanie3.png", "key": "06" },
//            ],
//            "Drawings": {                                                                                                     //lista rysunkow z zadaniami
//                "el": [
//                    { "key": "01", "pos": { "x": 130, "y": 175 }, "val": "2+2", "lineStyleX": "0", "lineStyleY": "0" },       //key - klucz, pokrywajacy sie z tym od Graphics , pos - pozycja rysunku do wyswietlenia
//                    { "key": "02", "pos": { "x": 130, "y": 411 }, "val": "3+1", "lineStyleX": "0", "lineStyleY": "0" },       //val - wartosc bedaca odpowiedzia - musi sie zgadzac miedzy rysunkiem i odpowiedzia
//                    { "key": "03", "pos": { "x": 130, "y": 647 }, "val": "2+1+2", "lineStyleX": "0", "lineStyleY": "0" }      //lineStyle - w procentach - okresla punktu zaczepu polaczenia w rysunku 
//                ]                                                                                                             //ujemna wartosc Y- odchylenie w gore,  dodatnia Y - w dol
//            },                                                                                                                //ujemna wartosc X - odchylenie w lewo, dodatnia X - w prawo    
//            "Answers": {                                                                                                      //lista odpowiedzi, ktore trzeba polaczyc z rysunkami
//                "el": [
//                    { "key": "04", "pos": { "x": 1100, "y": 175 }, "val": "2+1+2", "lineStyleX": "0", "lineStyleY": "0" },    //key - klucz, pokrywajacy sie z tym od Graphics , pos - pozycja rysunku do wyswietlenia
//                    { "key": "05", "pos": { "x": 1100, "y": 411 }, "val": "2+2", "lineStyleX": "0", "lineStyleY": "0" },      //val - wartosc bedaca odpowiedzia - musi sie zgadzac miedzy rysunkiem i odpowiedzia
//                    { "key": "06", "pos": { "x": 1100, "y": 647 }, "val": "3+1", "lineStyleX": "0", "lineStyleY": "0" }       //lineStyle - w procentach - okresla punktu zaczepu polaczenia w rysunku
//                ]                                                                                                             //ujemna wartosc Y - odchylenie w gore,  dodatnia Y - w dol
//            }                                                                                                                 //ujemna wartosc X - odchylenie w lewo, dodatnia X - w prawo    
//        }
//
//    }]
//}


 
       



