var tree = undefined;

class Game extends ManageLang {
    constructor(father, level = "level1") {
        super('Game', father);
        super.addOtherScenes('GamingBoard');
        SPEED_GAME = 1;
        this.level = level;
    }

    preload() {
        if (this.cache.json.exists('level')) {
            this.cache.json.remove('level');
        }
        this.load.json('level', 'public/json/' + this.level + '.json');
    }

    create() {
        super.create();

        if (this.tree !== undefined && this.initStat !== undefined) {
            let tree = this.tree.getJson(true);
            console.log(tree);
            tree = JSON.parse(tree);

            let initStat = this.initStat.getJson(true);
            initStat = JSON.parse(initStat);

            this.loadSave(tree, initStat);
        } else {
            let level = this.cache.json.get('level');
            if (level !== undefined) {
                this.loadSave(level.tree, level.initStat);
            }
        }

        this.doLine = false;
        this.gm = new GamingBoard(this);
        if (this.father.scene.getIndex('GamingBoard') !== -1) {
            this.father.scene.remove('GamingBoard');
        }
        this.father.scene.add('GamingBoard', this.gm);
        this.scene.launch('GamingBoard');
        this.scene.pause('GamingBoard');

        this.selected = null;

        let width = 200;
        let height = 30;

        this.createButton();

        let centerX = WIDTH_WINDOW / 4 * 3;
        let diffX = WIDTH_WINDOW / 10;


        this.gm.addRobot(new Robot(WIDTH_MAP * 0.1, WIDTH_MAP * 0.1, WIDTH_MAP * 0.9, WIDTH_MAP * 0.9, this.gm, MYSELF));
        this.gm.addRobot(new Robot(WIDTH_MAP * 0.1, WIDTH_MAP * 0.1, WIDTH_MAP * 0.2, WIDTH_MAP * 0.1, this.gm));
        this.gm.addRobot(new Robot(WIDTH_MAP * 0.1, WIDTH_MAP * 0.1, WIDTH_MAP * 0.1, WIDTH_MAP * 0.9, this.gm));


        this.input.keyboard.on('keydown-DELETE', () => {
            this.clickBin();
        });
        this.input.keyboard.on('keydown-E', () => {
            this.clickPencil();
        });
        this.input.keyboard.on('keydown-ENTER', () => {
            this.clickPlus();
        });
    }

    update(time, delta) {
        super.update(time, delta);
        if (this.doLine)
            this.tree.updateLine();
    }


    loadSave(tree, initStat) {
        this.initStat = this.loadInitSave(initStat);
        this.tree = this.loadTree(tree);
    }

    loadTree(element, posX = CENTERX_TREE, posY = OFFY_TREE / 2) {
        if (element.x !== undefined && element.y !== undefined) {
            let tree = new RectangleNode(element.x, element.y, this, element.type, element.option);
            if (element.lRect !== undefined && element.lRect.length > 0) {
                element.lRect.forEach(rect => tree.addRect(this.loadTree(rect)))
            }
            return tree;
        } else {
            let tree = new RectangleNode(posX, posY, this, element.type, element.option);
            if (element.lRect !== undefined && element.lRect.length > 0) {
                let nbRect = element.lRect.length;
                let x = posX - (OFFX_TREE / 2) * (nbRect - 1);
                let y = posY + OFFY_TREE;
                element.lRect.forEach(rect => {
                    tree.addRect(this.loadTree(rect, x, y))
                    x += OFFX_TREE;
                });
            }
            return tree;
        }
    }

    loadInitSave(element) {
        let width = 200;
        let height = 30;
        let initStat = new InitStat(this, OFFX_MAP + WIDTH_MAP + 5, OFFY_MAP, width, height, 10);

        for (let i = 0; i < element.lBar.length; i++) {
            initStat.addBar(element.lBar[i].value, element.lBar[i].valueMax, element.lBar[i].color, element.lText[i]);
        }
        return initStat;
    }

    finish() {
        console.log("FINISH");
        let winner;
        if (this.gm.winner()) {
            winner = new Winner(this.father, this);
        } else {
            winner = new Looser(this.father, this);
        }
        this.father.scene.add('Finish', winner);

        this.scene.pause('Game');

        this.scene.launch('Finish');
    }


