var EHDI = EHDI || Object.create(null);

EHDI.components = EHDI.components || Object.create(null);

EHDI.components.ObstacleSpawner = function(hand, gameLayer) {
    EHDI.aka.Container.call(this);
    this.gameLayer = gameLayer;
    this.activeObstacles = [];
    this.inactiveObstacles = [];
    this.distance = 0;  
    this.lastSpawn = 0;
    this.interval = Math.floor(EHDI.NumberUtil.randomRange(5,10));
    this.hand = hand;
    this.spawnGuide = 0;
    this.moveSpeed = 4;
    this.minSpeed = 4;
    this.maxSpeed = 8;
    this.nextSheep = 30;
};

EHDI.components.ObstacleSpawner.prototype = Object.create(EHDI.aka.Container.prototype);

EHDI.components.ObstacleSpawner.prototype.updateDistance = function (dt) {
    
    var addDistance = (this.moveSpeed * dt / 1000);
    this.distance += addDistance;
    
    var time = this.distance / 300; 
    this.moveSpeed = (1 - time) * this.minSpeed + time * this.maxSpeed; 
    
    var toInactive = null;
    for(var i = 0; i < this.activeObstacles.length; i++) {
        this.activeObstacles[i].x -= addDistance * 96;
        if(!this.activeObstacles[i].haveIPlaySFX && this.activeObstacles[i].checkIfPlaySFX)
            this.activeObstacles[i].checkIfPlaySFX();
        if(this.activeObstacles[i].move)
            this.activeObstacles[i].move(dt);
        if(!this.activeObstacles[i].ignoreCollision && this.activeObstacles[i].x < EHDI.GAME.sceneManager.getStageWidth() * 0.7)
            this.checkIfHit(this.activeObstacles[i], this.hand);
        if(this.activeObstacles[i] && this.activeObstacles[i].x + this.activeObstacles[i].width * this.activeObstacles[i].sprite.anchor.x < 0) {
            toInactive = this.activeObstacles[i];
            toInactive.distance = Math.floor(this.distance);
        }    
    }
    
    if(!this.warning) {
        EHDI.GAME.gameScene.hand.hideHint();
    }
    this.warning = false;
    
    if(toInactive) {
        this.activeObstacles.splice(this.activeObstacles.indexOf(toInactive), 1);
        this.gameLayer.removeChild(toInactive);
        if(!toInactive.isGrass && !toInactive.dontConvert)
            this.inactiveObstacles.push(toInactive);
    }
    
    var next = this.lastSpawn + this.interval;
    if(Math.floor(this.distance) ===  30 && !this.hasSpawned) {
        //Spawn first sheep
        this.hasSpawned = true;
        var toActiveSheep = new EHDI.components.Sheep("grey");
        var randomYPos = EHDI.NumberUtil.randomRange(90 + toActiveSheep.collider.height + 105, EHDI.GAME.sceneManager.getStageHeight() - 100);
        
        toActiveSheep.position.set(EHDI.GAME.sceneManager.getStageWidth() + toActiveSheep.width * 0.5, randomYPos);
        this.gameLayer.addChild(toActiveSheep);
        this.activeObstacles.push(toActiveSheep);
        this.lastSpawn = this.distance;
        toActiveSheep.zIndex = toActiveSheep.y;
        this.nextSheep = 100;
    } else if(Math.floor(this.distance) === 100 && !this.hasSpawned) {
        this.hasSpawned = true;
        var toActiveSheep = new EHDI.components.Sheep("brown");
        var randomYPos = EHDI.NumberUtil.randomRange(90 + toActiveSheep.collider.height + 105, EHDI.GAME.sceneManager.getStageHeight() - 100);
        
        toActiveSheep.position.set(EHDI.GAME.sceneManager.getStageWidth() + toActiveSheep.width * 0.5, randomYPos);
        this.gameLayer.addChild(toActiveSheep);
        this.activeObstacles.push(toActiveSheep);
        this.lastSpawn = this.distance;
        toActiveSheep.zIndex = toActiveSheep.y;
        this.nextSheep = 300;
    } else if(Math.floor(this.distance) === 300 && !this.lastSheep) {
        this.lastSheep = true;
        var toActiveSheep = new EHDI.components.Sheep("white");
        toActiveSheep.position.set(EHDI.GAME.sceneManager.getStageWidth() + toActiveSheep.width * 0.5, EHDI.GAME.sceneManager.getStageHeight() - toActiveSheep.collider.height);
        this.gameLayer.addChild(toActiveSheep);
        this.activeObstacles.push(toActiveSheep);
        this.lastSpawn = this.distance;        toActiveSheep.zIndex = toActiveSheep.y;
    } else if(Math.floor(this.distance - this.lastSpawn) === this.interval && !this.hasSpawned && ((this.nextSheep - next >= 4) && (Math.floor(this.distance) < 290))) {
        this.hasSpawned = true;
        var toActive = new EHDI.components.Bush();
        var randomizer = Math.random();
        var randomizeObstacle = 0;
        var additionalDistance = 0;
        if (this.distance > 100  && randomizer <= 0.5) {
            toActive = new EHDI.components.MovingAnimal();
            additionalDistance = 2;
        } else if(this.distance > 30 && randomizer <= 0.25 && this.distance <= 100) {
            toActive = new EHDI.components.MovingAnimal();
            additionalDistance = 2;
        } else {
            randomizeObstacle = Math.floor(EHDI.NumberUtil.randomRange(0, 3));
            while(randomizeObstacle === 1 && Math.floor(this.nextSheep - this.distance < 7))
                randomizeObstacle = Math.floor(EHDI.NumberUtil.randomRange(0, 3));
            if (randomizeObstacle === 1) {
                toActive = new EHDI.components.Tree();
            } else if (randomizeObstacle === 2) {
                toActive = new EHDI.components.Rocks();
            }
        }
        var randomYPos = EHDI.NumberUtil.randomRange(90 + toActive.collider.height * toActive.collider.anchor.y + 105, EHDI.GAME.sceneManager.getStageHeight());
        if(randomizeObstacle === 1) {
            randomYPos = EHDI.NumberUtil.randomRange(90 + toActive.collider.height * toActive.collider.anchor.y + 105, EHDI.GAME.sceneManager.getStageHeight() * 0.7);
        }
        if(toActive.move)
            randomYPos = EHDI.NumberUtil.randomRange(90 + toActive.collider.height * toActive.collider.anchor.y + 105, EHDI.GAME.sceneManager.getStageHeight() * 0.5);
        toActive.position.set(EHDI.GAME.sceneManager.getStageWidth() + toActive.sprite.width, randomYPos);
        this.gameLayer.addChild(toActive);
        this.activeObstacles.push (toActive);
        this.lastSpawn = this.distance + additionalDistance;
        toActive.zIndex = toActive.y - 50;
        
        if(randomizeObstacle === 1)
            this.lastSpawn += 2;
        
        var grassChance = Math.random();
        
        if(!toActive.move &&  (grassChance < 0.8 || this.spawnNextGrasss)) {
            var newGrass = new EHDI.components.Grass();
            var grassYRandom = EHDI.NumberUtil.randomRange(90 + newGrass.sprite.height * newGrass.sprite.anchor.y + 105, EHDI.GAME.sceneManager.getStageHeight());

            newGrass.position.set(EHDI.GAME.sceneManager.getStageWidth() + toActive.sprite.width, grassYRandom);

            if(this.checkIfOverlaps(toActive, newGrass)) {
                this.spawnNextGrass = true;
            } else {
                this.spawnNextGrass = false;
                this.gameLayer.addChild(newGrass);
                this.activeObstacles.push(newGrass);
                newGrass.zIndex = newGrass.y; 
                
            }
            
        }
        
        
    } else if(!this.obstacleLast && Math.floor(this.distance) === 291) {
        this.obstacleLast = true;
        var beforeSpawn = EHDI.GAME.sceneManager.getStageWidth();
        for(var i = 0; i < 10; i++) {
            var toActive = new EHDI.components.Tree();
            var randomizeObstacle = Math.floor(EHDI.NumberUtil.randomRange(0, 4));
            if(randomizeObstacle === 1) {
                toActive = new EHDI.components.Bush();
            } else if (randomizeObstacle === 2) {
                toActive = new EHDI.components.Rocks();
            }
            
            if(beforeSpawn === EHDI.GAME.sceneManager.getStageWidth())
                beforeSpawn += toActive.sprite.width + 75;
            
            toActive.position.set ( beforeSpawn + 100, EHDI.GAME.sceneManager.getStageHeight() * (0.25 + (i / 10)));
            this.gameLayer.addChild(toActive);
            this.activeObstacles.push(toActive);
            beforeSpawn = toActive.x;
            toActive.dontConvert = true;
            toActive.zIndex = toActive.y - 50;
            
        }
    }
    
    if(this.hasSpawned && Math.floor(this.distance) !== Math.floor(this.lastSpawn) && (300 - next >= 10)) {
        this.interval =  Math.floor(EHDI.NumberUtil.randomRange(5,10));
        this.hasSpawned = false;
    }
    
    return this.moveSpeed;
};

