////////////////////////////////////////////////////////////////////////////////
//
//  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 mx.containers
{

import flash.display.DisplayObject;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.geom.Point;

import mx.containers.dividedBoxClasses.BoxDivider;
import mx.core.EdgeMetrics;
import mx.core.IFlexDisplayObject;
import mx.core.IFlexModuleFactory;
import mx.core.IInvalidating;
import mx.core.IUIComponent;
import mx.core.UIComponent;
import mx.core.mx_internal;
import mx.events.ChildExistenceChangedEvent;
import mx.events.DividerEvent;
import mx.managers.CursorManager;
import mx.managers.CursorManagerPriority;
import mx.styles.IStyleManager2;
import mx.styles.StyleManager;

use namespace mx_internal;

//--------------------------------------
//  Events
//--------------------------------------

/**
 *  Dispatched multiple times as the user drags any divider.
 *
 *  The <code>dividerDrag</code> event is dispatched
 *  after the <code>dividerPress</code> event
 *  and before the <code>dividerRelease</code> event.
 *
 *  @eventType mx.events.DividerEvent.DIVIDER_DRAG
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="dividerDrag", type="mx.events.DividerEvent")]

/**
 *  Dispatched when the user presses any divider in this container.
 *
 *  The <code>dividerPress</code> event is dispatched
 *  before any <code>dividerDrag</code> events are dispatched.
 *
 *  @eventType mx.events.DividerEvent.DIVIDER_PRESS
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="dividerPress", type="mx.events.DividerEvent")]

/**
 *  Dispatched when the user releases a divider.
 *
 *  The <code>dividerRelease</code> event is dispatched
 *  after the <code>dividerDrag</code> events,
 *  but before the container's children are resized.
 *  The divider's x and y properties are not updated until
 *  after this event is triggered. As a result, a call to 
 *  <code>hDividerBox.getDividerAt(0).x</code> will return
 *  the value of the original x position of the first divider. If you want the
 *  position of the divider after the move, you can access it when the
 *  DividerBox's updateComplete event has been triggered.
 *
 *  @eventType mx.events.DividerEvent.DIVIDER_RELEASE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="dividerRelease", type="mx.events.DividerEvent")]

//--------------------------------------
//  Styles
//--------------------------------------

/**
 *  Thickness in pixels of the area where the user can click to drag a 
 *  divider.
 *  This area is centered in the gaps between the container's children,
 *  which are determined by the <code>horizontalGap</code> or
 *  <code>verticalGap</code> style property.
 *  The affordance cannot be set to a value larger than the gap size.
 *  A resize cursor appears when the mouse is over this area.
 *
 *  @default 6
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="dividerAffordance", type="Number", format="Length", inherit="no")]

/**
 *  The alpha value that determines the transparency of the dividers.
 *  A value of <code>0.0</code> means completely transparent
 *  and a value of <code>1.0</code> means completely opaque.
 *  
 *  @default 0.75
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="dividerAlpha", type="Number", inherit="no")]

/**
 *  Color of the dividers when the user presses or drags the dividers
 *  if the <code>liveDragging</code> property is set to <code>false</code>.
 *  If the <code>liveDragging</code> property is set to <code>true</code>,
 *  only the divider's knob is shown.
 *
 *  @default 0x6F7777
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="dividerColor", type="uint", format="Color", inherit="yes")]

/**
 *  The divider skin.
 *
 *  The default value is the "mx.skin.BoxDividerSkin" symbol in the Assets.swf file.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="dividerSkin", type="Class", inherit="no")]

/**
 *  Thickness in pixels of the dividers when the user presses or drags the 
 *  dividers, if the <code>liveDragging</code> property is set to <code>false</code>.
 *  (If the <code>liveDragging</code> property is set to <code>true</code>,
 *  only the divider's knob is shown.)
 *  The visible thickness cannot be set to a value larger than the affordance.
 *  
 *  @default 3
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="dividerThickness", type="Number", format="Length", inherit="no")]

/**
 *  The cursor skin for a horizontal DividedBox.
 *
 *  The default value is the "mx.skins.cursor.HBoxDivider" symbol in the Assets.swf file.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="horizontalDividerCursor", type="Class", inherit="no")]

/**
 *  The cursor skin for a vertical DividedBox.
 *
 *  The default value is the "mx.skins.cursor.VBoxDivider" symbol in the Assets.swf file.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="verticalDividerCursor", type="Class", inherit="no")]

//--------------------------------------
//  Excluded APIs
//--------------------------------------

[Exclude(name="focusIn", kind="event")]
[Exclude(name="focusOut", kind="event")]

[Exclude(name="focusBlendMode", kind="style")]
[Exclude(name="focusSkin", kind="style")]
[Exclude(name="focusThickness", kind="style")]

[Exclude(name="focusInEffect", kind="effect")]
[Exclude(name="focusOutEffect", kind="effect")]

//--------------------------------------
//  Other metadata
//--------------------------------------

[IconFile("DividedBox.png")]

/**
 *  A DividedBox container measures and lays out its children
 *  horizontally or vertically in exactly the same way as a
 *  Box container, but it inserts
 *  draggable dividers in the gaps between the children.
 *  Users can drag any divider to resize the children on each side.
 *  
 *  <p>The DividedBox class is the base class for the more commonly used
 *  HDividedBox and VDividedBox classes.</p>
 *
 *  <p>The <code>direction</code> property of a DividedBox container, inherited 
 *  from Box container, determines whether it has horizontal
 *  or vertical layout.</p>
 *  
 *  <p>A DividedBox, HDividedBox, or VDividedBox container has the following default sizing characteristics:</p>
 *     <table class="innertable">
 *        <tr>
 *           <th>Characteristic</th>
 *           <th>Description</th>
 *        </tr>
 *        <tr>
 *           <td>Default size</td>
 *           <td><strong>Vertical DividedBox</strong> Height is large enough to hold all of its children at the default or explicit 
 *               heights of the children, plus any vertical gap between the children, plus the top and bottom padding of the 
 *               container. The width is the default or explicit width of the widest child, plus the left and right padding of 
 *               the container. 
 *               <br><strong>Horizontal DividedBox</strong> Width is large enough to hold all of its children at the 
 *               default or explicit widths of the children, plus any horizontal gap between the children, plus the left and 
 *               right padding of the container. Height is the default or explicit height of the tallest child 
 *               plus the top and bottom padding of the container.</br></td>
 *        </tr>
 *        <tr>
 *           <td>Default padding</td>
 *           <td>0 pixels for the top, bottom, left, and right values.</td>
 *        </tr>
 *        <tr>
 *           <td>Default gap</td>
 *           <td>10 pixels for the horizontal and vertical gaps.</td>
 *        </tr>
 *     </table>
 *
 *  @mxml
 *  
 *  <p>The <code>&lt;mx:DividedBox&gt;</code> tag inherits all of the tag 
 *  attributes of its superclass, and adds the following tag attributes:</p>
 *  
 *  <pre>
 *  &lt;mx:DividedBox
 *    <strong>Properties</strong>
 *    liveDragging="false|true"
 *    resizeToContent="false|true"
 *  
 *    <strong>Styles</strong>
 *    dividerAffordance="6"
 *    dividerAlpha="0.75"
 *    dividerColor="0x6F7777"
 *    dividerSkin="<i>'mx.skins.BoxDividerSkin' symbol in Assets.swf</i>"
 *    dividerThickness="3"
 *    horizontalDividerCursor="<i>'mx.skins.cursor.HBoxDivider' symbol in Assets.swf</i>"
 *    verticalDividerCursor="<i>'mx.skins.cursor.VBoxDivider' symbol in Assets.swf</i>"
 * 
 *    <strong>Events</strong>
 *    dividerPress="<i>No default</i>"
 *    dividerDrag="<i>No default</i>"
 *    dividerRelease="<i>No default</i>"
 *    &gt;
 *      ...
 *      <i>child tags</i>
 *      ...
 *  &lt;/mx:DividedBox&gt;
 *  </pre>
 *  
 *  @see mx.containers.HDividedBox
 *  @see mx.containers.VDividedBox
 *
 *  @includeExample examples/DividedBoxExample.mxml
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class DividedBox extends Box
{
	include "../core/Version.as";

	//--------------------------------------------------------------------------
	//
	//  Class constants
	//
	//--------------------------------------------------------------------------

	/**
	 *  @private
	 */
	private static const PROXY_DIVIDER_INDEX:int = 999;

	//--------------------------------------------------------------------------
	//
	//  Constructor
	//
	//--------------------------------------------------------------------------

	/**
	 *  Constructor.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function DividedBox()
	{
		super();

        addEventListener(ChildExistenceChangedEvent.CHILD_ADD, childAddHandler);
		addEventListener(ChildExistenceChangedEvent.CHILD_REMOVE, 
						 childRemoveHandler);

		// make divided box visible in automation by default because
		// users interact with the dividers
		showInAutomationHierarchy = true;
	}

	//--------------------------------------------------------------------------
	//
	//  Variables
	//
	//--------------------------------------------------------------------------

	/**
	 *  @private
	 *  Container for holding divider objects.
	 */
	private var dividerLayer:UIComponent = null;

	/**
	 *  @private
	 */
	mx_internal var activeDivider:BoxDivider;
	
	/**
	 *  @private
	 */
	private var activeDividerIndex:int = -1;
	
	/**
	 *  @private
	 */
	private var activeDividerStartPosition:Number;
	
	/**
	 *  @private
	 */
	private var dragStartPosition:Number;
	
	/**
	 *  @private
	 */
	private var dragDelta:Number;
	
	/**
	 *  @private
	 */
	private var oldChildSizes:Array /* of ChildSizeInfo */;
	
	/**
	 *  @private
	 */
	private var minDelta:Number;
	
	/**
	 *  @private
	 */
	private var maxDelta:Number;

	/**
	 *  @private
	 *  Only allow a single divider to move at a time.
	 */
	private var dontCoalesceDividers:Boolean;

	/**
	 *  @private
	 */
	private var cursorID:int = CursorManager.NO_CURSOR;

	/**
	 *  @private
	 *  We'll measure ourselves once and then store the results here
	 *  for the lifetime of the DividedBox.
	 */
	private var dbMinWidth:Number;
	private var dbMinHeight:Number;
	private var dbPreferredWidth:Number;
	private var dbPreferredHeight:Number;

	/**
	 *  @private
	 */
	private var layoutStyleChanged:Boolean = false;

    /**
     *  @private
     */
    private	var _resizeToContent:Boolean = false;

	/**
	 *  @private
	 *  Number of children with their includeInLayout set to true.  The rest of
	 *  the children don't count.
	 */
	private var numLayoutChildren:int = 0;

    //--------------------------------------------------------------------------
    //
    //  Overridden Properties
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    override public function set moduleFactory(moduleFactory:IFlexModuleFactory):void
    {
        super.moduleFactory = moduleFactory;
        
        styleManager.registerSizeInvalidatingStyle("dividerAffordance");
        styleManager.registerSizeInvalidatingStyle("dividerThickness");
    }
    
	//--------------------------------------------------------------------------
	//
	//  Properties
	//
	//--------------------------------------------------------------------------

	//----------------------------------
	//  direction
	//----------------------------------

	/**
	 *  @private
	 */
	override public function set direction(value:String):void
	{
		if (super.direction != value)
		{
			super.direction = value;

			// Need to invalidate all our dividers
			if (dividerLayer)
			{
				for (var i:int = 0; i < dividerLayer.numChildren; i++)
					getDividerAt(i).invalidateDisplayList();
			}
		}
	}

	//----------------------------------
	//  dividerClass
	//----------------------------------

	/**
	 *  The class for the divider between the children.
	 *
	 *  @default mx.containers.dividedBoxClasses.BoxDivider
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	protected var dividerClass:Class = BoxDivider;

	//----------------------------------
	//  liveDragging
	//----------------------------------

	[Inspectable(category="General")]

	/**
	 *  If <code>true</code>, the children adjacent to a divider
	 *  are continuously resized while the user drags it.
	 *  If <code>false</code>, they are not resized
	 *  until the user releases the divider.
	 *  @default false
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public var liveDragging:Boolean = false;

    //----------------------------------
    //	numDividers
    //----------------------------------

	/**
 	 *  The number of dividers. 
	 *  The count is always <code>numChildren</code> - 1.
	 *
	 *  @return The number of dividers.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function get numDividers():int
	{
		if (dividerLayer)
           	if (!liveDragging && activeDivider)
           		return dividerLayer.numChildren-1;
           	else
				return dividerLayer.numChildren;
		else 
			return 0;
	}

    //----------------------------------
    //	resizeToContent
    //----------------------------------

    /**
	 *  If <code>true</code>, the DividedBox automatically resizes to the size
	 *  of its children.
     *  @default false
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function	get	resizeToContent():Boolean
    {
        return _resizeToContent;
    }

    /**
     *  @private
     */
    public function	set	resizeToContent(value:Boolean):void
    {
        if (value != _resizeToContent)
        {
            _resizeToContent = value;
            if (value)
                invalidateSize();
        }
    }
	
	//--------------------------------------------------------------------------
	//
	//  Overridden methods
	//
	//--------------------------------------------------------------------------

	/**
	 *  @private
	 *  Override of the measure method of Box.
	 *
	 *  <p>This function is almost identical to the Box version except
	 *  that more extensive testing of the min, max
	 *  boundary conditions is performed. This is because the DividedBox allows
	 *  default values to be less than the min value of a control.</p>
	 */
	override protected function measure():void
	{
		super.measure();

		// We only measure ourselves once, since as we change the 
		// size of children, they in turn change the preferred sizes
		//
		// We need to copy the cached values into the measured fields
		// again to handle the case where scaleX or scaleY is not 1.0.
		// When the ViewStack is zoomed, code in UIComponent.measureSizes
		// scales the measuredWidth/Height values every time that
		// measureSizes is called. (Bug 100749)
		if (!isNaN(dbPreferredWidth) && !_resizeToContent && !layoutStyleChanged) 
		{
			measuredMinWidth = dbMinWidth;
			measuredMinHeight = dbMinHeight;
			measuredWidth = dbPreferredWidth;
			measuredHeight = dbPreferredHeight;
			return;
		}
	
		layoutStyleChanged = false;
	
		var isVertical:Boolean = this.isVertical();
		var minWidth:Number = 0;
		var minHeight:Number = 0;
		var preferredWidth:Number = 0;
		var preferredHeight:Number = 0;

		var n:int = numChildren;
		for (var i:int = 0; i < n; i++)
		{
			var child:IUIComponent = getLayoutChildAt(i);

			if (!child.includeInLayout)
				continue;

			var prefW:Number = child.getExplicitOrMeasuredWidth();
			var prefH:Number = child.getExplicitOrMeasuredHeight();
			
			var minW:Number = child.minWidth;
			var minH:Number = child.minHeight;
			
			var wFlex:Boolean = !isNaN(child.percentWidth);
			var hFlex:Boolean = !isNaN(child.percentHeight);
		
			// Make sure we take the lowest of the low, since pref < min.
			var smallestMinW:Number = Math.min(prefW, minW);
			var smallestMinH:Number = Math.min(prefH, minH);

			if (isVertical)
			{
				minWidth = Math.max(wFlex ? minW : prefW, minWidth);
				preferredWidth = Math.max(prefW, preferredWidth);
				minHeight += hFlex ? smallestMinH : prefH;
				preferredHeight += prefH;
			}
			else
			{
				minWidth += wFlex ? smallestMinW : prefW;
				preferredWidth += prefW;
				minHeight = Math.max(hFlex ? minH : prefH, minHeight);
				preferredHeight = Math.max(prefH, preferredHeight);
			}
		}

        var wPadding:Number = layoutObject.widthPadding(numLayoutChildren);
        var hPadding:Number = layoutObject.heightPadding(numLayoutChildren);

		measuredMinWidth = dbMinWidth = minWidth + wPadding;
		measuredMinHeight = dbMinHeight = minHeight + hPadding;
		measuredWidth = dbPreferredWidth = preferredWidth + wPadding;
		measuredHeight = dbPreferredHeight = preferredHeight + hPadding;
	}

	/**
	 *  @private
	 */
	override protected function updateDisplayList(unscaledWidth:Number,
												  unscaledHeight:Number):void
	{
 		var n:int;
 		var i:int;

		// This method gets called while dragging a divider,
		// but we don't want to do anything then.
		if (!liveDragging && activeDivider)
 		{
 			n = numChildren;
 			for (i = 0; i < n; i++)
 			{
 				var child:IUIComponent = getLayoutChildAt(i);

				if (!child.includeInLayout)
					continue;
 	
 				// Clear out measured min/max
 				// so super.layout() doesn't use them.
 				child.measuredMinWidth = 0; 
 				child.measuredMinHeight = 0;
 			}
   			return;
 		}

		// Before we allow layout, let's clear out any measured min 
		// values of our children so that they don't restrict us.
		// We only honour explicitly set mins/maxs.
		// We also try to remove any excess space, but tweaking 
		// the % values on the flexible components.
		preLayoutAdjustment();

		// Let Box lay out the children.
		super.updateDisplayList(unscaledWidth, unscaledHeight);
		
        postLayoutAdjustment();

		// Lay out the dividers.
        if (!dividerLayer)
           return;

			var vm:EdgeMetrics = viewMetrics;

			dividerLayer.x = vm.left;
			dividerLayer.y = vm.top;

        var prevChild:IUIComponent = null;
        var dividerIndex:int = 0;
        n = numChildren;
			for (i = 0; i < n; i++)
			{
            child = UIComponent(getChildAt(i));
            if (child.includeInLayout)
            {
                if (prevChild)
                {
                    layoutDivider(dividerIndex, unscaledWidth, unscaledHeight, prevChild, child);
                    dividerIndex++;
                }
                prevChild = child;
			}
		}
	}

	/**
	 *  @private
	 */
	override public function styleChanged(styleProp:String):void
	{
		super.styleChanged(styleProp);
		
		// Need to invalidate all our dividers
		if (dividerLayer)
		{
			var n:int = dividerLayer.numChildren;
			for (var i:int = 0; i < n; i++)
			{
				getDividerAt(i).styleChanged(styleProp);
			}
		}
		
		if (styleManager.isSizeInvalidatingStyle(styleProp))
		{
			layoutStyleChanged = true;
		}
	}
	
	/**
	 *  @private
	 */
	override protected function scrollChildren():void
	{
		super.scrollChildren();

		// Scroll divider layer.
		if (contentPane && dividerLayer)
			dividerLayer.scrollRect = contentPane.scrollRect;
	}

	//--------------------------------------------------------------------------
	//
	//  Methods
	//
	//--------------------------------------------------------------------------

	/**
	 *  Returns a reference to the specified BoxDivider object
	 *  in this DividedBox container or null if it doesn't exist.
	 *
	 *  @param i Zero-based index of a divider, counting from 
	 *  the left for a horizontal DividedBox, 
	 *  or from the top for a vertical DividedBox.
	 *
	 *  @return A BoxDivider object.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function getDividerAt(i:int):BoxDivider
	{
		if (dividerLayer) {
			// Check whether this is a valid divider index.
			if (i < 0 || i >= dividerLayer.numChildren)
				return null;
			else
				return BoxDivider(dividerLayer.getChildAt(i));
		}
		else {
			return null;
		}
	}

	/**
	 *  Move a specific divider a given number of pixels.
	 *
	 *  @param i Zero-based index of a divider, counting from 
	 *  the left for a horizontal DividedBox, 
	 *  or from the top for a vertical DividedBox.
	 *
	 *  @param amt The number of pixels to move the divider.
     *  A negative number can be specified in order to move
     *  a divider up or left. The divider movement is
     *  constrained in the same manner as if a user
 	 *  had moved it.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 9
	 *  @playerversion AIR 1.1
	 *  @productversion Flex 3
	 */
	public function moveDivider(i:int, amt:Number):void
	{
		// Check whether this is a valid divider index.
		if (i < 0 || i >= numDividers)
			return;

		// Make sure the user is not currently dragging.
		if (activeDividerIndex >= 0)
			return;

		// We have to first hit the children if we haven't
		// yet done so since the first movement .

		// Mimic a divider moving.
		activeDividerIndex = i;

		// Store away child sizes,
		// then determine the limits on our movement.
		cacheChildSizes();
		computeMinAndMaxDelta();
		dragDelta = limitDelta(amt);

		// Now update the children sizes accordingly.
		adjustChildSizes();

		invalidateSize();
		invalidateDisplayList();

		// Reset the divider tracking stuff.
		resetDividerTracking();
	}

	/**
	 *  @private
	 */
	private function createDivider(i:int):BoxDivider
	{
		// Create separate layer for holding divider objects.
		if (!dividerLayer)
		{
			dividerLayer = UIComponent(rawChildren.addChild(new UIComponent()));
		}

		var divider:BoxDivider = BoxDivider(new dividerClass());
		dividerLayer.addChild(divider);
		
		// if we are creating the active divider bring the divider layer 
		// to the top most so that users can see the divider line over 
		// the other children
		if (i == PROXY_DIVIDER_INDEX)
		{
			rawChildren.setChildIndex(dividerLayer, 
										  rawChildren.numChildren-1);
		}
		
		// Tell BoxDivider to use DividedBox's styles,
		// unless we are sliding the divider; in that case,
		// use the styles of the divider we are sliding.
		var basedOn:IFlexDisplayObject = (i == PROXY_DIVIDER_INDEX) ?
										 getDividerAt(activeDividerIndex) :
										 this;
		
		divider.styleName = basedOn;
		
		divider.owner = this;
		
		return divider;
	}

	/**
	 *  @private
	 */
	private function layoutDivider(i:int, 
								   unscaledWidth:Number, 
                                   unscaledHeight:Number,
                                   prevChild:IUIComponent,
                                   nextChild:IUIComponent):void
	{
		// The mouse-over thickness of the divider is normally determined
		// by the dividerAffordance style, and the visible thickness is 
		// normally determined by the dividerThickness style, assuming that
		// the relationship thickness <= affordance <= gap applies. But if
		// one of the other five orderings applies, here is a table of what
		// happens:
		//
		//  divider    divider    horizontalGap/  dividerWidth/  visible width/
		// Thickness  Affordance  verticalGap     dividerHeight  visible height
		//                                           
		//    4           6             8               6              4
		//    4           8             6               6              4
		//    6           4             8               6              6
		//    6           8             4               4              4
		//    8           4             6               6              6        
		//    8           6             4               4              4

		var divider:BoxDivider = BoxDivider(getDividerAt(i));

		var vm:EdgeMetrics = viewMetrics;

		var verticalGap:Number = getStyle("verticalGap");
		var horizontalGap:Number = getStyle("horizontalGap");

		var thickness:Number = divider.getStyle("dividerThickness");
		var affordance:Number = divider.getStyle("dividerAffordance");

		if (isVertical())
		{
			var dividerHeight:Number = affordance;
				// dividerHeight is the mouse-over height,
				// not necessarily the visible height.
			
			// The specified affordance should be greater than the thickness.
			// But if it isn't, use the thickness instead to determine the
			// divider height.
			if (dividerHeight < thickness)
				dividerHeight = thickness;

			// Don't let the divider overlap the children.
			if (dividerHeight > verticalGap)
				dividerHeight = verticalGap;
			
			divider.setActualSize(unscaledWidth - vm.left - vm.right, dividerHeight);

			divider.move(vm.left,
						 Math.round((prevChild.y + prevChild.height +
						  			nextChild.y - dividerHeight) / 2));
		}
		else
		{
			var dividerWidth:Number = affordance;
				// dividerWidth is the mouse-over width,
				// not necessarily the visible width.

			// The specified affordance should be greater than the thickness.
			// But if it isn't, use the thickness instead to determine the
			// divider width.
			if (dividerWidth < thickness)
				dividerWidth = thickness;

			// Don't let the divider overlap the children.
			if (dividerWidth > horizontalGap)
				dividerWidth = horizontalGap;

			divider.setActualSize(dividerWidth, unscaledHeight - vm.top - vm.bottom);

			divider.move(Math.round((prevChild.x + prevChild.width +
						  			nextChild.x - dividerWidth) / 2),
						 vm.top);
		}

		divider.invalidateDisplayList();
	}

	/**
	 *  @private
	 */
	mx_internal function changeCursor(divider:BoxDivider):void
	{
		if (cursorID == CursorManager.NO_CURSOR)
		{
			// If a cursor skin has been set for the specified BoxDivider,
			// use it. Otherwise, use the cursor skin for the DividedBox.
			var cursorClass:Class = isVertical() ?
									getStyle("verticalDividerCursor") as Class :
									getStyle("horizontalDividerCursor") as Class;

			cursorID = cursorManager.setCursor(cursorClass,
											   CursorManagerPriority.HIGH, 0, 0);
		}
	}

	/**
	 *  @private
	 */
	mx_internal function restoreCursor():void
	{
		if (cursorID != CursorManager.NO_CURSOR)
		{
			cursorManager.removeCursor(cursorID);
			cursorID = CursorManager.NO_CURSOR;
		}
	}

	/**
	 *  @private
	 */
	mx_internal function getDividerIndex(divider:BoxDivider):int
	{
		var n:int = numChildren;
		for (var i:int = 0; i < n - 1; i++)
		{
			if (getDividerAt(i) == divider)
				return i;
		}
		return -1;
	}

	/**
	 *  @private
	 */
	private function getMousePosition(event:MouseEvent):Number
	{
        var point:Point = new Point(event.stageX, event.stageY);
        point = globalToLocal(point);
		return isVertical() ? point.y : point.x;
	}

	/**
	 *  @private
	 */
	mx_internal function startDividerDrag(divider:BoxDivider,
                                          trigger:MouseEvent):void
	{
		// Make sure the user is not currently dragging.
		if (activeDividerIndex >= 0)
			return;
		
		activeDividerIndex = getDividerIndex(divider);

		var event:DividerEvent = 
            new DividerEvent(DividerEvent.DIVIDER_PRESS);
		event.dividerIndex = activeDividerIndex;
		dispatchEvent(event);

		if (liveDragging)
			activeDivider = divider;
		else
		{
			activeDivider = createDivider(PROXY_DIVIDER_INDEX);
			activeDivider.visible = false;
			activeDivider.state = DividerState.DOWN;
			activeDivider.setActualSize(divider.width, divider.height);
			activeDivider.move(divider.x, divider.y);
			activeDivider.visible = true;
			divider.state = DividerState.UP;
		}

		if (isVertical())
			activeDividerStartPosition = activeDivider.y;
		else
			activeDividerStartPosition = activeDivider.x;

        dragStartPosition = getMousePosition(trigger);
		dragDelta = 0;

		cacheChildSizes();
		adjustChildSizes();

		computeMinAndMaxDelta();

		systemManager.getSandboxRoot().addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, true);
		systemManager.deployMouseShields(true);
	}

	/**
	 *  @private
	 *  Store away some important information about
	 *  each child for us to use while we move the divider.
	 */
	private function cacheSizes():void
	{
		oldChildSizes = []; // empty array

		var vertical:Boolean = isVertical();
		
		var smallest:Number = Number.MAX_VALUE; // use a big number
		
		var n:int = numChildren;
		for (var i:int = 0; i < n; i++)
		{
			var child:IUIComponent = getLayoutChildAt(i);
            if (!child.includeInLayout)
                continue;
		
			var sz:Number = vertical ? child.height : child.width;

			var mx:Number = vertical ? child.maxHeight : child.maxWidth;
			
			var umn:Number = vertical ?
							 child.explicitMinHeight :
							 child.explicitMinWidth; // avoid measured values
			
			// A NaN min means 0.
			var mn:Number = (isNaN(umn)) ? 0 : umn;
			
			// Compute these for later use.
			var dMin:Number = Math.max(0, sz - mn);
			var dMax:Number = Math.max(0, mx - sz);

			if (sz > 0 && sz < smallest)
				smallest = sz;

			oldChildSizes.push(new ChildSizeInfo(sz, mn, mx, dMin, dMax));
		}

		// Remember the smallest child size we saw.
		oldChildSizes.push(new ChildSizeInfo((smallest == Number.MAX_VALUE) ? 1 : smallest));
	}

	/**
	 *  @private
	 */
	private function cacheChildSizes():void
	{
		oldChildSizes = []; // clear or store
		
		cacheSizes();
	}

	/**
	 *  @private
	 */
	private function mouseMoveHandler(event:MouseEvent):void
	{
		dragDelta = limitDelta(getMousePosition(event) - dragStartPosition);

		var dividerEvent:DividerEvent = 
            new DividerEvent(DividerEvent.DIVIDER_DRAG);
		dividerEvent.dividerIndex = activeDividerIndex;
		dividerEvent.delta = dragDelta;
		dispatchEvent(dividerEvent);

		if (liveDragging)
		{
			adjustChildSizes();

			invalidateDisplayList();
			
			updateDisplayList(unscaledWidth, unscaledHeight);
		}
		else
		{
			if (isVertical())
				activeDivider.move(0, activeDividerStartPosition + dragDelta);
			else
				activeDivider.move(activeDividerStartPosition + dragDelta, 0);
		}
	}

	/**
	 *  @private
	 * 
	 *  @param trigger May be null if the event is not a MouseEvent but
	 *  a mouse event from another sandbox.
	 */
	mx_internal function stopDividerDrag(divider:BoxDivider,
                                         trigger:MouseEvent):void
	{
	    if (trigger)
		  dragDelta = limitDelta(getMousePosition(trigger) - dragStartPosition);

		var event:DividerEvent = 
            new DividerEvent(DividerEvent.DIVIDER_RELEASE);
		event.dividerIndex = activeDividerIndex;
		event.delta = dragDelta;
        dispatchEvent(event);

        if (!liveDragging)
		{
			if (dragDelta == 0)
				getDividerAt(activeDividerIndex).state = DividerState.OVER;

			if (activeDivider)
				dividerLayer.removeChild(activeDivider);
			activeDivider = null;
			
			adjustChildSizes();

			invalidateSize();
			invalidateDisplayList();
		}

		resetDividerTracking();
		systemManager.getSandboxRoot().removeEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler, true);
        systemManager.deployMouseShields(false);
	}

	/**
	 *  @private
	 */
	private function resetDividerTracking():void
	{
 		activeDivider = null;
		activeDividerIndex = -1;
		activeDividerStartPosition = NaN;
		dragStartPosition = NaN;
		dragDelta = NaN;
		oldChildSizes = null;
		minDelta = NaN;
		maxDelta = NaN;
	}

	/**
	 *  @private
	 *  Determine the maximum amount of movement that 
	 *  a divider, i, can move both up and down.
	 * 
	 *  We base this calculation on the amount of 
	 *  travel that each divider supports, assuming
	 *  that as one divider reaches its limits, the next
 	 *  divider will move.  In this way dividers will
	 *  cascade.
  	 */
	private function computeAllowableMovement(at:int):void
	{
		// We break the computation into two loops, 
		// so that we can calc min and max travel
		// independently as one would move the divider
		// either up or down.
		var deltaMinAbove:Number = 0;
		var deltaMaxAbove:Number = 0;
		var deltaMinBelow:Number = 0;
		var deltaMaxBelow:Number = 0;
		
        var n:int = numLayoutChildren;
		var i:int;
		var child:ChildSizeInfo;

		if (at < 0)
			return;
			
        for (i = at; i >= 0; i--)
		{	
			child = ChildSizeInfo(oldChildSizes[i]);
			
			deltaMinAbove += (dontCoalesceDividers && deltaMinAbove) ?
							 0 : child.deltaMin;
			
			deltaMaxAbove += (dontCoalesceDividers && deltaMaxAbove) ?
							 0 : child.deltaMax;
		}

		for (i = at + 1; i < n; i++)
		{
			child = ChildSizeInfo(oldChildSizes[i]);
			
			deltaMinBelow += (dontCoalesceDividers && deltaMinBelow) ?
							 0 : child.deltaMin;
			
			deltaMaxBelow += (dontCoalesceDividers && deltaMaxBelow) ?
							 0 : child.deltaMax;
		}

		// Now the maximum movement we can have if
		// the divider is moved up is equal to the 
		// smaller of how much we can shrink all
		// components above our divider or the 
		// maximum of how much the components below
		// our divider can grow. Similarly for the 
		// divider moving in the opposite direction.
		var deltaUp:Number = Math.min(deltaMinAbove, deltaMaxBelow);
		var deltaDn:Number = Math.min(deltaMinBelow, deltaMaxAbove);

		// deltaUp needs to be in -ve in order for our 
		// update logic to work
		minDelta = -deltaUp;
		maxDelta = deltaDn;
	}

	/**
	 *  @private
  	 */
	private function computeMinAndMaxDelta():void
	{
		computeAllowableMovement(activeDividerIndex);
	}

	/**
	 *  @private
  	 */
	private function limitDelta(delta:Number):Number
	{
		if (delta < minDelta)
			delta = minDelta;
		else if (delta > maxDelta)
			delta = maxDelta;

		// Make sure it is not fractional,
		// otherwise we lose pixels. (Bug 87339)
		delta = Math.round(delta);
		return delta;
	}

	/**
	 *  @private
     *  We distribute the delta space in the same
	 *  fashion that we calculated it. That is we
     *  start at the divider and give out space
	 *  until we hit a limit on the component or
	 *  we run out of space to distribute.
	 *  We need to do this in both directions since
	 *  in one direction we are shrinking and 
     *  in the other we are growing.
	 */
	private function distributeDelta():void
	{
		// if there is no movement of divider we need not
		// do any child resizing.
		if (!dragDelta)
			return;

		var vertical:Boolean = isVertical();
        var n:int = numLayoutChildren;
		var k:int = activeDividerIndex;
		var smallest:Number = oldChildSizes[n].size -
			Math.abs(dragDelta); // smallest possible child size
		
		if (smallest <= 0 || isNaN(smallest))
			smallest = 1;

		var i:int;
		var size:ChildSizeInfo;
		var move:Number;
		var newSize:Number;
		var child:IUIComponent;
		var childSize:Number;
		
        // Find the index of the child before the active divider
        var activeDividerChildIndex:int = -1;
        var dividerIndex:int = -1;
        while (dividerIndex < activeDividerIndex)
        {
            if (UIComponent(getChildAt(++activeDividerChildIndex)).includeInLayout)
                ++dividerIndex;
        }

		// Distribute space starting from the center and 
		// moving upwards.
        var curChildIndex:int = activeDividerChildIndex;
		var amt:Number = dragDelta;
        for (i = k; i >= 0; i--)
		{
			// If dragDelta -ve  => shrink upper components
			// otherwise grow them.
			size = ChildSizeInfo(oldChildSizes[i]);
			move = (amt < 0) ?
				   -Math.min(-amt, size.deltaMin) :
				   Math.min(amt, size.deltaMax);

			// Adjust the component and reduce the remaining delta
			newSize = size.size + move;
			amt -= move;

            // Find the previous child included in the layout
            do
            {
                 child = IUIComponent(getChildAt(curChildIndex--));
            }
            while (!child.includeInLayout);

			// Adjust the child size.
			childSize = (newSize / smallest) * 100;
			
			if (vertical)
				child.percentHeight = childSize;
			else
				child.percentWidth = childSize;

			// Force a re-measure.
			if (child is IInvalidating)
				IInvalidating(child).invalidateSize();
		}

		// assert(amt == 0)

		// Now do the same distribution but moving downwards.
        curChildIndex = activeDividerChildIndex + 1;
		amt = dragDelta;
		for (i = k + 1; i < n; i++)
		{
			// If dragDelta -ve  => grow lower components
			// otherwise shrink them.
			size = ChildSizeInfo(oldChildSizes[i]);
			move = (amt < 0) ?
				   Math.min(-amt, size.deltaMax) :
				   -Math.min(amt, size.deltaMin);

			// Adjust the component and reduce the remaining delta.
			newSize = size.size + move;
			amt += move;

            // Find the next child included in the layout
            do
            {
                 child = IUIComponent(getChildAt(curChildIndex++));
            }
            while (!child.includeInLayout);

			childSize = (newSize / smallest) * 100;
			
			if (vertical)
				child.percentHeight = childSize;
			else
				child.percentWidth = childSize;

			// Force a re-measure.
			if (child is IInvalidating)
				IInvalidating(child).invalidateSize();
		}
	}

	/**
	 *  @private
 	 *  For 1.5 we normalize all children to the smallest one
	 *  So that we can remove n-1 children and still guarantee
	 *  one child can consume 100%.
	 *  Also we support the concept of fixed sized children, 
	 *  which allows us to have one or more children be rigid
     *  in the DividedBox in this case, the dividers above 
     *  and below the fixed component move in unison.
	 */
	private function adjustChildSizes():void
	{
		distributeDelta();
	}

	/**
	 *  @private
	 *  Algorithm employed pre-layout to ensure that 
	 *  we don't leave any dangling space and to ensure
	 *  that only explicit min/max values are honored.
	 * 
	 *  We first compute the sum of %'s across all 
	 *  children to ensure that we have at least 100%.
 	 *  If so, we are done.  If not, then we attempt 
	 *  to attach the remaining amount to the last 
	 *  component, if not, then we distribute the 
	 *  percentages evenly across all % components.
	 * 
	 */
	private function preLayoutAdjustment():void
	{
		// Calculate the total %
		var vertical:Boolean = isVertical();
		
		var totalPerc:Number = 0;
		var percCount:Number = 0;
		
		var n:int = numChildren;
		var i:int;
		var child:IUIComponent;
		var perc:Number;

		for (i = 0; i < n; i++)
		{
			child = getLayoutChildAt(i);

			if (!child.includeInLayout)
				continue;

			// Clear out measured min/max
			// so super.layout() doesn't use them.
			child.measuredMinWidth = 0; 
			child.measuredMinHeight = 0;

			perc = vertical ? child.percentHeight : child.percentWidth;
			
			if (!isNaN(perc))
			{
				totalPerc += perc;
				percCount++;
			}
		}

        // during preLayoutAdjustment, we make some changes to the children's
        // widths and heights.  We keep track of the original values in postLayoutChanges
        // so we can later go back and reset them so another layout pass is working 
        // with the correct values rather than these modified values.
        postLayoutChanges = [];
        var changeObject:Object;

		// No flexible children, so we make the last one 100%.
		if (totalPerc == 0 && percCount == 0)
		{
            // Everyone is fixed and we can give 100% to the last
            // included in layout one without concern.
            for (i = n-1; i >= 0; i--)
			{
                child = UIComponent(getChildAt(i));
				if (child.includeInLayout)
				{
                    // create a changeObject to keep track of the original values 
                    // that this child had for width and height
                    changeObject = {child: child};
					if (vertical)
                    {
                        // we know there's no percentHeight originally
                        if (child.explicitHeight)
                            changeObject.explicitHeight = child.explicitHeight;
                        else 
                            changeObject.percentHeight = NaN;
                        
						child.percentHeight = 100;
                    }
					else
                    {
                        // we know there's no percentWidth originally
                        if (child.explicitWidth)
                            changeObject.explicitWidth = child.explicitWidth;
                        else if (child.percentWidth)
                            changeObject.percentWidth = NaN;
                        
						child.percentWidth = 100;
                    }
                    postLayoutChanges.push(changeObject);
                    break;
				}
			}
		}
		else if (totalPerc < 100)
		{
			// We have some %s but they don't total to 100, so lets
			// distribute the delta across all of them and in the
			// meantime normalize all %s to unscaledHeight/Width.
			// The normalization takes care of the case where any one
			// of the components hits a min/max limit on their size,
			// which could result in the others filling less than 100%.
			var delta:Number = Math.ceil((100 - totalPerc) / percCount);
			for (i = 0; i < n; i++)
			{
				child = getLayoutChildAt(i);

				if (!child.includeInLayout)
					continue;
				
                changeObject = {child: child};

				if (vertical)
				{
					perc = child.percentHeight;
					if (!isNaN(perc))
                    {
                        changeObject.percentHeight = child.percentHeight;
                        postLayoutChanges.push(changeObject);
                        
						child.percentHeight = (perc + delta) * unscaledHeight;
				}
				}
				else
				{
					perc = child.percentWidth;
					if (!isNaN(perc))
                    {
                        changeObject.percentWidth = child.percentWidth;
                        postLayoutChanges.push(changeObject);
                        
						child.percentWidth = (perc + delta) * unscaledWidth;
				}
			}
		}
        }

		// OK after all this magic we still can't guarantee that the space is
		// entirely filled. For example, all percent components hit their max
		// values. In this case, the layout will include empty space at the end,
		// and once the divider is touched, the non-percent based components
		// will be converted into percent based ones and fill the remaining
		// space. It seems to me that this scenario is highly unlikely.
		// Thus I've choosen the route of stretching the percent based
		// components and not touching the explicitly sized or default
		// sized ones.
		//
		// Another option would be to stretch the default sized components
		// either in addition to the percent based ones or instead of.
		// This seemed a  little odd to me as the user never indicated
		// that these components are to be stretched initially, so in the end
		// I choose to tweak the components that the user has indicated
		// as being stretchable. 
	}

    /**
     *  @private
     *  During preLayoutAdjustment, we make some changes to the children's
     *  widths and heights.  We keep track of the original values in postLayoutChanges
     *  so we can later go back and reset them so another layout pass is working 
     *  with the correct values rather than these modified values.
     */ 
    private var postLayoutChanges:Array;
    
    /**
     *  @private
     *  Post layout work.  In preLayoutAdjustment() 
     *  sometimes we set a child's percentWidth/percentHeight.  
     *  postLayoutAdjustment() will reset the child's width or height
     *  back to what it was.
     */
    private function postLayoutAdjustment():void
    {
        // each object has a child property and may have a set of width/height 
        // properties that it would like to be set
        var len:int = postLayoutChanges.length;
        for (var i:int = 0; i < len; i++)
        {
            var changeObject:Object = postLayoutChanges[i];
            
            if (changeObject.percentWidth !== undefined)
                changeObject.child.percentWidth = changeObject.percentWidth;
            
            if (changeObject.percentHeight !== undefined)
                changeObject.child.percentHeight = changeObject.percentHeight;
            
            if (changeObject.explicitWidth !== undefined)
                changeObject.child.explicitWidth = changeObject.explicitWidth;
            
            if (changeObject.explicitHeight !== undefined)
                changeObject.child.explicitHeight = changeObject.explicitHeight;
        }
        postLayoutChanges = null;
    }

	//--------------------------------------------------------------------------
	//
	//  Event handlers
	//
	//--------------------------------------------------------------------------

	/**
	 *  @private
	 */
	private function childAddHandler(event:ChildExistenceChangedEvent):void
	{
		var child:DisplayObject = event.relatedObject;

		child.addEventListener("includeInLayoutChanged",
                               child_includeInLayoutChangedHandler);

        if (!IUIComponent(child).includeInLayout)
          return;
			
        numLayoutChildren++;
			
        if (numLayoutChildren > 1)
            createDivider(numLayoutChildren - 2);
			
		// Clear the cached values so that we do another 
		// measurement pass.
		dbMinWidth = NaN;
		dbMinHeight = NaN;
		dbPreferredWidth = NaN;
		dbPreferredHeight = NaN;
	}

	/**
	 *  @private
	 */
	private function childRemoveHandler(event:ChildExistenceChangedEvent):void
	{
		var child:DisplayObject = event.relatedObject;
		
        child.removeEventListener("includeInLayoutChanged",
                                  child_includeInLayoutChangedHandler);

        if (!IUIComponent(child).includeInLayout)
          return;

			numLayoutChildren--;
	
		if (numLayoutChildren > 0)
			dividerLayer.removeChild(getDividerAt(numLayoutChildren - 1));

		// Clear the cached values so that we do another 
		// measurement pass.
		dbMinWidth = NaN;
		dbMinHeight = NaN;
		dbPreferredWidth = NaN;
		dbPreferredHeight = NaN;
		invalidateSize();
	}
	
	/**
	 *  @private
	 *  When a child's includeInLayout changes, we either remove or add a
	 *  divider.
	 */
	private function child_includeInLayoutChangedHandler(event:Event):void
	{
		var child:UIComponent = UIComponent(event.target);

		if (child.includeInLayout && ++numLayoutChildren > 1)
			createDivider(numLayoutChildren - 2);

		else if (!child.includeInLayout && --numLayoutChildren > 0)
			dividerLayer.removeChild(getDividerAt(numLayoutChildren - 1));

        // Clear the cached values so that we do another
        // measurement pass.
        dbMinWidth = NaN;
        dbMinHeight = NaN;
        dbPreferredWidth = NaN;
        dbPreferredHeight = NaN;
        invalidateSize();
	}
	
}

}