    clickNode() {
        console.log("NODE");
        this.tryClick();
        this.selected = this.tree.getSelected();

        if (this.selected === null)
            return;

        if (this.selected !== this.tree) {
            this.pencil.setVisible(true);
            this.bin.setVisible(true);
        }
        if (this.selected.canAddNode) {
            this.plus.setVisible(true);
        }
    }

    doDrag(pointer, target, dragX, dragY) {
        target.setX(dragX);
        target.setY(dragY);
    }

    dragStart() {
        console.log("START DRAG");

        this.doLine = true;
        this.pauseScene();
    }

    dragEnd() {
        console.log("END DRAG");

        this.doLine = false;
    }


    pauseScene() {
        this.linePlay = 0;
        this.changeFrame(this.play, 0);

        this.gm.pause();
    }

    resume() {
        this.linePlay = 1;

        let sortDesc = (a, b) => a.getX() - b.getX();
        this.tree.sort(sortDesc);
        this.gm.modifyNodes(this.tree.getNode());
        this.gm.modifyValue(this.initStat.lBar[0].value, this.initStat.lBar[1].value, this.initStat.lBar[2].value, this.initStat.lBar[3].value);

        this.gm.resume();
    }


    changeFrame(btn, column = 0, line = 0) {
        btn.setFrame(column + line * 2);
    }

    createButton() {
        let x = WIDTH_MAP + OFFX_MAP;
        let y = WIDTH_MAP + OFFY_MAP + 5;
        let width = OFFY_MAP / 1.5;
        let diffX = width * 1.1;

        let back = this.add.sprite(10, 10, 'back').setOrigin(0, 0).setInteractive();

        this.play = this.add.sprite(x, y, 'play').setOrigin(1, 0).setInteractive();
        let speed = this.add.sprite(x - diffX, y, 'speed').setOrigin(1, 0).setInteractive();

        let save = this.add.sprite(WIDTH_WINDOW, y, 'save').setOrigin(1, 0).setInteractive();

        this.pencil = this.add.sprite(x - diffX * 2, y, 'pencil').setOrigin(1, 0).setInteractive().setVisible(false);
        this.bin = this.add.sprite(x - diffX * 3, y, 'bin').setOrigin(1, 0).setInteractive().setVisible(false);
        this.plus = this.add.sprite(x - diffX * 4, y, 'plus').setOrigin(1, 0).setInteractive().setVisible(false);

        let mute = this.add.sprite(x - diffX * 5, y, 'mute').setOrigin(1, 0).setInteractive();

        this.linePlay = 0;
        if (SPEED_GAME === 1) {
            this.lineSpeed = 0;
        } else {
            this.lineSpeed = 1;
        }
        this.changeFrame(speed, 0, this.lineSpeed);
        if (this.father.sound.mute) {
            this.lineMute = 1;
        } else {
            this.lineMute = 0;
        }
        this.changeFrame(mute, 0, this.lineMute);

        back.displayHeight = back.displayWidth = width;
        save.displayHeight = save.displayWidth = width;
        this.play.displayHeight = this.play.displayWidth = width;
        speed.displayHeight = speed.displayWidth = width;
        mute.displayHeight = mute.displayWidth = width;
        this.pencil.displayHeight = this.pencil.displayWidth = width;
        this.bin.displayHeight = this.bin.displayWidth = width;
        this.plus.displayHeight = this.plus.displayWidth = width;

        this.play.on('pointerout', () => this.changeFrame(this.play, 0, this.linePlay));
        this.play.on('pointerover', () => this.changeFrame(this.play, 1, this.linePlay));
        speed.on('pointerout', () => this.changeFrame(speed, 0, this.lineSpeed));
        speed.on('pointerover', () => this.changeFrame(speed, 1, this.lineSpeed));
        mute.on('pointerout', () => this.changeFrame(mute, 0, this.lineMute));
        mute.on('pointerover', () => this.changeFrame(mute, 1, this.lineMute));
        this.creatBtnOutAndOver(save);
        this.creatBtnOutAndOver(back);
        this.creatBtnOutAndOver(this.pencil);
        this.creatBtnOutAndOver(this.bin);
        this.creatBtnOutAndOver(this.plus);

        this.play.on('pointerdown', () => this.clickPlay());
        speed.on('pointerdown', () => this.clickSpeed(speed));
        back.on('pointerdown', () => this.clickBack());
        mute.on('pointerdown', () => this.clickMute(mute));
        save.on('pointerdown', () => this.clickSave());
        this.pencil.on('pointerdown', () => this.clickPencil());
        this.bin.on('pointerdown', () => this.clickBin());
        this.plus.on('pointerdown', () => this.clickPlus());

        this.input.on('pointerdown', () => this.clickNode());
        this.input.on('drag', this.doDrag);
        this.input.on('dragstart', () => this.dragStart());
        this.input.on('dragend', () => this.dragEnd());
    }