EHDI.components.ObstacleSpawner.prototype.updateStars = function(dt) {
    var addDistance = -this.moveSpeed * dt / 1000;
    this.distance += addDistance;
    var toInactive = null;
    
    if(this.distance <= 0) 
        EHDI.GAME.gameScene.victory();
    
    for(var i = 0; i < this.activeObstacles.length; i++) {
        this.activeObstacles[i].x -= addDistance * 96;
        if(!this.activeObstacles[i].ignoreCollision && this.activeObstacles[i].x > EHDI.GAME.sceneManager.getStageWidth() * 0.3)
            this.starCollision(this.activeObstacles[i], this.hand);
        if(this.activeObstacles[i] && this.activeObstacles[i].x - this.activeObstacles[i].width * 0.5 > EHDI.GAME.sceneManager.getStageWidth()) {
            toInactive = this.activeObstacles[i];
        }
    }
    
    if(!this.warning) {
        EHDI.GAME.gameScene.hand.hideHint();
    }
    this.warning = false;
    
    if(toInactive) {
        this.activeObstacles.splice(this.activeObstacles.indexOf(toInactive), 1);
        this.gameLayer.removeChild(toInactive);
    }
    
    for(var i = 0; i < this.activeObstacles.length; i++) {
        if(this.activeObstacles[i].isInactive) {
            this.gameLayer.removeChild(this.activeObstacles[i]);
            this.activeObstacles.splice(i, 1);
            i--;
        }
    }
    
    var nextObject = this.inactiveObstacles[this.inactiveObstacles.length-1];
    if(nextObject && nextObject.distance === Math.floor(this.distance)) {
        this.inactiveObstacles.splice(this.inactiveObstacles.indexOf(nextObject), 1);
        var toActive = new EHDI.components.Star();
         toActive.position.set(- toActive.sprite.width, nextObject.y);
        this.gameLayer.addChild(toActive);
        this.activeObstacles.push (toActive);
        toActive.zIndex = toActive.y - 105;
        
    }
    
    return this.moveSpeed;
};

