//##############################################################################
var entityScaleFactor = 0.2;

//------------------------------------------------------------------------------
function Entity()
{    
    this.item = null;
    this.items = new Array();
    this.entities = new Array();
    this.childScale = 1;
    this.incomingWords = new Array();
    this.lockPosition = false;
    this.didSearch = false;
    this.itemsAdded = false;
}

//------------------------------------------------------------------------------
Entity.prototype.startSearches = function(priority)
{
}

//------------------------------------------------------------------------------
Entity.prototype.restartSearches = function(priority)
{
    this.didSearch = false;
    this.startSearches(priority);
}

//------------------------------------------------------------------------------
Entity.prototype.addItems = function()
{
    this.itemsAdded = true;
    
    var count = this.items.length;
    var a;
    for(a = 0; a < count; a++)
    {
        var item = this.items[a];
        if(item.attached)
            continue;
        
        doc.addItem(item);
        item.posX = this.item.posX + item.relativePosX;
        item.posY = this.item.posY + item.relativePosY;
    }

    this.startSearches(1);
}

//------------------------------------------------------------------------------
Entity.prototype.removeItems = function()
{
    this.itemsAdded = false;
    
    var count = this.items.length;
    var a;
    for(a = 0; a < count; a++)
    {
        var item = this.items[a];
        doc.removeItem(item);
        
        var entity = item.entity;
        if(entity)
            entity.removeItems();
    }
}

//------------------------------------------------------------------------------
Entity.prototype.plantSeed = function(data, type)
{
    this.incomingWords.push({ data: data, type: type});
}

//------------------------------------------------------------------------------
Entity.prototype.fadeInLabel = function()
{
    if(this.label)
		this.label.fadeIn();
}

//------------------------------------------------------------------------------
Entity.prototype.fadeOutLabel = function()
{
    if(this.label)
		this.label.fadeOut();
}

//------------------------------------------------------------------------------
Entity.prototype.update = function()
{
    if(!this.item.attached)
        return;
        
    // ___ Move Them
    var count = this.items.length;
    var a;
    for(a = 0; a < count; a++)
    {
        var item = this.items[a];
        
        var oldX = item.posX;
        var oldY = item.posY;
        
        if(item.attached && item.isLoaded())
        {
            item.relativePosX += item.velocityX;
            item.relativePosY += item.velocityY;
        }
        
        item.posX = this.item.posX + item.relativePosX;
        item.posY = this.item.posY + item.relativePosY;
        
        if(item.entity.label)
        	item.entity.label.update();

        if(controller.focusItem == item)        
            viewport.shiftPan(new Point(item.posX - oldX, item.posY - oldY));                        
    }

    // ___ Adjust Velocity    
    var parentBounds = this.item.getBounds();
    for(a = 0; a < count; a++)
    {
        var item = this.items[a];
        if(!item.attached || !item.isLoaded())
            continue;
        
        var myBounds = item.getBounds();
        var collision = false;
        var collisionCenter = null;
        var collisionArea = 0;

        var b;
        for(b = 0; b < count; b++)
        {
            var itemB = this.items[b];
            if(!itemB.attached || !itemB.isLoaded())
                continue;
            
            var bounds = itemB.getBounds();
            if(a == b)
                bounds = parentBounds;
                
            if(myBounds.intersects(bounds))
            {
                collision = true;
                var area = myBounds.getIntersection(bounds).getArea();
                if(area > collisionArea)
                {
                    collisionCenter = bounds.getCenter();
                    collisionArea = area;
                }
            }
        }
                
        if(collision)
        {
            var collisionScale = collisionArea / myBounds.getArea();
            
            var diff = new Point();
            diff.x = item.posX - collisionCenter.x;
            diff.y = item.posY - collisionCenter.y;
            diff.normalize();
            
            var moveX = diff.x * collisionScale * 4 * this.childScale;
            var moveY = diff.y * collisionScale * 4 * this.childScale;

            item.velocityX = (item.velocityX + moveX) / 2;
            item.velocityY = (item.velocityY + moveY) / 2;
        }
        else
        {
            item.velocityX *= 0.8;
            item.velocityY *= 0.8;
        }
    }

    // ___ Update Our Children
    count = this.entities.length;
    for(a = 0; a < count; a++)
    {
        var entity = this.entities[a];
        if(!entity.item.attached)
            continue;

        entity.update();
    }   
    
    // ___ Add New Ones    
    var seed = this.incomingWords.shift();
    if(seed)
    {
        var velocityRange = 40 * this.childScale;
     	if(seed.type == 'tag')
        {
            var item = new TextItem(seed.data, 10 * this.childScale);
            item.velocityX = 0;
            item.velocityY = 0;
            item.relativePosX = (Math.random() * velocityRange) - (velocityRange / 2);
            item.relativePosY = (Math.random() * velocityRange) - (velocityRange / 2);;
            item.posX = this.item.posX + item.relativePosX;
            item.posY = this.item.posY + item.relativePosY;
            item.parent = this.item;
            
            var word = new Word();
			word.isTag = true;
            word.childScale = this.childScale * entityScaleFactor;
            word.text = seed.data;
            word.item = item;
            item.entity = word;
    
            if(this.itemsAdded && this.item == controller.focusItem)
                doc.addItem(item);
                
            this.entities.push(word);
            this.items.push(item);
        }
    }
    
    // ___ delete excess
    if(this.isWord && controller.focusItem == this.item 
    		&& this.items.length > 20)
    {
        var loadedCount = 0;
        var a; 
        for(a = 0; a < this.items.length; a++)
        {
            if(this.items[a].isLoaded())
                loadedCount++; 
        }
        
        if(loadedCount > 20) 
        {
            var item = this.items[0];
            item.opacity -= 0.05;
            if(item.opacity <= 0)
            {
                this.items.shift();
                var photo = this.entities.shift();
                if(item.attached)
                    doc.removeItem(item);
            }
        }
    }
}

//------------------------------------------------------------------------------
Entity.prototype.getDepth = function()
{
    if(this.item && this.item.parent && this.item.parent.entity)
        return this.item.parent.entity.getDepth() + 1;
        
    return 0;
}

