﻿function EnemyHolder(holder)
{
    this.holder = holder;
    this.holder.EnemyHolder = this;
    EventCenter.addListener(this, Events.BOUNDARY_RESETS, "moveHolder");
    EventCenter.addListener(this, Events.ENTER_FRAME, "onEnterFrame");
    EventCenter.addListener(this, Events.SHOT_MOVES, "checkShotHit");
    this.init();
}

EnemyHolder.prototype.init = function()
{
    this.enemies = new Array();
    this.enemyTypes = Settings.ENEMY_TYPE_COUNT;
    this.rows = new Array();
    this.cols = new Array();
    this.rowCount = Math.min(Settings.ENEMY_ROWS, Settings.ENEMY_ROW_MAX);
    this.colCount = Math.min(Settings.ENEMY_COLS, Settings.ENEMY_COL_MAX);
    
    this.enemyCount = this.rowCount * this.colCount;
    this.killCount = 0;
    
    this.cellWidth = Settings.ENEMY_WIDTH + Settings.ENEMY_X_SPACE;
    this.cellHeight = Settings.ENEMY_HEIGHT + Settings.ENEMY_Y_SPACE;
    
    this.xPos = Boundary.xMin + Settings.ENEMY_X_INSET;
    this.yPos = Boundary.yMin + Settings.ENEMY_Y_INSET;

    this.width = Settings.ENEMY_WIDTH * this.colCount;
    this.width += (this.colCount - 1) * Settings.ENEMY_X_SPACE;

    this.height = Settings.ENEMY_HEIGHT * this.rowCount;
    this.height += (this.rowCount - 1) * Settings.ENEMY_Y_SPACE;  
    
    this.shotCounter = 0; 
    
    // height / width tracking
    this.topRow = 0;
    this.bottomRow = this.rowCount - 1;
    this.leftCol = 0;
    this.rightCol = this.colCount - 1;
    this.leftInset = 0;
    this.rightInset = 0;
    this.topInset = 0;
    this.bottomInset = 0;
    
    this.direction = -1; 
    this.moveRate = Settings.ENEMY_MOVE_RATE;
    this.buildHolder();
    this.buildEnemies();
}

EnemyHolder.prototype.buildHolder = function()
{
    var eh = this.enemyHolder = document.createElement('div');
    with(eh.style)
    {
        width = this.width + "px";
        height = this.height + "px";
        position = "absolute";
        top = this.yPos + "px";
        left = Boundary.yMin + (Boundary.xMax - this.width) / 2 + "px";
        zIndex = "10";
    }
    this.holder.appendChild(eh);
}

EnemyHolder.prototype.buildEnemies = function()
{   
    var type = 1;
    typeCount = Settings.ENEMY_TYPE_COUNT;
 
    for(var i = 0; i < this.rowCount; i++)
    {
        this.rows[i] = new Array();
        this.enemies[i] = new Array();
        
        for(var j = 0; j < this.colCount; j++)
        {
            var y = i * this.cellHeight;
            var x = j * this.cellWidth;
           
            if(!this.cols[j]) this.cols[j] = new Array();
            
            this.rows[i][j] = true;
            this.cols[j][i] = true;
            this.enemies[i][j] = new Enemy(x, y, type, this.enemyHolder);
        }
        
        // increment enemy type
        if(type < typeCount) type++;
    }
}

EnemyHolder.prototype.onEnterFrame = function()
{
    this.xPos = parseInt(this.enemyHolder.style.left);
    this.xPos += this.direction * this.moveRate;
   // trace(this.rightInset);
    if( this.xPos < Boundary.xMin - this.leftInset ||
        this.xPos + this.width - this.rightInset > Boundary.xMax)
    {
        this.yPos += this.moveRate;
        this.direction *= -1;
    }
   
    if(this.yPos >= Boundary.yMax + this.bottomInset)
    {
        // game over!!
    }
    this.enemyHolder.style.left = this.xPos + "px";
    this.enemyHolder.style.top = this.yPos + "px";
    
    // shootin!
    this.shotCounter++;
    if(this.shotCounter % Settings.ENEMY_SHOT_FREQUENCY == 1) this.enemyShoot();
}