EHDI.components.ObstacleSpawner.prototype.checkIfHit = function(obstacle, collidewith) {
    if(collidewith.y - collidewith.height * collidewith.anchor.y < obstacle.y + obstacle.collider.y  && collidewith.height * collidewith.anchor.y + collidewith.y > obstacle.y + obstacle.collider.y - obstacle.collider.height * obstacle.collider.anchor.y) {
        if(collidewith.x - collidewith.width * collidewith.anchor.x  < obstacle.x + obstacle.collider.x + obstacle.collider.width * obstacle.collider.anchor.x && collidewith.x + collidewith.width * collidewith.anchor.x > obstacle.x + obstacle.collider.x - obstacle.collider.width * obstacle.collider.anchor.x) {
            if(obstacle.isSheep) {
                if(this.distance < 100) {
                    EHDI.GAME.gameScene.getSheep(1);
                    EHDI.GAME.scoreManager.addScore(50);
                }
                else if(this.distance < 300) {
                    EHDI.GAME.gameScene.getSheep(2);
                    EHDI.GAME.scoreManager.addScore(150);
                }    
                else {
                    EHDI.GAME.gameScene.getSheep(3);
                    EHDI.GAME.scoreManager.addScore(300);
                }

                EHDI.GAME.grassManager.onGetSheep();
                this.activeObstacles.splice(this.activeObstacles.indexOf(obstacle), 1);
                this.gameLayer.removeChild(obstacle);
            } else if(obstacle.isGrass) {
                EHDI.GAME.grassManager.addGrass(1);
                EHDI.GAME.gameScene.showExplosion();
                EHDI.GAME.soundManager.playVO("positive0" + Math.floor(EHDI.NumberUtil.randomRange(1,6)));
                obstacle.fadeOut();
            } else {
                EHDI.GAME.gameScene.gameOver();
            }
        }
        if(collidewith.x < obstacle.x) {
            if(obstacle.isSheep || obstacle.isGrass)
                EHDI.GAME.gameScene.hand.showHint(false);
            else 
                EHDI.GAME.gameScene.hand.showHint(true);
            this.warning = true;
        }
        
    } 
};
    