////////////////////////////////////////////////////////////////////////////////
//
//  Helper class: ChildSizeInfo
//
////////////////////////////////////////////////////////////////////////////////

/**
 *  @private
 */
class ChildSizeInfo
{
	//--------------------------------------------------------------------------
	//
	//  Constructor
	//
	//--------------------------------------------------------------------------
	
	/**
	 *  @private
	 */
	public function ChildSizeInfo(size:Number,
								  min:Number = 0, max:Number = 0,
								  deltaMin:Number = 0, deltaMax:Number = 0)
	{
		super();

		this.size = size;
		this.min = min;
		this.max = max;
		this.deltaMin = deltaMin;
		this.deltaMax = deltaMax;
	}

	//--------------------------------------------------------------------------
	//
	//  Properties
	//
	//--------------------------------------------------------------------------

	//----------------------------------
	//  deltaMin
	//----------------------------------

	/**
	 *  @private
	 */
	public var deltaMin:Number;

	//----------------------------------
	//  deltaMax
	//----------------------------------

	/**
	 *  @private
	 */
	public var deltaMax:Number;

	//----------------------------------
	//  min
	//----------------------------------

	/**
	 *  @private
	 */
	public var min:Number;

	//----------------------------------
	//  max
	//----------------------------------

	/**
	 *  @private
	 */
	public var max:Number;

	//----------------------------------
	//  size
	//----------------------------------

	/**
	 *  @private
	 */
	public var size:Number;
}


