//Augment Module
var ITW = (function(itw){
    "use strict";
    //aliases
    var managers, protot, _this, _super;
    itw.managers = itw.managers || Object.create(null);
    managers = itw.managers;

    //privates - initialize on constructor function
    var _stageWidth;
    var _obstacles;
    var _reefs, _sunkenships, _islands, _ships, _anchors;
    var _objArea = [0, 0, 0, 0];
    var _lastSpawnedObstacle;
    var _surfaceTimer, _surfaceChance, _surfaceObstacleDist;
    var _underTimer, _underChance, _underObstacleDist;
    var _player;

    managers.ObstacleManager = function( player ){
        this.super.call(this);
        _this = this;
        _super = _this.super;
        _player = player;

        var _init = function(){
            // init stuff here
            _stageWidth = ITW.SceneMgr.getStageWidth();
            _obstacles = [];
            _reefs = [];
            _sunkenships = [];
            _islands = [];
            _ships = [];
            _anchors = [];

            _surfaceTimer = 0;
            _surfaceChance = 0.6;
            _surfaceObstacleDist = _stageWidth * 0.7;

            _underTimer = 0;
            _underChance = 0.5;
            _underObstacleDist = _stageWidth * 0.55;

            _this.initObstacles();
        }
        _init();
    }

    protot = managers.ObstacleManager.prototype = Object.create(EHDI.aka.Container.prototype);
    protot.constructor = managers.ObstacleManager;
    protot.super = EHDI.aka.Container;

    protot.loop = function( dt ){
        if( _surfaceObstacleDist > _stageWidth * 0.6 ){
            _surfaceObstacleDist -= dt * ITW.GameMgr.getSpeed();
        }
        else{
            _surfaceTimer += dt;

            if( _surfaceTimer > 0.75 ){
                _surfaceTimer = 0;
                _this.spawnSurfaceObstacle();
            }
        }

        if( _underObstacleDist > _stageWidth * 0.5 ){
            _underObstacleDist -= dt * ITW.GameMgr.getSpeed();
        }
        else{
            _underTimer += dt;

            if( _underTimer > 0.25 && ( ITW.GameMgr.getScore() > 30 )){
                _underTimer = 0;
                _this.spawnUnderObstacle();
            }
        }

        var obstacleLength = _obstacles.length;
        if( obstacleLength > 0 ){
            var curSpeed = ITW.GameMgr.getSpeed();

            for ( var i = obstacleLength - 1; i >= 0; i-- ) {
                _obstacles[i].x -= dt * curSpeed;

                if( _obstacles[i].x < -( _obstacles[i].width * 0.5 ) ){
                    var obstacle = _obstacles[i];
                    _obstacles.splice( i, 1 );
                    _this.removeChild( obstacle );
                }
                else{
                    _this.checkCollision( _obstacles[i] );
                }
            }
        }
    }

    protot.initObstacles = function(){
        _this.initReef();
        _this.initSunken();
        _this.initIsland();
        _this.initShip();
    }

    protot.spawnSurfaceObstacle = function(){
        if( EHDI.NumberUtil.randomRange(0, _surfaceChance) > 0.4 ){
            _surfaceChance -= 0.1;
            return;
        }

        switch( Math.floor( EHDI.NumberUtil.randomRange(1, 4) ) ){
            case 1:
            case 2:
                _this.addShip();
                break;

            case 3:
                _this.addIsland();
                break;
        }

        _surfaceChance += 0.2;
        if( _surfaceChance > 1.1 ) _surfaceChance = 1.1;
    }

    protot.spawnUnderObstacle = function(){
        if( EHDI.NumberUtil.randomRange(0, _underChance) > 0.5 ){
            _underChance -= 0.1;
            return;
        }

        var textureRandomizer = Math.floor(EHDI.NumberUtil.randomRange(1, 4));
        var randomIndex;
        if(textureRandomizer === 0) {
            return;
        } else if(textureRandomizer < 3) {
            _this.addReef();

        } else if(textureRandomizer === 3) {
            _this.addSunken();
        }

        _this.checkObstacleOverlap();
        _underChance += 0.2;
    }

    protot.initReef = function(){
        for( var i = 0; i <= 3; i++ ){
            for( var j = 0; j < 2; j++ ){
                _reefs.push( new ITW.components.Reef( i ) );
            }
        }
    }

    protot.initSunken = function(){
        for( var i = 0; i < 3; i++ ){
            _sunkenships.push( new ITW.components.SunkenShip() );
        }
    }

    protot.initIsland = function(){
        for( var i = 0; i < 3; i++ ){
            _islands.push( new ITW.components.Island() );
        }
    }

    protot.initShip = function(){
        for( var i = 0; i < 3; i++ ){
            _ships.push( new ITW.components.Ship() );
            _anchors.push( new ITW.components.Anchor() );
        }
    }

    protot.addReef = function(){
        var randomIndex;
        do{
            randomIndex = Math.floor( EHDI.NumberUtil.randomRange(0, _reefs.length) );
            if( _reefs[ randomIndex ].parent !== null ){
                randomIndex = -1;
            }
        }while( randomIndex === -1 );

        var reefObj = _reefs[ randomIndex ];
        reefObj.resetState();

        _this.addChild( reefObj );
        _obstacles.push( reefObj );

        _underObstacleDist = reefObj.x;
    }

    protot.addSunken = function(){
        var randomIndex;
        do{
            randomIndex = Math.floor( EHDI.NumberUtil.randomRange(0, _sunkenships.length) );
            if( _sunkenships[ randomIndex ].parent !== null ){
                randomIndex = -1;
            }
        }while( randomIndex === -1 );

        var sunkenObj = _sunkenships[ randomIndex ];
        sunkenObj.resetState();

        _this.addChild( sunkenObj );
        _obstacles.push( sunkenObj );

        _underObstacleDist = sunkenObj.x;
    }

    protot.addIsland = function(){
        var randomIndex;
        do{
            randomIndex = Math.floor( EHDI.NumberUtil.randomRange(0, _islands.length) );
            if( _islands[ randomIndex ].parent !== null ){
                randomIndex = -1;
            }
        }while( randomIndex === -1 );

        var islandObj = _islands[ randomIndex ];
        islandObj.resetState();

        _this.addChild( islandObj );
        _obstacles.push( islandObj );

        _surfaceObstacleDist = islandObj.x;
    }

    protot.pauseShips = function(){
      for(var i = 0; i < _ships.length; i++){
        _ships[i].pause();
      }
    }

    protot.resumeShips = function(){
      for(var i = 0; i < _ships.length; i++){
        _ships[i].resume();
      }
    }

    protot.addShip = function(){
        // add the ship first
        var randomShipIndex;
        do{
            randomShipIndex = Math.floor( EHDI.NumberUtil.randomRange(0, _ships.length) );
            if( _ships[ randomShipIndex ].parent !== null ){
                randomShipIndex = -1;
            }
        }while( randomShipIndex === -1 );

        var shipObj = _ships[ randomShipIndex ];
        shipObj.resetState();

        _this.addChild( shipObj );
        _obstacles.push( shipObj );

        // add the anchor now
        var randomAnchorIndex;
        do{
            randomAnchorIndex = Math.floor( EHDI.NumberUtil.randomRange(0, _anchors.length) );
            if( _anchors[ randomAnchorIndex ].parent !== null ){
                randomAnchorIndex = -1;
            }
        }while( randomAnchorIndex === -1 );

        var anchorObj = _anchors[ randomAnchorIndex ];
        anchorObj.x = shipObj.x + ( shipObj.width * 0.225 );
        if( anchorObj.y === 0 ) anchorObj.y = shipObj.y + ( shipObj.height * 0.1 ) + anchorObj.height;
        anchorObj.resetState();

        _this.addChild( anchorObj );
        _obstacles.push( anchorObj );

        _surfaceObstacleDist = shipObj.x;
    }

    protot.checkObstacleOverlap = function(){
        if( _obstacles.length < 2 ) return;

        var collArea1 = _obstacles[ _obstacles.length - 1 ].getCollisionArea();
        var collArea2 = _obstacles[ _obstacles.length - 2 ].getCollisionArea();
        var widthArea1, widthArea2, heightArea1, heightArea2;

        if( typeof collArea1 === "undefined" || typeof collArea2 === "undefined" ) return;

        if( typeof collArea1.r !== "number" ){
            widthArea1 = collArea1.width;
            heightArea1 = collArea1.height;
        }
        else{
            widthArea1 = heightArea1 = collArea1.r;
        }

        if( typeof collArea2.r !== "number" ){
            widthArea2 = collArea2.width;
            heightArea2 = collArea2.height;
        }
        else{
            widthArea2 = heightArea2 = collArea2.r;
        }

        if((Math.abs( collArea1.x - ( collArea2.x + widthArea2 ) ) < _player.width * 1.1 ||
            Math.abs( ( collArea1.x + widthArea1 ) - collArea2.x ) < _player.width * 1.1) &&
           (Math.abs( collArea1.y - ( collArea2.y + heightArea2 ) ) < _player.height * 1.4 ||
            Math.abs( ( collArea1.y + heightArea1 ) - collArea2.y ) < _player.height * 1.4)
        ){
            var obstacle = _obstacles[ _obstacles.length - 1 ];
            _obstacles.splice( _obstacles.length - 1, 1 );
            _this.removeChild( obstacle );

            _underChance -= 0.2;
            _underObstacleDist = _stageWidth * 0.55;
        }
    }

    protot.checkCollision = function( obstacle ){
        if (typeof obstacle.getCollisionArea !== "function") return;
        _objArea = obstacle.getCollisionArea();

        if( typeof _objArea === "undefined" ) return;
        if( _objArea.x > _stageWidth * 0.4 ) return;
        var pcir = { x: _player.x + (_player.width * 0.1), y: _player.y - (_player.height * 0.02),
          r: _player.width * 0.125 };
        var pcirn = { x: pcir.x + 30, y: pcir.y, r: pcir.r + 50}

        if( typeof _objArea.r !== "number" ){
            if( _objArea.x + _objArea.width + 50 < _player.x - ( _player.width * 0.5 ) ) return;

            if( EHDI.CollisionUtil.circleToRect(pcirn, _objArea) ){
                _player.nearCollision = true;
            }else _player.nearCollision = false;

            if( EHDI.CollisionUtil.circleToRect(pcir, _objArea) ){
                this.gameover( obstacle );
            }
        }
        else{
            if( _objArea.x + _objArea.r + 25 < _player.x - ( _player.width * 0.5 ) ) return;

            if( EHDI.CollisionUtil.circleToRect(pcirn, _objArea) ){
                _player.nearCollision = true;
            }else _player.nearCollision = false;

            if( EHDI.CollisionUtil.circleToCircle(pcir, _objArea) ){
              this.gameover( obstacle );
            }
        }
    }

    /**
     * ADDED
     */
    protot.gameover = function( obstacle ){
      if(!!ITW.GameMgr.getGameOver()) return;
      this.pauseShips();
      ITW.GameMgr.setLoop("obstacle", false);
      ITW.GameMgr.setLoop("bg", false);
      _player.animateDeath(true, function(){
          ITW.GameMgr.setGameOver(true);
          ITW.DBoneFactory.enableClock = false;
      })
    }

    protot.destroy = function(){
      while(_obstacles.length > 0)  _obstacles.pop().destroy({children: true});
      while(_reefs.length > 0)  _reefs.pop().destroy({children: true});
      while(_sunkenships.length > 0)  _sunkenships.pop().destroy({children: true});
      while(_islands.length > 0)  _islands.pop().destroy({children: true});
      while(_ships.length > 0)  _ships.pop().destroy({children: true});
      while(_anchors.length > 0)  _anchors.pop().destroy({children: true});

      _super.prototype.destroy.call(this, {children: true});
    }

    return itw;
}(ITW || Object.create(null)));