EHDI.components.ObstacleSpawner.prototype.checkIfOverlaps = function(obstacle, grass) {
    /*var wow = !(grass.x + grass.sprite.x > obstacle.x + obstacle.sprite.x + obstacle.sprite.width * obstacle.sprite.anchor.x || grass.x + grass.sprite.x + grass.sprite.width * grass.sprite.anchor.x < obstacle.x + obstacle.sprite.x || grass.y + grass.sprite.y > obstacle.y + obstacle.sprite.y + obstacle.sprite.height * obstacle.sprite.anchor.y || grass.y + grass.sprite.y + grass.sprite.height * grass.sprite.anchor.y < obstacle.y + obstacle.sprite.y);
    return wow;*/
    var top = Math.max(grass.y - grass.height, obstacle.y - obstacle.height),
        bottom = Math.min(grass.y, obstacle.y);
    return (top < bottom);
}

EHDI.components.ObstacleSpawner.prototype.pauseObstacles = function() {
    for(var i = 0; i < 
    this.activeObstacles.length; i++) {
        if(this.activeObstacles[i].pause)
            this.activeObstacles[i].pause();
    }
};

EHDI.components.ObstacleSpawner.prototype.resumeObstacles = function() {
    for(var i = 0; i < 
    this.activeObstacles.length; i++) {
        if(this.activeObstacles[i].resume)
            this.activeObstacles[i].resume();
    }
};

EHDI.components.ObstacleSpawner.prototype.starCollision = function(obstacle, collidewith) {
    if(collidewith.y - collidewith.height * collidewith.anchor.y < obstacle.y + obstacle.collider.y  && collidewith.height * collidewith.anchor.y + collidewith.y > obstacle.y + obstacle.collider.y - obstacle.collider.height * obstacle.collider.anchor.y) {
        if(collidewith.x - collidewith.width * collidewith.anchor.x  < obstacle.x + obstacle.collider.x + obstacle.collider.width * obstacle.collider.anchor.x &&collidewith.x + collidewith.width * collidewith.anchor.x > obstacle.x + obstacle.collider.x - obstacle.collider.width * obstacle.collider.anchor.x && obstacle.isStar) {
            EHDI.GAME.scoreManager.addScore(10);
            EHDI.GAME.soundManager.playVO("positive0" + Math.floor(EHDI.NumberUtil.randomRange(1,6)));
            EHDI.GAME.gameScene.showExplosion();
            obstacle.fadeOut();
        }
        if(collidewith.x > obstacle.x && obstacle.isStar) {
            EHDI.GAME.gameScene.hand.showHint(false);
            this.warning = true;
        }    
    }
};