// this makes sure that the holder is in line with the resized screen
EnemyHolder.prototype.moveHolder = function(evt)
{
    this.xPos += evt.data.x;
    this.yPos += evt.data.y;
    this.enemyHolder.style.left = this.xPos + "px";
    this.enemyHolder.style.top = this.yPos + "px";   
}

EnemyHolder.prototype.checkShotHit = function(evt)
{
    var x = evt.data.x;
    var y = evt.data.y;
    if(evt.data.type == "ship")
    {
        if(y > this.yPos + this.topInset && y < this.yPos + this.height - this.bottomInset)
        {
            if(x > this.xPos + this.leftInset && x < this.xPos + this.width - this.rightInset)
            {
                x = x - this.xPos;
                y = y - this.yPos;
                var col = Math.floor(x / this.cellWidth);
                var row = Math.floor(y / this.cellHeight);
               
                var targetX = (col + 1) * this.cellWidth - Settings.ENEMY_X_SPACE;
                var targetY = (row + 1) * this.cellHeight - Settings.ENEMY_Y_SPACE;
                
                if(x < targetX  && y < targetY)
                {
                    if(this.enemies[row][col])
                    {
                        this.killCount++;
                        this.enemies[row][col].die();
                        EventCenter.broadcast(Events.SHOT_HIT, evt.data.shot);                 
                        if(this.killCount < this.enemyCount)
                        {
                            this.updateParams(row, col);
                        }
                        else
                        {
                            EventCenter.broadcast(Events.NEXT_LEVEL);
                            this.die(true);
                            this.init();
                        }
                    }
                }
            }
        }
    }
}

EnemyHolder.prototype.updateParams = function(row, col)
{
    this.rows[row][col] = false;
    this.cols[col][row] = false;
    this.enemies[row][col] = false;
    // check height / width shifts
    this.paramGrind("top", row);
    this.paramGrind("bottom", row);
    this.paramGrind("left", col);
    this.paramGrind("right", col);
    // set move rate
    this.moveRate = Math.round((LevelManager.LEVEL * (this.killCount / this.enemyCount) / 2) + this.moveRate);
   
}
/**
*   @param param - "left"
*   @param target - this.leftCol
*   @param array - this.cols
*   @param value - col 
*   @param increment - +1/-1
*/
EnemyHolder.prototype.paramGrind = function(param, value)
{
    var change = true;
    var inset = param + "Inset";
    var array;
    var increment;
    var target;
    var cellParam;
    
    if(param == "left" || param == "right") // then is cols
    {
        array = this.cols;
        target = param + "Col";
        increment = (param == "left") ? 1 : -1;
        cellParam = "cellWidth";
    }
    else // is rows
    {
        array = this.rows;
        target = param + "Rows";
        increment = (param == "top") ? 1 : -1;
        cellParam = "cellHeight";
    }
    // loop through any empty sets on the exterior
    while(change)
    {
        if(this[target] == value)
        {
            for(var i in array[value])
            {
                if(array[value][i]) change = false;
                //trace(param + " " +change);
            }
            if(change)
            {
                this[target] += increment;
                this[inset] += this[cellParam];
                value += increment;
            }
        }
        else 
        {
            change = false;
        }
    }
}

EnemyHolder.prototype.enemyShoot = function()
{

    for(var i = this.leftCol; i <=  this.rightCol; i++)
    {
        var last = 0;
        for(var j = this.topRow; j <= this.bottomRow; j++)
        {
            if(this.cols[i][j]) last = j;
        }
        if(this.enemies[last][i])
        {
            var x = this.xPos + i * this.cellWidth;
            var y = this.yPos + last * this.cellHeight;
            this.enemies[last][i].fire(x, y);
        }
    }
}

EnemyHolder.prototype.die = function(reset)
{    
    if(!reset)
    {
        this.enemyHolder.innerHTML = '';
        EventCenter.removeListener(this, Events.BOUNDARY_RESETS, "moveHolder");
        EventCenter.removeListener(this, Events.ENTER_FRAME, "onEnterFrame");
        EventCenter.removeListener(this, Events.SHOT_MOVES, "checkShotHit");
    }
    else
    {
        this.holder.removeChild(this.enemyHolder);
    }
}