    creatBtnOutAndOver(btn) {
        btn.on('pointerout', () => this.changeFrame(btn, 0));
        btn.on('pointerover', () => this.changeFrame(btn, 1));
    }

    clickSave() {
        let sortDesc = (a, b) => a.getX() - b.getX();
        this.tree.sort(sortDesc);
        let tree = this.tree.getJson();
        let initStat = this.initStat.getJson();
        let json = '{' + '"tree":' + tree + ',"initStat":' + initStat + '}';
        console.log(json);
    }

    clickPlay() {
        if (this.scene.isPaused('GamingBoard'))
            this.resume();
        else
            this.pauseScene();

        this.changeFrame(this.play, 1, this.linePlay);
    }

    clickSpeed(btn) {
        if (SPEED_GAME === 1) {
            SPEED_GAME = 2;
            this.lineSpeed = 1;
        } else {
            SPEED_GAME = 1;
            this.lineSpeed = 0;
        }

        this.changeFrame(btn, 1, this.lineSpeed);
    }

    clickPencil() {
        if (this.selected !== null) {
            console.log("PENCIL");
            this.changeFrame(this.pencil, 0);
            switch (this.selected.type) {
                case 'attack':
                    this.father.scene.add('AddNode', new AddAttack(this.father, this, this.selected, false, this.selected.node.percentRange));
                    break;
                case 'move':
                    this.father.scene.add('AddNode', new AddMove(this.father, this, this.selected, this.selected.node.toward, this.selected.node.enemyBot));
                    break;
                case 'condition':
                    if (this.selected.node.shieldFilter) {
                        this.father.scene.add('AddNode', new AddCondition(this.father, this, this.selected, this.selected.node.myself, [this.selected.node.shield, 'shield']));
                    } else {
                        this.father.scene.add('AddNode', new AddCondition(this.father, this, this.selected, this.selected.node.myself, [this.selected.node.range, 'range']));
                    }
                    break;
                default:
                    return;
            }
            this.scene.pause('Game');
            this.scene.launch('AddNode');
        }
    }

    clickBin() {
        if (this.selected !== null) {
            console.log("BIN");
            this.tree.delete(this.selected);

            this.changeFrame(this.bin, 0);
            this.tryClick();
        }
    }

    clickPlus() {
        if (this.selected !== null && this.selected.canAddNode) {
            console.log("PLUS");

            this.father.scene.add('PlusNode', new PlusNode(this.father, this, this.selected));

            this.scene.launch('PlusNode');

            this.changeFrame(this.plus, 0);

            this.scene.pause('Game');
        }
    }

    clickBack() {
        console.log("BACK");

        this.father.scene.stop('GamingBoard');
        this.father.scene.remove('GamingBoard');
        this.father.scene.stop('Game');
        this.father.scene.start('Type');
    }

    clickMute(btn) {
        console.log("MUTE");

        if (this.father.sound.mute) {
            this.father.sound.mute = false;
            this.lineMute = 0;
        } else {
            this.father.sound.mute = true;
            this.lineMute = 1;
        }
        this.changeFrame(btn, 1, this.lineMute);
    }

    tryClick() {
        this.pencil.setVisible(false);
        this.bin.setVisible(false);
        this.plus.setVisible(false);
        if (this.selected != null) {
            this.selected.deselect();
            this.selected = null;
        }
    }
}