////////////////////////////////////////////////////////////////////////////////
//
//  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
{
import flash.events.Event;

import mx.core.IVisualElement;
import mx.core.UIComponent;
import mx.core.mx_internal;

import spark.core.IDisplayText;

use namespace mx_internal;

/**
 *  Specifies the image source to use for the required indicator. 
 *
 *  The default value is "assets/RequiredIndicator.png".
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
[Style(name="requiredIndicatorSource", type="Object", inherit="no")]

/**
 *  Specifies the image source to use for the error indicator. 
 *
 *  The default value is "assets/ErrorIndicator.png".
 *  
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5
 */
[Style(name="errorIndicatorSource", type="Object", inherit="no")]

/**
 *  The FormItem container defines the following in a Spark From:
 *
 *  <ul>
 *    <li>A single label.</li>
 *    <li>A sequence label.</li>
 *    <li>One or more child controls or containers.</li>
 *    <li>Help content that provides a description of the form item 
 *      or instructions for filling it in.</li>
 *    <li>Required indicator to indicate if a form item has to be filled</li>
 *  </ul>
 *
 *  Children can be controls or other containers.
 *  A single Form container can hold multiple FormItem containers.
 *  By default, all the FormItem elements are arranged in a horizontal 
 *  layout with the label placed on the left and the Help content on the right.
 *
 *  @mxml
 *
 *  <p>The <code>&lt;s:FormItem&gt;</code> tag inherits all the tag 
 *  attributes of its superclass and adds no new tag attributes:</p>
 *
 *  <pre>
 *  &lt;s:FormItem
 *    <strong>Properties</strong>
 *    helpContent="null"
 *    label=""
 *    required="false"
 *    sequenceLabel=""
 *  
 *    <strong>Common Styles</strong>
 *    errorIndicatorSource="assets/ErrorIndicator.png"
 *    requiredIndicatorSource="assets/RequiredIndicator.png"
 * 
 *    <strong>Mobile Styles</strong>
 *    leading="2"
 *    letterSpacing="0"
 *  /&gt;
 *  </pre>
 * 
 *  @see spark.components.Form
 *  @see spark.components.FormHeading
 *  @see spark.layouts.FormLayout
 *  @see spark.skins.spark.FormItemSkin
 *
 *  @includeExample examples/FormItemExample.mxml
 *
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 2.5
 *  @productversion Flex 4.5 
 */
public class FormItem extends SkinnableContainer
{
    include "../core/Version.as";
    
    //--------------------------------------------------------------------------
    //
    //  Constructor
    //
    //--------------------------------------------------------------------------
    
    /**
     *  Constructor.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function FormItem()
    {
        super();
        // Set these here instead of in the CSS type selector for Form
        // We want to hide the fact that the Form itself doesn't show
        // the error skin or error tip, but that its children do. 
        setStyle("showErrorSkin", false);
        setStyle("showErrorTip", false);
        
        showInAutomationHierarchy = false;
    }
    
    //--------------------------------------------------------------------------
    //
    //  Skin Parts
    //
    //--------------------------------------------------------------------------
    
    /**
     *   A reference to the visual element that displays this FormItem's label.
     */
    [SkinPart(required="false")]
    public var labelDisplay:IDisplayText;
            
    /**
     *  A reference to the visual element that displays the FormItem's sequenceLabel.
     */
    [SkinPart(required="false")]
    public var sequenceLabelDisplay:IDisplayText;
    
    /**
     *  A reference to the Group that contains the FormItem's helpContentGroup.
     */
    [SkinPart(required="false")]
    public var helpContentGroup:Group;
    
    /**
     *  A reference to the visual element that display the FormItem's error strings.
     */
    [SkinPart(required="false")]
    public var errorTextDisplay:IDisplayText;
    
    //--------------------------------------------------------------------------
    //
    //  Properties 
    //
    //--------------------------------------------------------------------------
    
    mx_internal var _elementErrorStrings:Vector.<String> = new Vector.<String>;
    
    /**
     *  Each Vector item contains the error string from a content element. 
     *  If none of the content elements are invalid, then the vector 
     *  is empty. 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */     
    [Bindable(event="elementErrorStringsChanged")]
    
    public function get elementErrorStrings():Vector.<String>
    {
        return _elementErrorStrings;
    }
     
    //----------------------------------
    //  helpContent
    //----------------------------------

    private var _helpContent:Array;
    private var helpContentChanged:Boolean = false;
    
    [ArrayElementType("mx.core.IVisualElement")]
    [Bindable("helpContentChanged")]
    [Inspectable(category="General", arrayType="mx.core.IVisualElement", defaultValue="")]
    
    /** 
     *  The set of components to include in the help content 
     *  area of the FormItem.
     * 
     *  @default null
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get helpContent():Array
    {
        if (helpContentGroup)
            return helpContentGroup.getMXMLContent();
        else
            return _helpContent;
    }
    
    /**
     *  @private
     */
    public function set helpContent(value:Array):void
    {
        _helpContent = value;
        helpContentChanged = true;
        invalidateProperties();
    }
    
    //----------------------------------
    //  label
    //----------------------------------
    
    private var _label:String = "";
    
    [Bindable("labelChanged")]
    [Inspectable(category="General", defaultValue="")]
    
    /**
     *  Text label for the FormItem.
     *  For example, a FormItem used to input an 
     *  address might have the label of "Address".
     * 
     *  @default ""
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get label():String
    {
        return _label;
    }
    
    /**
     *  @private
     */
    public function set label(value:String):void
    {
        if (_label == value)
            return;
        
        _label = value;
        
        if (labelDisplay)
            labelDisplay.text = label;
        dispatchEvent(new Event("labelChanged"));
    }
            
    //----------------------------------
    //  required
    //----------------------------------
    
    private var _required:Boolean = false;
    
    [Bindable("requiredChanged")]
    [Inspectable(category="General", defaultValue="false")]
    
    /**
     *  If <code>true</code>, puts the FormItem skin into the
     *  <code>required</code> state. By default, this state displays 
     *  an indicator that the FormItem children require user input.
     *  If <code>false</code>, the indicator is not displayed.
     *
     *  <p>This property controls skin's state only.
     *  You must assign a validator to the child 
     *  if you require input validation.</p>
     *
     *  @default false
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get required():Boolean
    {
        return _required;
    }
    
    /**
     *  @private
     */
    public function set required(value:Boolean):void
    {
        if (value == _required)
            return;
        
        _required = value;
        invalidateSkinState();
    }
    
    //----------------------------------
    //  sequenceLabel
    //----------------------------------
    
    private var _sequenceLabel:String = "";
    
    [Bindable("sequenceLabelChanged")]
    [Inspectable(category="General", defaultValue="")]
    
    /**
     *  The number of the form item in the form. 
     * 
     *  @default ""
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    public function get sequenceLabel():String
    {
        return _sequenceLabel;
    }
    
    /**
     *  @private
     */
    public function set sequenceLabel(value:String):void
    {
        if (_sequenceLabel == value)
            return;
        
        _sequenceLabel = value;
        
        if (sequenceLabelDisplay)
            sequenceLabelDisplay.text = sequenceLabel;
        dispatchEvent(new Event("sequenceLabelChanged"));
        
        invalidateProperties();
    }
    
    //--------------------------------------------------------------------------
    //
    //  Overridden Properties
    //
    //--------------------------------------------------------------------------
    
    //----------------------------------
    //  baselinePosition
    //----------------------------------
    
    /**
     *  @private
     */
    override public function get baselinePosition():Number
    {
        return getBaselinePositionForPart(labelDisplay as IVisualElement);
    }     
    
    //--------------------------------------------------------------------------
    //
    //  Overridden Methods
    //
    //--------------------------------------------------------------------------
 
    /**
     *  @private
     */
    override protected function commitProperties():void
    {
        super.commitProperties();
        
        if (helpContentChanged)
        {
            createHelpContent();
            helpContentChanged = false;
        }
    }
    
    /**
     *  @private
     */
    override protected function getCurrentSkinState():String
    {
        if (required)
        {
            if (!enabled)
                return "requiredAndDisabled";
            else if (elementErrorStrings.length > 0)
                return "requiredAndError";
            else
                return "required";
        }
        else
        {
            if (!enabled)
                return "disabled";
            else if (elementErrorStrings.length > 0)
                return "error";
            else
                return "normal";       
        }
    }
    
    /**
     *  @private
     */
    override protected function partAdded(partName:String, instance:Object) : void
    {
        super.partAdded(partName, instance);
        
        if (instance == labelDisplay)
            labelDisplay.text = label;
        else if (instance == sequenceLabelDisplay)
            sequenceLabelDisplay.text = sequenceLabel;
        else if (instance == errorTextDisplay)
            updateErrorTextDisplay();
        else if (instance == helpContentGroup)
        {
            helpContentChanged = true;
            createHelpContent();
        }
        else if (instance == contentGroup)
        {
            contentGroup.addEventListener("errorStringChanged", contentGroup_errorStringdHandler, true);
        }
    }
    
    /**
     *  @private
     */
    override protected function partRemoved(partName:String, instance:Object) : void
    {
        super.partRemoved(partName, instance);
        
        // Remove the helpContent from the helpContentGroup so that it can be parented
        // by a different skin's helpContentGroup
        if (instance == helpContentGroup)
            helpContentGroup.removeAllElements();
        if (instance == contentGroup)
            contentGroup.removeEventListener("errorStringChanged", contentGroup_errorStringdHandler, true);
    }
    
    //--------------------------------------------------------------------------
    //
    //  Methods
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    private function updateErrorString():void
    {
        var uicElt:UIComponent;
        _elementErrorStrings = new Vector.<String>;
        
        for (var i:int = 0; i < numElements; i++)
        {
            uicElt = getElementAt(i) as UIComponent;
            
            if (uicElt)
            {
                if (uicElt.errorString != "")
                {
                    _elementErrorStrings.push(uicElt.errorString);
                }
            }
        }
        
        invalidateSkinState();
        
        updateErrorTextDisplay();
        dispatchEvent(new Event("elementErrorStringsChanged"));
    }
    
    /**
     *  Converts <code>elementErrorStrings</code> into a String, and assigns
     *  that String to the <code>errorTextDisplay</code> skin part for display. 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 10
     *  @playerversion AIR 2.5
     *  @productversion Flex 4.5
     */
    protected function updateErrorTextDisplay():void
    {
        var msg:String = "";
        for (var i:int=0; i < elementErrorStrings.length; i++)
        {
            if (msg != "")
                msg += "\n";
            msg += elementErrorStrings[i];
        }
        
        if (errorTextDisplay)
            errorTextDisplay.text = msg;
        errorString = msg;
    }
    
    /**
     *  @private
     */
    private function createHelpContent():void
    {
        if (helpContentGroup)
            helpContentGroup.mxmlContent = _helpContent; 
    }
    
    //--------------------------------------------------------------------------
    //
    //  Event Handlers 
    //
    //--------------------------------------------------------------------------
    
    /**
     *  @private
     */
    private function contentGroup_errorStringdHandler(event:Event):void
    {
        updateErrorString();
    }
}
}