////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

package spark.components.gridClasses
{
import flash.geom.Rectangle;
import flash.utils.Dictionary;

import mx.collections.IList;
import mx.core.IFactory;
import mx.core.IVisualElement;
import mx.core.mx_internal;
import mx.events.CollectionEvent;
import mx.events.CollectionEventKind;

import spark.components.DataGrid;
import spark.components.Grid;
import spark.components.GridColumnHeaderGroup;
import spark.components.Group;
import spark.components.supportClasses.GroupBase;
import spark.layouts.supportClasses.LayoutBase;

use namespace mx_internal;

[ExcludeClass]

/**
 *  @private
 *  Virtual horizontal layout for each column header view Group.  This is not a general 
 *  purpose layout class, it's only intended for column header view Groups.
 * 
 *  This layout tracks the layout of the corresponding GridView. 
 *  
 */
public class GridHeaderViewLayout extends LayoutBase
{
    /**
     *  Constructor. 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */    
    public function GridHeaderViewLayout()
    {
        super();
    }
    
    //--------------------------------------------------------------------------
    //
    //  Internal variables
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  Layers for header renderers and separators.
     */
    private var rendererLayer:Group;
    private var overlayLayer:Group;
    
    /**
     *  @private
     *  Cached header renderer heights maintained by the measure() method, 
     *  and the current content height.
     */
    private const rendererHeights:Array = [];
    private var maxRendererHeight:Number = 0;
    
    /**
     *  @private
     *  Bounds of all currently visible header renderers.
     */
    private const visibleRenderersBounds:Rectangle = new Rectangle();
    
    /**
     *  @private
     *  Currently visible header renderers.
     */
    private const visibleHeaderRenderers:Vector.<IGridItemRenderer> = new Vector.<IGridItemRenderer>();
    
    /**
     *  @private
     *  Currently visible header separators.
     */
    private const visibleHeaderSeparators:Vector.<IVisualElement> = new Vector.<IVisualElement>();
    
    /**
     *  @private
     *  The elements available for reuse aka the "free list".   Maps from an IFactory 
     *  to a list of the elements that have been allocated by that factory and then freed.   
     *  The list is represented by a Vector.<IVisualElement>.
     */
    private var freeElementMap:Dictionary = new Dictionary(); 
    
    /**
     *  @private
     *  Records the IFactory used to allocate a Element so that freeVisualElement()
     *  can find it again.
     */
    private var elementToFactoryMap:Dictionary = new Dictionary();
	
	//---------------------------------------------------------------
	//
	//  Properties
	//
	//---------------------------------------------------------------

	//----------------------------------
	//  columns
	//----------------------------------
	
	private var _columnsView:IList;
	
	/**
	 *  @private
	 *  Returns a cached reference to gridView.columns. A local reference is kept so
	 *  that we can remove the colllection change handler if the columns list changes.
	 */
	private function get columnsView():IList
	{
		const gridView:GridView = this.gridView;
		const newColumns:IList = (gridView) ? gridView.gridViewLayout.columnsView : null;
		
		if (newColumns != _columnsView)
		{
			if (_columnsView)
				_columnsView.removeEventListener(CollectionEvent.COLLECTION_CHANGE, columns_collectionChangeHandler);
			
			_columnsView = newColumns;
			
			if (_columnsView)
				_columnsView.addEventListener(CollectionEvent.COLLECTION_CHANGE, columns_collectionChangeHandler);
		}
		
		return _columnsView;
	}
	
	//----------------------------------
	//  grid (private read-only)
	//----------------------------------
	
	/**
	 *  @private
	 */
	private function get grid():Grid
	{
		const view:GridView = this.gridView;
		return (view) ? view.parent as Grid : null;
	}
	
	//----------------------------------
	//  gridColumnHeaderGroup
	//----------------------------------
	
	private var _gridColumnHeaderGroup:GridColumnHeaderGroup = null;
	
	/**
	 *  The GridColumnHeaderGroup whose columns this header view is associated with.
	 * 
	 *  This property is set by GridColumnHeaderGroup.
	 */
	public function get gridColumnHeaderGroup():GridColumnHeaderGroup
	{
		return _gridColumnHeaderGroup
	}
	
	/**
	 *  @private
	 */
	public function set gridColumnHeaderGroup(value:GridColumnHeaderGroup):void
	{
		if (value == _gridColumnHeaderGroup)
			return;
		
		_gridColumnHeaderGroup = value;
	}	
	
	//----------------------------------
	//  gridView
	//----------------------------------
	
	private var _gridView:GridView = null;
	
	/**
	 *  The GridView whose columns this header view is associated with.
	 * 
	 *  This property is set by GridColumnHeaderGroup.
	 */
	public function get gridView():GridView
	{
		return _gridView
	}
	
	/**
	 *  @private
	 */
	public function set gridView(value:GridView):void
	{
		if (value == _gridView)
			return;
		
		_gridView = value;
	}
	
    //---------------------------------------------------------------
    //
    //  Overridden methods
    //
    //---------------------------------------------------------------
    
    /**
     *  @private
     */
    override public function set target(value:GroupBase):void
    {
        super.target = value;
        
        const group:Group = value as Group;
		if (!group)
			return;
		
		rendererLayer = new Group();
		rendererLayer.layout = new LayoutBase();
		group.addElement(rendererLayer);
		
		overlayLayer = new Group();
		overlayLayer.layout = new LayoutBase();
		group.addElement(overlayLayer);
    }
    
    /**
     *  @private
     */
    override public function get useVirtualLayout():Boolean
    {
        return true;
    }
    
    /**
     *  @private
     */
    override public function set useVirtualLayout(value:Boolean):void
    {
    }
    
    /**
     *  @private
     *  Clear everything.
     */
    override public function clearVirtualLayoutCache():void
    {		
		freeRenderers(visibleHeaderRenderers);
        visibleHeaderRenderers.length = 0;
		
		freeVisualElements(visibleHeaderSeparators);
        visibleHeaderSeparators.length = 0;
		
        rendererHeights.length = 0;
        visibleRenderersBounds.setEmpty();
        elementToFactoryMap = new Dictionary();
        freeElementMap = new Dictionary();

		if (gridColumnHeaderGroup)
			gridColumnHeaderGroup.visibleSortIndicatorIndices = null;
    }     
    
    /**
     *  @private
     */
    override protected function scrollPositionChanged():void
    {
		const target:GroupBase = this.target;
        if (!target)
            return;
        
        super.scrollPositionChanged();  // sets target's scrollRect
        
        // Only invalidate if we're clipping and scrollR extends outside visibleRenderersBounds
        const scrollR:Rectangle = target.scrollRect;
		if (scrollR && !visibleRenderersBounds.containsRect(scrollR))
            target.invalidateDisplayList();
    }    
    
    /**
     *  @private
     */
    override public function measure():void
    {
		const target:GroupBase = this.target;
		if (!target)
			return;
		
		updateRendererHeights();
		
		const measuredWidth:Number = Math.max(0, target.minWidth);
		const measuredHeight:Number = Math.max(maxRendererHeight, target.minHeight);
		
        target.measuredWidth = Math.ceil(measuredWidth);
        target.measuredHeight = Math.ceil(measuredHeight);
    }

    /**
     *  @private
     */
    override public function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
    {
		const target:GroupBase = this.target;
        const gridColumnHeaderGroup:GridColumnHeaderGroup = this.gridColumnHeaderGroup;
        const gridView:GridView = this.gridView;
        
        if (!target || !gridColumnHeaderGroup || !gridView)
            return;

		// TBD explain about Grid relative column indices...
		
		const visibleColumnIndices:Vector.<int> = gridView.gridViewLayout.getVisibleColumnIndices();  
		const visibleColumnCount:int = visibleColumnIndices.length;
		const firstVisibleColumnIndex:int = (visibleColumnCount > 0) ? visibleColumnIndices[0] : -1;
		const lastVisibleColumnIndex:int = (visibleColumnCount > 0) ? visibleColumnIndices[visibleColumnCount - 1] : -1;
		
        const oldRenderers:Array = [];
        const rendererLayer:Group = this.rendererLayer;
        const overlayLayer:Group = this.overlayLayer;
        const columnSeparatorFactory:IFactory = gridColumnHeaderGroup.columnSeparator;
        
        var renderer:IGridItemRenderer;
        var separator:IVisualElement;
        var column:GridColumn;
        var columnIndex:int = -1;
        
        // Add all of the renderers whose column is still visible to oldRenderers and free the rest
        
        for each (renderer in visibleHeaderRenderers)
        {
            column = renderer.column;
            columnIndex = (column) ? column.columnIndex : -1; 
            
            if ((visibleColumnIndices.indexOf(columnIndex) != -1) && (oldRenderers[columnIndex] == null))
                oldRenderers[columnIndex] = renderer;
            else
                freeRenderer(renderer);
        }
        visibleHeaderRenderers.length = 0;
        
        // Add all of the separators to the free-list, since laying them out is cheap.
        
		freeVisualElements(visibleHeaderSeparators);
		visibleHeaderSeparators.length = 0;
        
        // Layout the header renderers and update the CHB's content size
        // The loop below is written in terms of Grid - not GridView - column indices,
        // and terminates when we reach GridColumnCount.
        
        const gridColumns:IList = grid.columns;  // TBD what if grid.columns is null?
        const gridViewLayout:GridViewLayout = gridView.layout as GridViewLayout;
        const gridColumnCount:int = gridViewLayout.viewColumnIndex + gridViewLayout.columnsView.length; 
        
		const rendererY:Number = 0;
		const rendererHeight:Number = unscaledHeight;
        const maxRendererX:Number = target.horizontalScrollPosition + unscaledWidth;
        
        var visibleLeft:Number = 0;
        var visibleRight:Number = 0;
        
        // This isn't quite as simple as: 
        //     for each (var columnIndex:int in visibleColumnIndices)
        // since the GridColumnHeaderGroup may be wider than the grid because it
        // spans the vertical scrollbar.  If it does, we may need to display 
        // additional column headers (usually one).  
        
        for (var index:int = 0; /* termination conditions below */; index++)
        {
            if (index < visibleColumnIndices.length)
                columnIndex = visibleColumnIndices[index];
            else
                columnIndex = grid.getNextVisibleColumnIndex(columnIndex);
           
            if (columnIndex < 0 || columnIndex >= gridColumnCount)
                break;

            column = gridColumns.getItemAt(columnIndex) as GridColumn;

            // reuse or create a new renderer
            
            renderer = oldRenderers[columnIndex];
            delete oldRenderers[columnIndex];
            if (!renderer)
            {
                var factory:IFactory = column.headerRenderer;
                if (!factory)
                    factory = gridColumnHeaderGroup.headerRenderer;
                renderer = allocateVisualElement(factory) as IGridItemRenderer;
            }
            visibleHeaderRenderers.push(renderer);
            
            // initialize the renderer
            
            initializeItemRenderer(renderer, columnIndex, column, true);
            if (renderer.parent != rendererLayer)
                rendererLayer.addElement(renderer);
            
            // layout the renderer
            
            var isLastColumn:Boolean = columnIndex == lastVisibleColumnIndex;
            var headerViewColumnIndex:int = columnIndex - gridViewLayout.viewColumnIndex;
			var rendererX:Number = gridViewLayout.gridDimensionsView.getCellX(0, headerViewColumnIndex);
            var rendererWidth:Number = grid.getColumnWidth(columnIndex);
            
			if (isLastColumn)
                rendererWidth = horizontalScrollPosition + unscaledWidth - rendererX - 1; // TODO: this is a temporary hack
			
            renderer.setLayoutBoundsSize(rendererWidth, rendererHeight);
            renderer.setLayoutBoundsPosition(rendererX, rendererY);
            
            if (index == 0)
                visibleLeft = rendererX;
            visibleRight = rendererX + rendererWidth;
            
            renderer.prepare(!createdVisualElement);
            
            if (isLastColumn || ((rendererX + rendererWidth) >= maxRendererX))
                break;
            
            // allocate and layout a column separator
            
            if (columnSeparatorFactory && !isLastColumn)
            {
                separator = allocateVisualElement(columnSeparatorFactory);
                visibleHeaderSeparators.push(separator);
                separator.visible = true;
                if (separator.parent != overlayLayer)
                    overlayLayer.addElement(separator);
                
                var separatorWidth:Number = separator.getPreferredBoundsWidth();
                var separatorX:Number = rendererX + rendererWidth;
                separator.setLayoutBoundsSize(separatorWidth, rendererHeight);
                separator.setLayoutBoundsPosition(separatorX, rendererY);
            }
        }

        target.setContentSize(grid.contentWidth, rendererHeight);

		visibleRenderersBounds.left = visibleLeft;
		visibleRenderersBounds.right = visibleRight = 0;
		visibleRenderersBounds.top = rendererY;
        visibleRenderersBounds.height = rendererHeight;
		
        // We may have created new renderers or changed their visibility.  Force
        // validation to avoid a display list flash.

        target.validateNow();
        
        // Update the renderer heights cache.
        // Invalidates the target's size if the maxRendererHeight has changed.
        
        updateRendererHeights(true);
    }
    
    //---------------------------------------------------------------
    //
    //  Public methods
    //
    //--------------------------------------------------------------- 
    
    /**
     *  Returns the column index corresponding to the specified coordinates,
     *  or -1 if the coordinates are out of bounds. The coordinates are 
     *  resolved with respect to the column header view layout target.
     * 
     *  <p>If all of the columns or rows for the grid have not yet been scrolled
     *  into view, the returned index may only be an approximation, 
     *  based on all of the columns' <code>typicalItem</code>s.</p>
     *  
     *  @param x The pixel's x coordinate relative to the target column header view
     *  @param y The pixel's y coordinate relative to the target column header view
     *  @return the index of the column or -1 if the coordinates are out of bounds. 
     * 
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.0
     *  @productversion Flex 4.5
     */
    public function getHeaderIndexAt(x:Number, y:Number):int
    {
        return gridView.gridViewLayout.gridDimensionsView.getColumnIndexAt(x, y);
        
        // TODO: restore the special case handling below
        /*
        const gridColumnHeaderGroup:GridColumnHeaderGroup = this.gridColumnHeaderGroup;
        const grid:Grid = this.grid;
        const columnsView:IList = this.columnsView;
        
        if (!gridColumnHeaderGroup || !grid || !columnsView)
            return -1; 
        
        const paddingLeft:Number = gridColumnHeaderGroup.getStyle("paddingLeft");
        const paddedX:Number = x + paddingLeft;
        var columnIndex:int = grid.getColumnIndexAt(paddedX, 0);
        
        // Special case for the stretched renderer above the vertical scrollbar
        // TODO (klin): Rethink this case if we change how the last header looks.
        if (columnIndex < 0)
        {
            const contentWidth:Number = gridColumnHeaderGroup.contentWidth;
            const totalWidth:Number = horizontalScrollPosition + gridColumnHeaderGroup.width - gridColumnHeaderGroup.getStyle("paddingRight");
            if (paddedX >= contentWidth && paddedX < totalWidth)
                columnIndex = grid.getPreviousVisibleColumnIndex(columnsView.length)
        }
        
        return columnIndex;
        */
    }
    
    /**
     *  Returns the column separator index corresponding to the specified 
     *  coordinates, or -1 if the coordinates don't overlap a separator. The 
     *  coordinates are resolved with respect to the GridColumnHeaderGroup layout target.
     * 
     *  <p>A separator is considered to "overlap" the specified location if the
     *  x coordinate is within <code>separatorMouseWidth</code> of separator's
     *  horizontal midpoint.</p>
     *  
     *  <p>The separator index is the same as the index of the column on the left
     *  (assuming that this component's layoutDirection is "rtl").  That means 
     *  that all column headers are flanked by two separators, except for the first
     *  visible column, which just has a separator on the right, and the last visible
     *  column, which just has a separator on the left.</p>
     * 
     *  <p>If all of the columns or rows for the grid have not yet been scrolled
     *  into view, the returned index may only be an approximation, 
     *  based on all of the columns' <code>typicalItem</code>s.</p>
     *  
     *  @param x The pixel's x coordinate relative to the columnHeaderGroup
     *  @param y The pixel's y coordinate relative to the columnHeaderGroup
     *  @return the index of the column or -1 if the coordinates don't overlap a separator.
     * 
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.0
     *  @productversion Flex 4.5
     */
    public function getSeparatorIndexAt(x:Number, y:Number):int
    {
        const gdv:GridDimensionsView = gridView.gridViewLayout.gridDimensionsView;
        const columnIndex:int = gdv.getColumnIndexAt(x, y); 
        if (columnIndex == -1)
            return -1;        
        
        const isFirstColumn:Boolean = columnIndex == gridView.getNextVisibleColumnIndex(-1);
        const isLastColumn:Boolean = false; //columnIndex == gridView.getPreviousVisibleColumnIndex(gridView.viewColumnCount);
        
        const columnLeft:Number = gdv.getCellX(0, columnIndex);
        const columnRight:Number = columnLeft + gdv.getColumnWidth(columnIndex);
        const smw:Number = gridColumnHeaderGroup.getStyle("separatorAffordance");
        
        if (!isFirstColumn && (x > (columnLeft - smw)) && (x < (columnLeft + smw)))
            return grid.getPreviousVisibleColumnIndex(columnIndex);
        
        if (!isLastColumn && (x > (columnRight - smw)) && (x < columnRight + smw))
            return columnIndex;
        
        return -1;
    }
    
    /**
     *  Returns the current pixel bounds of the specified header (renderer), or null if 
     *  no such column exists.  Header bounds are reported in GridColumnHeaderGroup coordinates.
     * 
     *  <p>If all of the visible columns preceeding the specified column have not 
     *  yet been scrolled into view, the returned bounds may only be an approximation, 
     *  based on all of the Grid's <code>typicalItem</code>s.</p>
     * 
     *  @param columnIndex The 0-based index of the column. 
     *  @return A <code>Rectangle</code> that represents the column header's pixel bounds, or null.
     * 
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.0
     *  @productversion Flex 4.5
     */ 
    public function getHeaderBounds(columnIndex:int):Rectangle
    {
        const gridColumnHeaderGroup:GridColumnHeaderGroup = this.gridColumnHeaderGroup;
        const grid:Grid = this.grid;
        
        if (!gridColumnHeaderGroup || !grid)
            return null;
        
        const columns:IList = columnsView;
        const columnsLength:int = (columns) ? columns.length : 0;
        
        if (columnIndex >= columnsLength)
            return null;
        
        const column:GridColumn = columns.getItemAt(columnIndex) as GridColumn;
        if (!column.visible)
            return null;
        
        const paddingLeft:Number = gridColumnHeaderGroup.getStyle("paddingLeft");
        const paddingRight:Number = gridColumnHeaderGroup.getStyle("paddingRight");
        const paddingTop:Number = gridColumnHeaderGroup.getStyle("paddingTop");
        const paddingBottom:Number = gridColumnHeaderGroup.getStyle("paddingBottom");
        
        var isLastColumn:Boolean = columnIndex == grid.getPreviousVisibleColumnIndex(columnsLength);
        var rendererX:Number = grid.getCellX(0, columnIndex) + paddingLeft;
        const rendererY:Number = paddingTop;
        var rendererWidth:Number = grid.getColumnWidth(columnIndex); 
        const rendererHeight:Number = gridColumnHeaderGroup.height - paddingTop - paddingBottom;        
        
        if (isLastColumn)
            rendererWidth = horizontalScrollPosition + gridColumnHeaderGroup.width - rendererX - paddingRight;
        
        return new Rectangle(rendererX, rendererY, rendererWidth, rendererHeight);
    }

    /**
     *  If the requested header renderer is visible, returns a reference to 
     *  the header renderer currently displayed for the specified column. 
     *  Note that once the returned header renderer is no longer visible it 
     *  may be recycled and its properties reset.  
     * 
     *  <p>If the requested header renderer is not visible then, 
     *  each time this method is called, a new header renderer is created.  The
     *  new item renderer is not visible</p>
     * 
     *  <p>The width of the returned renderer is the same as for item renderers
     *  returned by DataGrid/getItemRendererAt().</p>
     *  
     *  @param columnIndex The 0-based column index of the header renderer's column
     *  @return The item renderer or null if the column index is invalid.
     * 
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.0
     *  @productversion Flex 4.5
     */
    public function getHeaderRendererAt(columnIndex:int):IGridItemRenderer
    {
        const gridColumnHeaderGroup:GridColumnHeaderGroup = this.gridColumnHeaderGroup;
        const grid:Grid = this.grid;
        
        if (!gridColumnHeaderGroup || !grid || (columnIndex < 0))
            return null;
        
        // If columnIndex refers to a visible header renderer, return it
        
        const rendererLayer:Group = rendererLayer;
        const visibleColumnIndices:Vector.<int> = grid.getVisibleColumnIndices();
        const eltIndex:int = visibleColumnIndices.indexOf(columnIndex);
        if (eltIndex != -1)
        {
            const rendererLayerNumElements:int = rendererLayer.numElements;
            for (var index:int = 0; index < rendererLayerNumElements; index++)
            {
                var elt:IGridItemRenderer = rendererLayer.getElementAt(index) as IGridItemRenderer;
                if (elt && elt.visible && elt.column && (elt.column.columnIndex == columnIndex))
                    return elt;
            }
            return null;
        }
            
        // create a new renderer

        const columns:IList = columnsView;
        if (!columns || (columns.length <= columnIndex))
            return null;
        const column:GridColumn = columns.getItemAt(columnIndex) as GridColumn;
        if (!column.visible)
            return null;
        
        var factory:IFactory = column.headerRenderer;
        if (!factory)
            factory = gridColumnHeaderGroup.headerRenderer;
        const renderer:IGridItemRenderer = allocateVisualElement(factory) as IGridItemRenderer;
        
        rendererLayer.addElement(renderer);

        // initialize the renderer
        
        initializeItemRenderer(renderer, columnIndex, column, renderer.visible);
        
        // layout the renderer

        const paddingLeft:Number = gridColumnHeaderGroup.getStyle("paddingLeft");
        const paddingRight:Number = gridColumnHeaderGroup.getStyle("paddingRight");
        const paddingTop:Number = gridColumnHeaderGroup.getStyle("paddingTop");
        const paddingBottom:Number = gridColumnHeaderGroup.getStyle("paddingBottom");
        
        const isLastColumn:Boolean = columnIndex == grid.getPreviousVisibleColumnIndex(columns.length);
        const rendererX:Number = grid.getCellX(0, columnIndex) + paddingLeft;
        const rendererY:Number = paddingTop;
        const rendererHeight:Number = gridColumnHeaderGroup.height - paddingTop - paddingBottom;
        var rendererWidth:Number = grid.getColumnWidth(columnIndex); 
        
        if (isLastColumn)
            rendererWidth = horizontalScrollPosition + gridColumnHeaderGroup.width - rendererX - paddingRight;
        
        renderer.setLayoutBoundsSize(rendererWidth, rendererHeight);
        renderer.setLayoutBoundsPosition(rendererX, rendererY);
        
        rendererLayer.removeElement(renderer);
        renderer.visible = false;
        
        return renderer;
    }
    
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;

    //---------------------------------------------------------------
    //
    //  Internal methods, properties
    //
    //---------------------------------------------------------------    
    
    /**
     *  @private
     */
    private function initializeItemRenderer(renderer:IGridItemRenderer,
                                            columnIndex:int,
                                            column:GridColumn,
                                            visible:Boolean=true):void
    {
        renderer.visible = visible;
        renderer.column = column;
        renderer.label = column.headerText;
        
        const columnHeaderGroup:GridColumnHeaderGroup = this.gridColumnHeaderGroup;

        const dataGrid:DataGrid = columnHeaderGroup.dataGrid;
        if (dataGrid)
            renderer.owner = dataGrid;
        
        renderer.hovered = columnIndex == columnHeaderGroup.hoverColumnIndex;
        renderer.selected = columnIndex == columnHeaderGroup.selectedColumnIndex;
        renderer.down = columnIndex == columnHeaderGroup.downColumnIndex;
    }
    
    /**
     *  @private
     *  Let the allocateGridElement() caller know if the returned element was 
     *  created or recycled.
     */
    private var createdVisualElement:Boolean = false;
    
    /**
     *  @private
     */
    private function createVisualElement(factory:IFactory):IVisualElement
    {
        createdVisualElement = true;
        const newElement:IVisualElement = factory.newInstance() as IVisualElement;
        elementToFactoryMap[newElement] = factory;
        return newElement;
    }
    
    /**
     *  @private
     *  If the freeElementMap "free list" contains an instance of this factory, then 
     *  remove if from the free list and return it, otherwise create a new instance
     *  using createVisualElement().
     */
    private function allocateVisualElement(factory:IFactory):IVisualElement
    {
        createdVisualElement = false;
        const freeElements:Vector.<IVisualElement> = freeElementMap[factory] as Vector.<IVisualElement>;
        if (freeElements)
        {
            const freeElement:IVisualElement = freeElements.pop();
            if (freeElements.length == 0)
                delete freeElementMap[factory];
            if (freeElement)
                return freeElement;
        }
        
        return createVisualElement(factory);
    }
    
    /**
     *  @private
     *  Move the specified element to the free list after hiding it. Note that we 
     *  do not actually remove the element from its parent.
     */
    private function freeVisualElement(element:IVisualElement):void
    {
        const factory:IFactory = elementToFactoryMap[element];

        var freeElements:Vector.<IVisualElement> = freeElementMap[factory];
        if (!freeElements)
        {
            freeElements = new Vector.<IVisualElement>();
            freeElementMap[factory] = freeElements;
        }
        freeElements.push(element);
        
        element.visible = false;
    }
	
	private function freeVisualElements(elements:Vector.<IVisualElement>):void
	{
		for each (var elt:IVisualElement in elements)
		    freeVisualElement(elt);
			
		elements.length = 0;
	}
	
	private function freeRenderer(renderer:IGridItemRenderer):void
	{
		freeVisualElement(renderer as IVisualElement);
		renderer.discard(true);	
	}
	
	private function freeRenderers(renderers:Vector.<IGridItemRenderer>):void
	{
		for each (var renderer:IGridItemRenderer in renderers)
			freeRenderer(renderer);
			
		renderers.length = 0;
	}		
    
    /**
     *  @private
     *  Updates the renderer heights cache and the current max renderer height.
     *  Invalidates the target's size if the max renderer height has changed.
     * 
     *  <p>If the max live renderer height is the same as the max cached height, then
     *  just update the cache.
     *  If the max live renderer height is greater than the max cached height, then
     *  update the cache, cache the new height, and invalidate the target's size if
     *  necessary.
     *  If the max live renderer height is less than the max cached height, then
     *  update the cache, check to see if the cached max height has lowered, and
     *  invalidate the target's size if necessary.
     */
    private function updateRendererHeights(inUpdateDisplayList:Boolean = false):void
    {
        const columns:IList = columnsView;
        rendererHeights.length = (columns) ? columns.length : 0;
        
        var newHeight:Number = 0;
        
        // update cached renderer heights with live renderer heights.
        for each (var renderer:IGridItemRenderer in visibleHeaderRenderers)
        {
            var preferredHeight:Number = renderer.getPreferredBoundsHeight();
            rendererHeights[renderer.column.columnIndex] = preferredHeight;
            if (preferredHeight > newHeight)
                newHeight = preferredHeight;
        }
        
        // Do nothing if the heights are the same.
        if (newHeight == maxRendererHeight)
            return;
        
        if (newHeight < maxRendererHeight)
        {
            // If the live renderers' max height is less than the current
            // max height, check if this also lowers the maxRendererHeight.
			for each (var rendererHeight:Number in rendererHeights)
			{
                if (!isNaN(rendererHeight) && rendererHeight > newHeight)
                    newHeight = rendererHeight;
            }
        }
        
        maxRendererHeight = newHeight;
        
        if (inUpdateDisplayList) // TBD: should be target.invalidateSize()?
            gridColumnHeaderGroup.invalidateSize();
    }
    

    /**
     *  @private
     *  Handles changes to the columns IList that might affect the visible sort
     *  indicators.
     */
    private function columns_collectionChangeHandler(event:CollectionEvent):void
    {
        // TODO (klin): The cache could be adjusted here too.
        switch (event.kind)
        {
            case CollectionEventKind.ADD: 
            {
                columns_collectionChangeAdd(event);
                break;
            }
            
            case CollectionEventKind.REMOVE:
            {
                columns_collectionChangeRemove(event);
                break;
            }
                
            case CollectionEventKind.MOVE:
            {
                columns_collectionChangeMove(event);
                break;
            }
                
            case CollectionEventKind.REPLACE:
            case CollectionEventKind.UPDATE:
            {
                // Do nothing.
                break;
            }
                
            case CollectionEventKind.REFRESH:
            case CollectionEventKind.RESET:
            {
                clearVirtualLayoutCache();
                break;
            }                
        }
    }
    
    /**
     *  @private
     *  Adjusts the visibleSortIndicatorIndices to the correct columns
     *  after columns are added.
     */
    private function columns_collectionChangeAdd(event:CollectionEvent):void
    {   
        const itemsLength:int = event.items.length;
        if (itemsLength <= 0)
            return;
        
        const chg:GridColumnHeaderGroup = gridColumnHeaderGroup;
        const indices:Vector.<int> = chg.visibleSortIndicatorIndices;
        const indicesLength:int = indices.length;
        const startIndex:int = event.location;
        
        for (var i:int = 0; i < indicesLength; i++)
        {
            if (indices[i] >= startIndex)
                indices[i] += itemsLength;
        }
        chg.visibleSortIndicatorIndices = indices;
    }
    
    /**
     *  @private
     *  Adjusts the visibleSortIndicatorIndices to the correct columns
     *  after columns are removed.
	 * 
	 *  TBD: Remove the rendererHeights cache entries for the corresponding columns.
     */
    private function columns_collectionChangeRemove(event:CollectionEvent):void
    {
        const itemsLength:int = event.items.length;
        if (itemsLength <= 0)
            return;
        
        const chg:GridColumnHeaderGroup = gridColumnHeaderGroup;
        const indices:Vector.<int> = chg.visibleSortIndicatorIndices;
        const indicesLength:int = indices.length;
        const startIndex:int = event.location;
        const lastIndex:int = startIndex + itemsLength;
        const newIndices:Vector.<int> = new Vector.<int>();
        var index:int;
        
        for each (index in indices)
        {
            if (index < startIndex)
                newIndices.push(index);
            else if (index >= lastIndex)
                newIndices.push(index - lastIndex);
        }
        chg.visibleSortIndicatorIndices = newIndices;
    }
    
    /**
     *  @private
     *  Adjusts the visibleSortIndicatorIndices to the correct columns
     *  after columns are moved.
     */
    private function columns_collectionChangeMove(event:CollectionEvent):void
    {
        const itemsLength:int = event.items.length;
        if (itemsLength <= 0)
            return;
        
        const gridColumnHeaderGroup:GridColumnHeaderGroup = this.gridColumnHeaderGroup;
        const indices:Vector.<int> = gridColumnHeaderGroup.visibleSortIndicatorIndices;
        const indicesLength:int = indices.length;
        const oldStart:int = event.oldLocation;
        const oldEnd:int = event.oldLocation + itemsLength;
        const newStart:int = event.location;
        const newEnd:int = event.location + itemsLength;
        var index:int;
        
        for (var i:int = 0; i < indicesLength; i++)
        {
            index = indices[i];
            
            if (index >= oldStart && index < oldEnd)
            {
                // Moved items move up to new position
                indices[i] = newStart + (index - oldStart);
                continue;
            }
            
            // Two cases:
            //      1) New position is greater than old position, so we
            //         decrement their position by the number of moved items.
            //      2) New position is less than old position, so we
            //         increment their position by the number of moved items.
            if (newStart > oldStart)
            {
                if (index >= oldEnd && index < newEnd)
                    indices[i] -= itemsLength;
            }
            else if (newStart < oldStart)
            {
                if (index >= newStart && index < oldStart)
                    indices[i] += itemsLength;
            }
        }
		
        gridColumnHeaderGroup.visibleSortIndicatorIndices = indices;
    }
}
}

