import {Pad} from "../input/Pad";
import {Player} from "../entities/Player";
import {Robe} from "../entities/Robe";
import {RitualManager} from "../manager/RitualManager";
import Graphics = Phaser.Graphics;
import {Sequence} from "../manager/Sequence";

export class Ritual extends Phaser.State {
    pad:Pad;
    ritualManager:RitualManager;

    npcs:Robe[] = [];

    music:Phaser.Sound;

    dialog1:Phaser.Sprite;
    dialog2:Phaser.Sprite;

    player: Player;
    canCheck = false;

    preload() {
        this.game.load.atlasJSONHash('player', 'assets/animations/player_robe/player_robe.png', 'assets/animations/player_robe/player_robe.json');
        this.game.load.atlasJSONHash('robe', 'assets/animations/robe/robe.png', 'assets/animations/robe/robe.json');
        this.game.load.image('ritual_bg', 'assets/images/ritual_bg.png');
        this.game.load.audio('ritual_music', 'assets/music/ritual.ogg');
        this.game.load.image('flame1', 'assets/particles/flame1.png');
        this.game.load.image('dialog_1', 'assets/dialogs/scene_3_0.png');
        this.game.load.image('dialog_2', 'assets/dialogs/scene_3_1.png');
        this.game.load.image('princess_small', 'assets/images/princess_small.png');
    }

