// *************************************************************************************************************************
// TileBoxObj (Javascript Object)
//
// A TileBoxObj is a wrapper around a 'div' HTML element which can contain an unlimited number of user tiles.
// Add tiles to the TileBoxObj through addTile().  A callback can be specified for when 'Sign In' was clicked
// and any of the UserTileObj, and the UserTileObj will be returned through the call to callback so the function
// needs to handle this.  Also, optionally, another callback can be specified, which will be called when the
// TileBoxObj becomes empty.
// To add the TileBoxObj to another element, call the draw() function providing the actual HTML element to
// which appendChild() will be called to attach the TileBox.
// *************************************************************************************************************************

/// <reference path="usertile.js">
/// <reference path="uicore.js" />

TileBoxObj = function(uniqueID, maxHeight, callBack, emptyCallback, defaultWidth)
{
    /// <summary>Constructor for TileBoxObj.  [TileBox = 'div' HTML Element]</summary>
    /// <param name="uniqueID">[OPTIONAL] (string) Actual ID of this element.  If null, generates random unique ID.</param>
    /// <param name="maxHeight">[OPTIONAL] (string/int) Maximum height of this tile box before scrolling starts
    /// (default = 310px)</param>
    /// <param name="callBack">(function) Global function to call which takes an index as a parameter.  This
    /// function will be called when 'Sign In' is clicked on any user tile, and the tile is sent as a parameter</param>
    /// <param name="emptyCallback">(function) Global function to call when all tiles have been removed from this tilebox</param>
    /// <returns>A new TileBoxObj</returns>
    var self = this;
    
    this.m_strID = (uniqueID != undefined) ? uniqueID : 'TileBoxObj' + UIHelper.generateRandomString(10);
    this.m_varMaxHeight = maxHeight ? maxHeight : '282px';
    this.m_fnCallBack = callBack;
    this.m_fnEmptyCallback = emptyCallback;
    this.m_arrTiles = new Array();

    // Elements
    this.m_elDivTileBox = null;
    this.m_elContainer = null;
    this.m_lDefaultWidth = defaultWidth;
    
    this.m_elDivTileBox = document.createElement('div');
    this.m_elDivTileBox.style.height = this.m_varMaxHeight;
    this.m_elDivTileBox.style.width = '100%';
    this.m_elDivTileBox.style.overflow = 'auto';
    this.m_elDivTileBox.onscroll = function() { self.scrollTile(); }                    
    
}

