//this module handles transitioning between levels
//it will spawn a new level above the old one and
//when change level is called it will start scrolling
//both the current level and the new one down. When
//the old level has gone offscreen it will despawn it
ig.module('game.level-transition')
.requires(
    'impact.impact',
    'game.level',
    'game.floor',
    'game.entities.brick',
    'game.xml-loader',
    'game.entities.timed-entity',
    'game.entities.ending'
)
.defines(function () {
    "use strict";
    ig.global.LevelTransition = function (oldl, newl) {
        this.isEnding = false;

        //will store the new level during transition, we make it later
        var newlevel = null;

        //we only want to show the level message
        //once so that if someone resets the game
        //we do not show it again
        var hasShownLevel = false;

        //go through and find pies and bricks and whatnot and get rid of them
        function cullEntities() {
            var bricks = ig.game.getEntitiesByType('EntityBrick');
            var pies = ig.game.getEntitiesByType('EntityPie');
            var piespawners = ig.game.getEntitiesByType('EntityPieSpawner');
            var heads = ig.game.getEntitiesByType('EntityHead');
            var ducks = ig.game.getEntitiesByType('EntityDuck');
            var duckSpawners = ig.game.getEntitiesByType('EntityDuckSpawner');
            duckSpawners.forEach(function (val) { val.kill(); });
            ducks.forEach(function (val) { val.kill(); });
            heads.forEach(function (val) { val.kill(); });
            bricks.forEach(function (val) { val.kill(); });
            pies.forEach(function (val) { val.kill(); });
            piespawners.forEach(function (val) { val.kill(); });

        };
        //kick off the level change
        //will change between oldlevel and
        //newlevel
        function changeLevel() {
            if (hasShownLevel === false) {
                UI.showLevelChange(newl + 1);
                hasShownLevel = true;
            }
            var moveSpeed = { x: IMG.SIZE(0), y: IMG.SIZE(1500) };


            //actually create the new level
            if (newlevel === null && newl < XmlLoader.levelCount) {
                newlevel = XmlLoader.parseXLevel(XmlLoader.getXLevel(XmlLoader.getXStage(0), newl), IMG.SIZE(1890));
                if (newlevel.duckSpawner) {
                    newlevel.duckSpawner.enabled = false;
                }
                if (newlevel.pieSpawner) {
                    newlevel.pieSpawner.enabled = false;
                }
                if (oldl.pieSpawner) {
                    oldl.pieSpawner.kill();
                }
            } else if (newl === XmlLoader.levelCount) {
                UI.hideLevelChange();
                ig.game.ralph.vel = { x: 0, y: 0 };
                ig.game.ralph.renderLock = true;
                ig.game.ralph.behavior = function () { };
                this.level.floors[1].windows[1].spawnHead();
                this.level.floors[2].windows[2].spawnHead();
                this.level.floors[2].windows[3].spawnHead();
                this.isEnding = true;
                //we have beat the game, lets show the ending stuff
                ig.game.spawnEntity(EntityTimedEntity, ig.game.spawnEntity(EntitySpeechBubble, 0, 0), 5, function () {
                    oldl.removeLevel();
                    ig.game.spawnEntity(EntityEnding, 0, 0);
                });
            } else {
                oldl.setProperty("vel", moveSpeed);
                newlevel.setProperty("vel", moveSpeed);
            }
        };
        function isDone() {
            if (newlevel !== null && newlevel.pos().y >= ig.system.height) {
                onDone();
                return true;
            } else {
                return false;
            }
        };
        function onDone() {

            if (ig.game.player && ig.game.player.lives !== 0) {
                delete ig.game.player.behavior;
                delete ig.game.player.movement;
                ig.game.player.vel = { x: 0, y: 0 };
                ig.game.player.isDieing = false;
                ig.game.player.invincible = false;
                ig.game.player.scoreMultiple = 1;
                ig.game.player.currentAnim = ig.game.player.anims.idle;
                ig.game.player.gridPosition = { floor: 0, window: 0 };
                ig.game.player.pos = newlevel.floors[0].windows[0].getPlayerPosition();
                Brick.breakLock = false;
            }
            UI.Timer.resetTimer(60);
            //UI.Timer.resumeTimer();
        };
        function getPositionOnNewLevel(gridpos) {
            if (newlevel) {
                return newlevel.getPosition(gridpos);
            } else {
                return false;
            }
        }
        function updateLevelTransition() {
            if (isDone()) {
                oldl.removeLevel();
                newlevel.setProperty("vel", { x: 0, y: 0 });
                ig.game.ralph.aiOptions = XmlLoader.parseXRalph(XmlLoader.getXLevel(XmlLoader.getXStage(0), newl));
                Brick = XmlLoader.parseXBrick(XmlLoader.getXLevel(XmlLoader.getXStage(0), newl));
                Brick.breakLock = false;
                UI.hideLevelChange();
                return new LevelTransition(newlevel, newl + 1);

            } else {
                return this;
            }
        };
        this.hasStarted = false;
        this.getPositionOnNewLevel = getPositionOnNewLevel;
        this.updateTransition = updateLevelTransition;
        this.isDone = isDone;
        this.level = oldl;
        this.nextLevel = function () { return newlevel; };
        //we want to be able to call changelevel from outside with no params
        this.changeLevel = changeLevel;
        this.cullEntities = cullEntities;
    }
});