    create() {
        // setup background
        this.game.stage.backgroundColor = '#fff';
        this.game.add.sprite(0, 0, 'ritual_bg');

        this.music = this.game.add.audio('ritual_music');
        this.music.play();

        var flame = this.game.add.image(this.game.world.centerX, this.game.world.centerY, 'flame1');
        flame.visible = false;
        flame.anchor.setTo(0.5, 1);

        // setup input
        this.game.input.gamepad.start();
        this.pad = new Pad(this.game.input.gamepad.pad1);

        // setup ritual manager
        this.ritualManager = new RitualManager(this.game);

        // setup player
        var playerRobeLook = this.game.add.sprite(0, 180, 'player', '05.png');
        this.player = new Player(playerRobeLook, this.pad);
        this.player.setupPlayerRobeAnimations(playerRobeLook);
        this.player.speed = 3;

        var npcs:Robe[] = [];
        for (var i = 0; i < 5; i++) {
            npcs.push(new Robe(this.game.add.sprite(0, i * 80, 'robe', '01.png')));
            npcs[i].sprite.anchor.setTo(0.5, 1);
            this.game.add.tween(npcs[i].sprite.position)
                .to({
                    x: this.ritualManager.circle.fields[i].x + this.game.world.centerX,
                    y: this.ritualManager.circle.fields[i].y + this.game.world.centerY
                }, 4000, Phaser.Easing.Linear.None, true);
        }

        var blinkFire = ()=> {
            flame.visible = true;
            this.game.time.events.add(50, ()=> {
                flame.visible = false;

                this.game.time.events.add(100, ()=> {
                    flame.visible = true;

                    this.game.time.events.add(200, ()=> {
                        flame.visible = false;
                    });
                });
            });
        };

        var walkToMidAndBack = (delay:number, toMid:number, back:number)=> {
            var def = $.Deferred();
            seq.chain(delay, ()=> {
                var previousRadius = this.ritualManager.circle.radius;
                var walkCenter = this.game.add.tween(this.ritualManager.circle).to({radius: 30}, toMid, Phaser.Easing.Quadratic.Out, false);
                var walkBackOut = this.game.add.tween(this.ritualManager.circle).to({radius: previousRadius}, back, Phaser.Easing.Quadratic.Out, false);
                walkCenter.chain(walkBackOut).onComplete.add(()=> {
                    def.resolve(walkCenter)
                });
                walkCenter.start();
            });
            return def;
        };

        var princess_small = this.game.add.image(0, 0, 'princess_small');
        princess_small.position.setTo(this.game.world.centerX, this.game.world.centerY);
        princess_small.anchor.setTo(0.5, 0.5);
        princess_small.scale.setTo(1.2, 1.2);
        princess_small.position.y -= 80;
        princess_small.visible = false;

        this.dialog1 = this.game.add.sprite(0, this.game.world.height, 'dialog_1');
        this.dialog1.anchor.setTo(0, 1);

        this.dialog2 = this.game.add.sprite(0, this.game.world.height, 'dialog_2');
        this.dialog2.anchor.setTo(0, 1);
        this.dialog2.visible = false;

        var seq = new Sequence(this.game);

        seq.chain(4000, ()=> {
            this.dialog1.visible = false;
        }).resolve();

        seq.chain(7000, ()=> {
            this.ritualManager.rotate();
            this.canCheck = true;
            this.npcs = npcs;
        }).then(()=> {
            return seq.chain(8000, ()=> {
                this.ritualManager.stopRotation();
            });
        }).then(()=> {
            return seq.chain(500, ()=> {
                this.ritualManager.rotate(false);
            });
        }).then(()=> {
            return seq.chain(3500, ()=> {
                this.ritualManager.setRotation(0.7);
            });
        }).then(()=> {
            return seq.chain(4500, ()=> {
                this.ritualManager.setRotation(-0.45);
            });
        }).then(()=> {
            return walkToMidAndBack(1000, 2000, 2000);
        }).then(()=> {
            return seq.chain(8000, ()=> {
                blinkFire();
            }).resolve();
        }).then(()=> {
            return seq.chain(4000, ()=> {
                flame.visible = true;
            }).resolve();
        }).then(()=> {
            return seq.chain(21000, ()=> {
                var previousRadius = this.ritualManager.circle.radius;
                var walkCenter = this.game.add.tween(this.ritualManager.circle).to({radius: 30}, 1000, Phaser.Easing.Quadratic.In, false);
                var walkBackOut = this.game.add.tween(this.ritualManager.circle).to({radius: previousRadius}, 1000, Phaser.Easing.Quadratic.Out, false);
                walkCenter.chain(walkBackOut);
                walkCenter.start();
            });
        }).then(()=> {
            return seq.chain(2000, ()=> {
                this.ritualManager.setRotation(-0.6);
            });
        }).then(()=> {
            return seq.chain(1000, ()=> {
                this.ritualManager.setRotation(0.6);
            });
        }).then(()=> {
            return seq.chain(1000, ()=> {
                this.ritualManager.stopRotation();
            });
        }).then(()=> {
            return seq.chain(1000, ()=> {
                blinkFire();
            });
        }).then(()=> {
            return seq.chain(300, ()=> {
                this.ritualManager.setRotation(-0.6);
            });
        }).then(()=> {
            var def = $.Deferred();
            seq.chain(3000, ()=> {
                var previousRadius = this.ritualManager.circle.radius;
                var walkOut = this.game.add.tween(this.ritualManager.circle).to({radius: previousRadius + 100}, 1000, Phaser.Easing.Quadratic.In, false);
                var walkBackRing = this.game.add.tween(this.ritualManager.circle).to({radius: previousRadius}, 1000, Phaser.Easing.Quadratic.Out, false);
                walkOut.chain(walkBackRing).onComplete.add(()=> {
                    def.resolve(walkOut);
                });
                walkOut.start();
            });
            return def;
        }).then(()=> {
            return walkToMidAndBack(4000, 2000, 2000);
        }).then(()=> {
            return seq.chain(500, ()=> {
                this.ritualManager.setRotation(0.8);
            });
        }).then(()=> {
            return seq.chain(500, ()=> {
                this.ritualManager.setRotation(-0.8);
            });
        }).then(()=> {
            return seq.chain(1000, ()=> {
                this.ritualManager.stopRotation();
            });
        }).then(()=> {
            return seq.chain(1000, ()=> {
                this.ritualManager.setRotation(0.6);
            });
        }).then(()=> {
            return seq.chain(5000, ()=> {
                this.canCheck = false;
                this.ritualManager.checkIfWon();
                this.ritualManager.stopRotation();
                flame.visible = true;
                this.npcs.forEach((npc)=> {
                    npc.animDown();
                    npc.sprite.animations.stop();
                    this.player.enabled = false;
                });
            });
        }).then(()=> {
            return seq.chain(2000, ()=> {
                princess_small.visible = true;
            })
        }).then(()=> {
            return seq.chain(6000, ()=> {
                this.dialog2.visible = true;
            });
        }).then(()=> {
            return seq.chain(5000, ()=> {
                this.game.state.start('end');
            });
        });
    }

    shutdown() {
        this.music.stop();
    }

    update() {
        this.pad.update();
        this.ritualManager.update();
        if(this.canCheck){
            this.ritualManager.check(this.player);
        }
        for (var i = 0; i < this.npcs.length; i++) {
            var bla = this.npcs[i];
            bla.animRight();
            bla.sprite.x = this.ritualManager.circle.fields[i].x + this.game.world.centerX;
            bla.sprite.y = this.ritualManager.circle.fields[i].y + this.game.world.centerY;
        }
    }
}