////////////////////////////////////////////////////////////////////////////////
//
//  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.controls
{

import flash.display.DisplayObject;
import flash.events.MouseEvent;
import mx.core.ClassFactory;
import mx.core.EdgeMetrics;
import mx.core.IFlexDisplayObject;
import mx.core.mx_internal;
import mx.events.ChildExistenceChangedEvent;
import mx.events.FlexEvent;
import mx.events.ItemClickEvent;
import mx.styles.ISimpleStyleClient;
import mx.styles.StyleProxy;

use namespace mx_internal;

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

/**
 *  Number of pixels between the LinkButton controls in the horizontal direction.
 * 
 *  @default 8
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="horizontalGap", type="Number", format="Length", inherit="no")]

/**
 *  Name of CSS style declaration that specifies the styles to use for the link
 *  button navigation items.
 * 
 *  @default ""
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="linkButtonStyleName", type="String", inherit="no")]

/**
 *  Number of pixels between the bottom border and the LinkButton controls.
 * 
 *  @default 2
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="paddingBottom", type="Number", format="Length", inherit="no")]

/**
 *  Number of pixels between the top border and the LinkButton controls.
 * 
 *  @default 2
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="paddingTop", type="Number", format="Length", inherit="no")]

/**
 *  Color of links as you roll the mouse pointer over them.
 *  The default value is based on the current <code>themeColor</code>.
 * 
 *  The default value for the Halo theme is <code>0xB2E1FF</code>.
 *  The default value for the Spark theme is <code>0xCEDBEF</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="rollOverColor", type="uint", format="Color", inherit="yes")]

/**
 *  Background color of the LinkButton control as you press it.
 * 
 *  The default value for the Halo theme is <code>0x7FCEFF</code>.
 *  The default value for the Spark theme is <code>0xA8C6EE</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="selectionColor", type="uint", format="Color", inherit="yes")]

/**
 *  Separator color used by the default separator skin.
 * 
 *  @default 0xC4CCCC
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="separatorColor", type="uint", format="Color", inherit="yes")]

/**
 *  Seperator symbol between LinkButton controls in the LinkBar. 
 * 
 *  @default mx.skins.halo.LinkSeparator (for both Halo and Spark themes)
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="separatorSkin", type="Class", inherit="no")]

/**
 *  Separator pixel width, in pixels.
 * 
 *  @default 1
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="separatorWidth", type="Number", format="Length", inherit="yes")]

/**
 *  Text color of the link as you move the mouse pointer over it.
 * 
 *  The default value for the Halo theme is <code>0x2B333C</code>.
 *  The default value for the Spark theme is <code>0x000000</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="textRollOverColor", type="uint", format="Color", inherit="yes")]

/**
 *  Text color of the link as you press it.
 * 
 *  The default value for the Halo theme is <code>0x2B333C</code>.
 *  The default for the Spark theme is <code>0x000000</code>.
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="textSelectedColor", type="uint", format="Color", inherit="yes")]

/**
 *  Number of pixels between children in the vertical direction.
 * 
 *  @default 8
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Style(name="verticalGap", type="Number", format="Length", inherit="no")]

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

[Exclude(name="horizontalLineScrollSize", kind="property")]
[Exclude(name="horizontalPageScrollSize", kind="property")]
[Exclude(name="horizontalScrollBar", kind="property")]
[Exclude(name="horizontalScrollPolicy", kind="property")]
[Exclude(name="horizontalScrollPosition", kind="property")]
[Exclude(name="maxHorizontalScrollPosition", kind="property")]
[Exclude(name="maxVerticalScrollPosition", kind="property")]
[Exclude(name="verticalLineScrollSize", kind="property")]
[Exclude(name="verticalPageScrollSize", kind="property")]
[Exclude(name="verticalScrollBar", kind="property")]
[Exclude(name="verticalScrollPolicy", kind="property")]
[Exclude(name="verticalScrollPosition", kind="property")]

[Exclude(name="scroll", kind="event")]
[Exclude(name="click", kind="event")]

[Exclude(name="horizontalScrollBarStyleName", kind="style")]
[Exclude(name="verticalScrollBarStyleName", kind="style")]

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

[DefaultProperty("dataProvider")]

[IconFile("LinkBar.png")]

[MaxChildren(0)]

/**
 *  A LinkBar control defines a horizontal or vertical row of LinkButton controls
 *  that designate a series of link destinations.
 *  You typically use a LinkBar control to control
 *  the active child container of a ViewStack container,
 *  or to create a stand-alone set of links.
 *
 *  <p>The LinkBar control creates LinkButton controls based on the value of 
 *  its <code>dataProvider</code> property. 
 *  Even though LinkBar is a subclass of Container, do not use methods such as 
 *  <code>Container.addChild()</code> and <code>Container.removeChild()</code> 
 *  to add or remove LinkButton controls. 
 *  Instead, use methods such as <code>addItem()</code> and <code>removeItem()</code> 
 *  to manipulate the <code>dataProvider</code> property. 
 *  The LinkBar control automatically adds or removes the necessary children based on 
 *  changes to the <code>dataProvider</code> property.</p>
 *
 *  <p>A LinkBar control has the following default characteristics:</p>
 *  <table class="innertable">
 *     <tr>
 *        <th>Characteristic</th>
 *        <th>Description</th>
 *     </tr>
 *     <tr>
 *        <td>Preferred size</td>
 *        <td>A width wide enough to contain all label text, plus any padding and separators, and the height of the tallest child.</td>
 *     </tr>
 *     <tr>
 *        <td>Control resizing rules</td>
 *        <td>LinkBar controls do not resize by default. Specify percentage sizes if you want your LinkBar to resize based on the size of its parent container.</td>
 *     </tr>
 *     <tr>
 *        <td>Padding</td>
 *        <td>2 pixels for the top, bottom, left, and right properties.</td>
 *     </tr>
 *  </table>
 *
 *  @mxml
 *  <p>The <code>&lt;mx:LinkBar&gt;</code> tag inherits all of the tag
 *  attributes of its superclass, and adds the following tag attributes:</p>
 *
 *  <pre>
 *  &lt;mx:LinkBar
 *    <b>Properties</b>
 *    selectedIndex="-1"
 *  
 *    <b>Styles</b>
 *    linkButtonStyleName=""
 *    horizontalGap="8"
 *    paddingBottom="2"
 *    paddingTop="2"
 *    rollOverColor="0xEEFEE6"
 *    selectionColor="0xCDFFC1"
 *    separatorColor="<i>No default</i>"
 *    separatorSkin="0x000000"
 *    separatorWidth="1"
 *    textRollOverColor="0x2B333C"
 *    textSelectedColor="0x000000"
 *    verticalGap="8"
 *    &gt;
 *    ...
 *      <i>child tags</i>
 *    ...
 *  &lt;/mx:LinkBar&gt;
 *  </pre>
 *
 *  @includeExample examples/LinkBarExample.mxml
 *
 *  @see mx.controls.NavBar
 *  @see mx.containers.ViewStack
 *  @see mx.controls.LinkButton
 *  @see mx.controls.ToggleButtonBar
 *  @see mx.controls.ButtonBar
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class LinkBar extends NavBar
{
    include "../core/Version.as";

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

    /**
     *  @private
     */
    private static const SEPARATOR_NAME:String = "_separator";

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

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

        navItemFactory = new ClassFactory(LinkButton);

        addEventListener(MouseEvent.CLICK, defaultClickHandler);
        addEventListener(ChildExistenceChangedEvent.CHILD_REMOVE, 
                         childRemoveHandler);
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden properties
    //
    //--------------------------------------------------------------------------

    //----------------------------------
    //  selectedIndex
    //----------------------------------

    /**
     *  @private
     *  Storage for the selectedIndex property.
     */
    private var _selectedIndex:int = -1;

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

    [Bindable("valueCommit")]
    [Inspectable(category="General")]

    /**
     *  The index of the last selected LinkButton control if the LinkBar 
     *  control uses a ViewStack container as its data provider.
     * 
     *  @default -1
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    override public function get selectedIndex():int
    {
        return super.selectedIndex;
    }

    /**
     *  @private
     */
    override public function set selectedIndex(value:int):void
    {
        if (value == selectedIndex)
            return;

        _selectedIndex = value;
        
        _selectedIndexChanged = true;

        invalidateProperties();

        dispatchEvent(new FlexEvent(FlexEvent.VALUE_COMMIT));
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden methods: UIComponent
    //
    //--------------------------------------------------------------------------

    /**
     *  @inheritDoc
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    override public function styleChanged(styleProp:String):void
    {
        super.styleChanged(styleProp);
        
        var navItemStyleName:Object;
        
        if (styleProp == "linkButtonStyleName")
            navItemStyleName = getStyle("linkButtonStyleName");
        
        if (navItemStyleName)
        {
            var n:int = numChildren;
            for (var i:int = 0; i < n; i++)
            {               
                LinkButton(getChildAt(i)).styleName = navItemStyleName;
            }
        }
    }

    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();

        if (_selectedIndexChanged)
        {
            hiliteSelectedNavItem(_selectedIndex);

            // Update parent index.
            super.selectedIndex = _selectedIndex;

            _selectedIndexChanged = false;
        }
    }

    /**
     *  Responds to size changes by setting the positions and sizes
     *  of this LinkBar control's children. 
     *  For more information about the <code>updateDisplayList()</code> method,
     *  see the <code>UIComponent.updateDisplayList()</code> method.
     *
     *  <p>The <code>LinkBar.updateDisplayList()</code> method first calls
     *  the <code>Box.updateDisplayList()</code> method to position the LinkButton controls.
     *  For more details, see the <code>Box.updateDisplayList()</code> method.
     *  After laying out the LinkButton controls, the separators are positioned
     *  between them.</p>
     *
     *  @param unscaledWidth Specifies the width of the component, in pixels,
     *  of the component's coordinates, regardless of the value of the
     *  <code>scaleX</code> property of the component.
     *
     *  @param unscaledHeight Specifies the height of the component, in pixels,
     *  in the component's coordinates, regardless of the value of the
     *  <code>scaleY</code> property of the component.
     * 
     *  @see mx.core.UIComponent#updateDisplayList()
     *  @see mx.containers.Box#updateDisplayList()
     * 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    override protected function updateDisplayList(unscaledWidth:Number,
                                                  unscaledHeight:Number):void
    {
        // The super method will lay out the Links.
        super.updateDisplayList(unscaledWidth, unscaledHeight);

        var vm:EdgeMetrics = viewMetricsAndPadding;

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

        var separatorHeight:Number = unscaledHeight - (vm.top + vm.bottom);
        var separatorWidth:Number = unscaledWidth - (vm.left + vm.right);

        // Lay out the separators.
        var n:int = numChildren;
        for (var i:int = 0; i < n; i++)
        {
            var child:IFlexDisplayObject = IFlexDisplayObject(getChildAt(i));

            var separator:IFlexDisplayObject = IFlexDisplayObject(
                rawChildren.getChildByName(SEPARATOR_NAME + i));

            if (separator)
            {
                separator.visible = false;

                // The 0th separator is to the left of the first link.
                // It should always be invisible, and doesn't need
                // to be laid out.
                if (i == 0)
                    continue;

                if (isVertical())
                {
                    separator.move(vm.left, child.y - verticalGap);
                    separator.setActualSize(separatorWidth, verticalGap);

                    // The separators don't get clipped.
                    // (In general, chrome elements
                    // don't get automatically clipped.)
                    // So show a separator only if it is completely visible.
                    if (separator.y + separator.height <
                        unscaledHeight - vm.bottom)
                    {
                        separator.visible = true;
                    }
                }
                else
                {
                    separator.move(child.x - horizontalGap, vm.top);
                    separator.setActualSize(horizontalGap, separatorHeight);

                    if (separator.x + separator.width <
                        unscaledWidth - vm.right)
                    {
                        separator.visible = true;
                    }
                }
            }
        }
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden methods: NavBar
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     */
    override protected function createNavItem(
                                        label:String,
                                        icon:Class = null):IFlexDisplayObject
    {
        // Create the new LinkButton.

        var newLink:Button = Button(navItemFactory.newInstance());

        var linkButtonStyleName:String = getStyle("linkButtonStyleName");
        if (linkButtonStyleName)
            newLink.styleName = linkButtonStyleName;
                 
        if (label && label.length > 0)
            newLink.label = label;
        else
            newLink.label = " ";

        if (icon)
            newLink.setStyle("icon", icon);

        addChild(newLink);

        newLink.addEventListener(MouseEvent.CLICK, clickHandler);

        // Create the new separator to the left of the LinkButton.

        var separatorClass:Class = Class(getStyle("separatorSkin"));
        var separator:DisplayObject = DisplayObject(new separatorClass());

        separator.name = SEPARATOR_NAME + (numChildren - 1);
        if (separator is ISimpleStyleClient)
            ISimpleStyleClient(separator).styleName = this;

        rawChildren.addChild(separator);
        
        return newLink;
    }

    /**
     *  @private
     */
    override protected function hiliteSelectedNavItem(index:int):void
    {
        var child:Button;

        // Un-hilite the current selection.
        if (selectedIndex != -1 && selectedIndex < numChildren)
        {
            child = Button(getChildAt(selectedIndex));
            child.enabled = true;
        }

        // Set new index.
        super.selectedIndex = index;

        if (index != -1)
        {
            // Hilite the new selection.
            child = Button(getChildAt(selectedIndex));
            child.enabled = false;
        }
    }

    /**
     *  @private
     */
    override protected function resetNavItems():void
    {
        // Reset the index values and selection state.
        var n:int = numChildren;
        for (var i:int = 0; i < n; i++)
        {
            var child:Button = Button(getChildAt(i));
            child.enabled = !(i == selectedIndex);
        }

        invalidateDisplayList();
    }

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

    /**
     *  @private
     */
    private function childRemoveHandler(event:ChildExistenceChangedEvent):void
    {
        var child:DisplayObject = event.relatedObject;
        var index:int = getChildIndex(child);
        var separator:DisplayObject =
            rawChildren.getChildByName(SEPARATOR_NAME + index);
        rawChildren.removeChild(separator);

        // Shuffle the separators down.
        var n:int = numChildren - 1;
        for (var i:int = index; i < n; i++)
        {
            rawChildren.getChildByName(SEPARATOR_NAME + (i + 1)).name =
                SEPARATOR_NAME + i;
        }
    
    }

    /**
     *  @private
     */
    private function defaultClickHandler(event:MouseEvent):void
    {
        // We do not want to propagate a MouseEvent.CLICK event up.
        if (!(event is ItemClickEvent))
            event.stopImmediatePropagation();
    }
    
    //--------------------------------------------------------------------------
    //
    //  Overridden event handlers: NavBar
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    override protected function clickHandler(event:MouseEvent):void
    {
        var index:int = getChildIndex(Button(event.currentTarget));

        if (targetStack)
        {
            if (index == selectedIndex)
                hiliteSelectedNavItem(-1);
                
            else
                hiliteSelectedNavItem(index);
        }
        
        super.clickHandler(event);
    }
    
}

}