TileBoxObj.prototype =
{
    draw:function(elementDiv)
    {
        /// <summary>Calls appendChild() on the provided element, appending this div element</summary>
        /// <param name="elementDiv">(HTML Element) HTML element to append this tile box to</param>
        if(elementDiv != undefined)
        {
            this.m_elContainer = elementDiv;
            
            if(this.m_arrTiles.length<=2)
            {
                this.m_elDivTileBox.style.overflow = 'visible';
                this.m_elDivTileBox.style.height = 'auto'
            }
            this.m_elContainer.appendChild(this.m_elDivTileBox);
        }
        this.refreshTile();
    },
    getElement:function()
    {
        return this.m_elDivTileBox;
    },
    
    addTile:function(userTileObj)
    {
        /// <summary>Adds this user tile to the tile box</summary>
        /// <param name="userTileObj">(UserTileObj) User Tile to add</param>
        if(userTileObj != undefined)
        {
            var newIndex = this.m_arrTiles.length;
            this.m_arrTiles[newIndex] = userTileObj;
            this.m_arrTiles[newIndex].draw(this.m_elDivTileBox);
            this.m_arrTiles[newIndex].attachClickEvent(this);
            this.m_arrTiles[newIndex].setIndex(newIndex);
        }
    },
    
    submit:function(id)
    {
        if((id >= 0) && (id < this.m_arrTiles.length) && (this.m_arrTiles[id] != undefined) && (this.m_fnCallBack != undefined))
            this.m_fnCallBack(this.m_arrTiles[id]);
    },
    
    switchTiles:function(index)
    {
        if((index >= 0) && (index < this.m_arrTiles.length))
        {
            if(this.m_arrTiles[index].isActive())
                return true;
            else
            {
                this.m_arrTiles[index].activate();
                this.m_arrTiles[index].detachClickEvent();

                var objEx = new ExternalWrapperObj();
                if ( objEx!= undefined && objEx != null )
                    objEx.adjustWindowSize( null, null, true);
                
                // Make sure all other tiles are not activated
                for(var i=0;i<this.m_arrTiles.length;i++)
                {
                    if(i!=index)
                    {
                        if(this.m_arrTiles[i].isActive())
                        {
                            this.m_arrTiles[i].deactivate();
                            this.m_arrTiles[i].attachClickEvent(this);
                        }
                    }
                }
                this.refreshTile();
            }
        }
    },
    
    getTile:function(index)
    {
        /// <summary>Retrieves the UserTileObj at the specified index</summary>
        /// <param name="index">(int) Index of user tile to retrieve</param>
        if((index >= 0) && (index < this.m_arrTiles.length))
            return this.m_arrTiles[index];
        return null;
    },
    
    removeTile:function(index)
    {
        /// <summary>Removes the UserTileObj at the specified index</summary>
        /// <param name="index">(int) Index of user tile to remove (also deletes user from persisted state)</param>
        if((index >= 0) && (index < this.m_arrTiles.length))
        {
            var newArray = new Array();
            // Remove tile from parent
            if(this.m_arrTiles[index] != undefined)
            {
                if ( this.m_arrTiles.length > 1 )
                {
                    this.m_arrTiles[index].removeMe();
                } else {
                    // for the last tile, we don't change ui, switch
                    // to newuser page seamlessly
                    this.m_arrTiles[index].removeMe( true );
                    if (this.m_fnEmptyCallback != undefined)
                        this.m_fnEmptyCallback();
                    return;
                }
            }

                
            // Put other tiles into another array (no remove in javascript arrays)
            for(var i=0; i < index; i++)
                newArray.push(this.m_arrTiles[i]);
            for(var i=(index+1); i < this.m_arrTiles.length; i++)
            {
                var newIndex = i -1;
                var currTile = this.m_arrTiles[i];
                currTile.setIndex(newIndex);
                newArray.push(currTile);
            }
            this.m_arrTiles = newArray;
            if(this.m_arrTiles.length<=2)
            {
                this.m_elDivTileBox.style.overflow = 'visible';
                this.m_elDivTileBox.style.height = 'auto'
            }

            this.refreshTile();
            
            var objEx = new ExternalWrapperObj();
            if ( objEx!= undefined && objEx != null )
                objEx.adjustWindowSize( null, null, true);
        }
    },

    // adjust the positions of the combobox 
    scrollTile:function()
    {
        if ( this.m_elDivTileBox != undefined )
        {
            var offset = this.m_elDivTileBox.scrollTop;
            for(var i=0; i < this.m_arrTiles.length; i++)
            {
                var currTile = this.m_arrTiles[i];
                currTile.adjustCombobox(offset);
            }            
        }
    },

    // refresh tile, when scroll bar appear, need to increase the width
    refreshTile:function()
    {
        if ( null == this.m_elDivTileBox || undefined == this.m_elDivTileBox )
            return;
        
        if ( this.m_elDivTileBox.scrollHeight > 282 ) // overflow
        {
            this.m_elDivTileBox.style.width = '100%';
        } else {
            this.m_elDivTileBox.style.width = this.m_lDefaultWidth;
        }
        
    },
	getCount:function()
	{
	    /// <summary>Gets the number of tiles currently in this tilebox</summary>
	    if(this.m_arrTiles != undefined)
	        return this.m_arrTiles.length;
        return 0;
	}
}

