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

    import flash.events.Event;
    import flash.events.EventDispatcher;

    import mx.collections.errors.SortError;
    import mx.core.mx_internal;
    import mx.resources.IResourceManager;
    import mx.resources.ResourceManager;
    import mx.utils.ObjectUtil;

    [ResourceBundle("collections")]
[Alternative(replacement="spark.collections.SortField", since="4.5")]

/**
 *  Provides the sorting information required to establish a sort on a field
 *  or property in a collection view.
 *
 *  The SortField class is meant to be used with the Sort class.
 *
 *  Typically the sort is defined for collections of complex items, that is
 *  items in which the sort is performed on properties of those objects.
 *  As in the following example:
 *
 *  <pre><code>
 *     var col:ICollectionView = new ArrayCollection();
 *     col.addItem({first:"Anders", last:"Dickerson"});
 *     var sort:Sort = new Sort();
 *     sort.fields = [new SortField("first", true)];
 *     col.sort = sort;
 *  </code></pre>
 *
 *  There are situations in which the collection contains simple items, like
 *  <code>String</code>, <code>Date</code>, <code>Boolean</code>, etc.
 *  In this case, sorting should be applied to the simple type directly.
 *  When constructing a sort for this situation only a single sort field is
 *  required and should not have a <code>name</code> specified.
 *  For example:
 *
 *  <pre><code>
 *     var col:ICollectionView = new ArrayCollection();
 *     col.addItem("California");
 *     col.addItem("Arizona");
 *     var sort:Sort = new Sort();
 *     sort.fields = [new SortField(null, true)];
 *     col.sort = sort;
 *  </code></pre>
 *
 *  <p>By default the comparison provided by the SortField class does
 *  not provide correct language specific
 *  sorting for strings.  For this type of sorting please see the
 *  <code>spark.collections.Sort</code> and
 *  <code>spark.collections.SortField</code> classes.</p>
 *
 *  @mxml
 *
 *  <p>The <code>&lt;mx:SortField&gt;</code> tag has the following attributes:</p>
 *
 *  <pre>
 *  &lt;mx:SortField
 *  <b>Properties</b>
 *  caseInsensitive="false"
 *  compareFunction="<em>Internal compare function</em>"
 *  descending="false"
 *  name="null"
 *  numeric="null"
 *  /&gt;
 *  </pre>
 *
 *  @see mx.collections.ICollectionView
 *  @see mx.collections.Sort
 *  @see spark.collections.Sort
 *  @see spark.collections.SortField

 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
public class SortField extends EventDispatcher implements ISortField
{
    include "../core/Version.as";

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

    /**
     *  Constructor.
     *
     *  @param name The name of the property that this field uses for
     *              comparison.
     *              If the object is a simple type, pass <code>null</code>.
     *  @param caseInsensitive When sorting strings, tells the comparator
     *              whether to ignore the case of the values.
     *  @param descending Tells the comparator whether to arrange items in
     *              descending order.
     *  @param numeric Tells the comparator whether to compare sort items as
     *              numbers, instead of alphabetically.
     *  @param sortCompareType Gives an indication to SortField which of the
     *              default compare functions to use.
     *  @param customCompareFunction Use a custom function to compare the
     *              objects based on this SortField.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function SortField(name:String = null,
                              caseInsensitive:Boolean = false,
                              descending:Boolean = false,
                              numeric:Object = null,
                              sortCompareType:String = null,
                              customCompareFunction:Function = null)
    {
        super();

        _name = name;
        _caseInsensitive = caseInsensitive;
        _descending = descending;
        _numeric = numeric;
        _sortCompareType = sortCompareType;

        if(customCompareFunction != null)
        {
            compareFunction = customCompareFunction;
        }
        else if (updateSortCompareType() == false)
        {
            _compareFunction = stringCompare;
        }
    }

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

    /**
     *  @private
     *  Used for accessing localized Error messages.
     */
    private var resourceManager:IResourceManager =
                                    ResourceManager.getInstance();

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

    //---------------------------------
    //  arraySortOnOptions
    //---------------------------------

    /**
    *  @inheritDoc
    *
    *  @langversion 3.0
    *  @playerversion Flash 9
    *  @playerversion AIR 1.1
    *  @productversion Flex 3
    */
    public function get arraySortOnOptions():int
    {
        if (usingCustomCompareFunction
            || name == null
            || _compareFunction == xmlCompare
            || _compareFunction == dateCompare)
        {
            return -1;
        }
        var options:int = 0;
        if (caseInsensitive) options |= Array.CASEINSENSITIVE;
        if (descending) options |= Array.DESCENDING;
        if (numeric == true || _compareFunction == numericCompare) options |= Array.NUMERIC;
        return options;
    }

    //---------------------------------
    //  caseInsensitive
    //---------------------------------

    /**
     *  @private
     *  Storage for the caseInsensitive property.
     */
    private var _caseInsensitive:Boolean;

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

    /**
     *  Specifies whether the sort for this field should be case insensitive.
     *
     *  @default false
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get caseInsensitive():Boolean
    {
        return _caseInsensitive;
    }

    /**
     *  @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
     *  argument instead.
     */
    mx_internal function setCaseInsensitive(value:Boolean):void
    {
        if (value != _caseInsensitive)
        {
            _caseInsensitive = value;
            dispatchEvent(new Event("caseInsensitiveChanged"));
        }
    }

    //---------------------------------
    //  compareFunction
    //---------------------------------

    /**
     *  @private
     *  Storage for the compareFunction property.
     */
    private var _compareFunction:Function;

    [Inspectable(category="General")]

    /**
     *  The function that compares two items during a sort of items for the
     *  associated collection. If you specify a <code>compareFunction</code>
     *  property in an <code>ISort</code> object, Flex ignores any
     *  <code>compareFunction</code> properties of the ISort's
     *  <code>SortField</code> objects.
     *
     *  <p>The compare function must have the following signature:</p>
     *
     *  <p><code>function myCompare(a:Object, b:Object):int</code></p>
     *
     *  <p>This function must return the following values:</p>
     *
     *   <ul>
     *        <li>-1, if the <code>Object a</code> should appear before the
     *        <code>Object b</code> in the sorted sequence</li>
     *        <li>0, if the <code>Object a</code> equals the
     *        <code>Object b</code></li>
     *        <li>1, if the <code>Object a</code> should appear after the
     *        <code>Object b</code> in the sorted sequence</li>
     *  </ul>
     *
     *  <p>The default value is an internal compare function that can perform
     *  a string, numeric, or date comparison in ascending or descending order,
     *  with case-sensitive or case-insensitive string comparisons.
     *  Specify your own function only if you need a need a custom comparison
     *  algorithm. This is normally only the case if a calculated field is
     *  used in a display.</p>
     *
     *  Note if you need language-specific sorting then consider using the
     *  <code>spark.collections.SortField</code> class.
     *
     *  @see spark.collections.SortField
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get compareFunction():Function
    {
        return _compareFunction;
    }

    /**
     *  @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
     *  argument instead.
     */
    public function set compareFunction(c:Function):void
    {
        _compareFunction = c;
        _usingCustomCompareFunction = (c != null);
    }

    //---------------------------------
    //  descending
    //---------------------------------

    /**
     *  @private
     *  Storage for the descending property.
     */
    private var _descending:Boolean;

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

    /**
     *  @inheritDoc
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get descending():Boolean
    {
        return _descending;
    }

    /**
     *  @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
     *  argument instead.
     */
    public function set descending(value:Boolean):void
    {
        if (_descending != value)
        {
            _descending = value;
            dispatchEvent(new Event("descendingChanged"));
        }
    }

    //---------------------------------
    //  name
    //---------------------------------

    /**
     *  @private
     *  Storage for the name property.
     */
    private var _name:String;

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

    /**
     *  @inheritDoc
     *
     *  @default null
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get name():String
    {
        return _name;
    }

    /**
     *  @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
     *  argument instead.
     */
    public function set name(n:String):void
    {
        _name = n;
        dispatchEvent(new Event("nameChanged"));
    }

    //---------------------------------
    //  numeric
    //---------------------------------

    /**
     *  @private
     *  Storage for the numeric property.
     */
    private var _numeric:Object;

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

    /**
     *  @inheritDoc
     *
     *  @default null
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get numeric():Object
    {
        return _numeric;
    }

    /**
     *  @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
     *  argument instead.
     */
    public function set numeric(value:Object):void
    {
        if (_numeric != value)
        {
            _numeric = value;
            dispatchEvent(new Event("numericChanged"));
        }
    }


    //---------------------------------
    //  sortCompareType
    //---------------------------------

    /**
     *  @private
     */
    private var _sortCompareType:String = null;

    /**
     *  @inheritDoc
     *
     *  @langversion 3.0
     *  @playerversion Flash 11.8
     *  @playerversion AIR 3.8
     *  @productversion Flex 4.11
     */
    [Bindable("sortCompareTypeChanged")]
    public function get sortCompareType():String
    {
        return _sortCompareType;
    }

    /**
     *  @deprecated A future release of Apache Flex SDK will remove this function. Please use the constructor
     *  argument instead.
     */
    public function set sortCompareType(value:String):void
    {
        if (_sortCompareType != value)
        {
            _sortCompareType = value;
            dispatchEvent(new Event("sortCompareTypeChanged"));
        }

        updateSortCompareType();
    }


    //---------------------------------
    //  usingCustomCompareFunction
    //---------------------------------

    private var _usingCustomCompareFunction:Boolean;

    /**
     *  @inheritDoc
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get usingCustomCompareFunction():Boolean
    {
        return _usingCustomCompareFunction;
    }

    //--------------------------------------------------------------------------
    //
    //  Overridden Methods
    //
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  A pretty printer for SortField that lists the sort fields and their
     *  options.
     */
    override public function toString():String
    {
        return ObjectUtil.toString(this);
    }

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

    /**
     *  @inheritDoc
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function initializeDefaultCompareFunction(obj:Object):void
    {
        // if the compare function is not already set then we can set it
        if (!usingCustomCompareFunction)
        {
            if (_sortCompareType)
            {
                //Attempt to set the compare function based on the sortCompareType
                if (updateSortCompareType() == true)
                {
                    return;
                }
            }

            if (numeric == true)
                _compareFunction = numericCompare;
            else if (caseInsensitive || numeric == false)
                _compareFunction = stringCompare;
            else
            {
                // we need to introspect the data a little bit
                var value:Object;
                if (_name)
                {
                    value = getSortFieldValue(obj);
                }
                //this needs to be an == null check because !value will return true
                //where value == 0 or value == false
                if (value == null)
                {
                    value = obj;
                }

                var typ:String = typeof(value);
                switch (typ)
                {
                    case "string":
                        _compareFunction = stringCompare;
                    break;
                    case "object":
                        if (value is Date)
                        {
                            _compareFunction = dateCompare;
                        }
                        else
                        {
                            _compareFunction = stringCompare;
                            var test:String;
                            try
                            {
                                test = value.toString();
                            }
                            catch(error2:Error)
                            {
                            }
                            if (!test || test == "[object Object]")
                            {
                                _compareFunction = nullCompare;
                            }
                        }
                    break;
                    case "xml":
                        _compareFunction = xmlCompare;
                    break;
                    case "boolean":
                    case "number":
                        _compareFunction = numericCompare;
                    break;
                }
            }  // else
        } // if
    }

    /**
     *  @inheritDoc
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function reverse():void
    {
        descending = !descending;
    }


    /**
     *  @inheritDoc
     *
     *  @langversion 3.0
     *  @playerversion Flash 11.8
     *  @playerversion AIR 3.8
     *  @productversion Flex 4.11
     */
    public function updateSortCompareType():Boolean
    {
        if (!_sortCompareType)
        {
            return false;
        }


        //Lookup the sortCompareType by its SortFieldCompareTypes value and set the associated compare method.
        switch(_sortCompareType)
        {
            case SortFieldCompareTypes.DATE:
            {
                _compareFunction = dateCompare;

                return true;
            }

            case SortFieldCompareTypes.NULL:
            {
                _compareFunction = nullCompare;

                return true;
            }

            case SortFieldCompareTypes.NUMERIC:
            {
                _compareFunction = numericCompare;

                return true;
            }

            case SortFieldCompareTypes.STRING:
            {
                _compareFunction = stringCompare;

                return true;
            }

            case SortFieldCompareTypes.XML:
            {
                _compareFunction = xmlCompare;

                return true;
            }
        }


        return false;
    }


    public function objectHasSortField(object:Object):Boolean
    {
        return getSortFieldValue(object) !== undefined;
    }


    //--------------------------------------------------------------------------
    //
    //  Protected Methods
    //
    //--------------------------------------------------------------------------

    protected function getSortFieldValue(obj:Object):*
    {
        var result:* = undefined;

        try
        {
            result = obj[_name];
        }
        catch(error:Error)
        {
        }

        return result;
    }

    //--------------------------------------------------------------------------
    //
    //  Private Methods
    //
    //--------------------------------------------------------------------------

    private function nullCompare(a:Object, b:Object):int
    {
        var left:Object;
        var right:Object;

        var found:Boolean = false;

        // return 0 (ie equal) if both are null
        if (a == null && b == null)
        {
            return 0;
        }

        // we need to introspect the data a little bit
        if (_name)
        {
            left = getSortFieldValue(a);
            right = getSortFieldValue(b);
        }

        // return 0 (ie equal) if both are null
        if (left == null && right == null)
            return 0;

        if (left == null && !_name)
            left = a;

        if (right == null && !_name)
            right = b;


        var typeLeft:String = typeof(left);
        var typeRight:String = typeof(right);


        if (typeLeft == "string" || typeRight == "string")
        {
                found = true;
                _compareFunction = stringCompare;
        }
        else if (typeLeft == "object" || typeRight == "object")
        {
            if (left is Date || right is Date)
            {
                found = true;
                _compareFunction = dateCompare;
            }
        }
        else if (typeLeft == "xml" || typeRight == "xml")
        {
                found = true;
                _compareFunction = xmlCompare;
        }
        else if (typeLeft == "number" || typeRight == "number"
                 || typeLeft == "boolean" || typeRight == "boolean")
        {
                found = true;
                _compareFunction = numericCompare;
        }

        if (found)
        {
            return _compareFunction(left, right);
        }
        else
        {
            var message:String = resourceManager.getString(
                "collections", "noComparatorSortField", [ name ]);
            throw new SortError(message);
        }
    }

    /**
     *  Pull the numbers from the objects and call the implementation.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    private function numericCompare(a:Object, b:Object):int
    {
        var fa:Number = _name == null ? Number(a) : Number(getSortFieldValue(a));
        var fb:Number = _name == null ? Number(b) : Number(getSortFieldValue(b));

        return ObjectUtil.numericCompare(fa, fb);
    }

    /**
     *  Pull the date objects from the values and compare them.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    private function dateCompare(a:Object, b:Object):int
    {
        var fa:Date = _name == null ? a as Date : getSortFieldValue(a) as Date;
        var fb:Date = _name == null ? b as Date : getSortFieldValue(b) as Date;

        return ObjectUtil.dateCompare(fa, fb);
    }

    /**
     *  Pull the strings from the objects and call the implementation.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function stringCompare(a:Object, b:Object):int
    {
        var fa:String = _name == null ? String(a) : String(getSortFieldValue(a));
        var fb:String = _name == null ? String(b) : String(getSortFieldValue(b));

        return ObjectUtil.stringCompare(fa, fb, _caseInsensitive);
    }

    /**
     *  Pull the values out fo the XML object, then compare
     *  using the string or numeric comparator depending
     *  on the numeric flag.
     *
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function xmlCompare(a:Object, b:Object):int
    {
        var sa:String = _name == null ? a.toString() : getSortFieldValue(a).toString();
        var sb:String = _name == null ? b.toString() : getSortFieldValue(b).toString();

        if (numeric == true)
        {
            return ObjectUtil.numericCompare(parseFloat(sa), parseFloat(sb));
        }
        else
        {
            return ObjectUtil.stringCompare(sa, sb, _caseInsensitive);
        }
    }
}
}
