////////////////////////////////////////////////////////////////////////////////
//
//  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.EventDispatcher;
import flash.events.IEventDispatcher;
import flash.system.ApplicationDomain;
import flash.utils.IDataInput;
import flash.utils.IDataOutput;
import flash.utils.IExternalizable;
import flash.utils.getQualifiedClassName;

import mx.core.IPropertyChangeNotifier;
import mx.events.CollectionEvent;
import mx.events.CollectionEventKind;
import mx.events.PropertyChangeEvent;
import mx.events.PropertyChangeEventKind;
import mx.resources.IResourceManager;
import mx.resources.ResourceManager;
import mx.utils.ArrayUtil;
import mx.utils.UIDUtil;

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

/**
 *  Dispatched when the IList has been updated in some way.
 *  
 *  @eventType mx.events.CollectionEvent.COLLECTION_CHANGE
 *  
 *  @langversion 3.0
 *  @playerversion Flash 9
 *  @playerversion AIR 1.1
 *  @productversion Flex 3
 */
[Event(name="collectionChange", type="mx.events.CollectionEvent")]

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

[RemoteClass(alias="flex.messaging.io.ArrayList")]

[ResourceBundle("collections")]

[DefaultProperty("source")]

/**
 *  The ArrayList class is a simple implementation of IList 
 *  that uses a backing Array as the source of the data. 
 * 
 *  Items in the backing Array can be accessed and manipulated 
 *  using the methods and properties of the <code>IList</code>
 *  interface. Operations on an ArrayList instance modify the 
 *  data source; for example, if you use the <code>removeItemAt()</code> 
 *  method on an ArrayList, you remove the item from the underlying 
 *  Array.
 * 
 *  This base class will not throw ItemPendingErrors but it
 *  is possible that a subclass might.
 * 
 *  <pre>
 *  &lt;mx:ArrayList
 *  <b>Properties</b>
 *  source="null"
 *  /&gt;
 *  </pre>
 * 
 *  @langversion 3.0
 *  @playerversion Flash 10
 *  @playerversion AIR 1.5
 *  @productversion Flex 4
 */
public class ArrayList extends EventDispatcher
       implements IList, IExternalizable, IPropertyChangeNotifier
{
    include "../core/Version.as";

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

    /**
     *  Construct a new ArrayList using the specified array as its source.
     *  If no source is specified an empty array will be used.
     * 
     *  @param source The Array to use as a source for the ArrayList.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function ArrayList(source:Array = null)
    {
        super();

        disableEvents();
        this.source = source;
        enableEvents();
    }
    
    //--------------------------------------------------------------------------
    //
    // Variables
    // 
    //--------------------------------------------------------------------------

    /**
     *  @private
     *  Used for accessing localized Error messages.
     */
    private var resourceManager:IResourceManager =
        ResourceManager.getInstance();
                                    
    /**
     *  @private 
     *  Indicates if events should be dispatched.
     *  calls to enableEvents() and disableEvents() effect the value when == 0
     *  events should be dispatched. 
     */
    private var _dispatchEvents:int = 0;

    //--------------------------------------------------------------------------
    //
    // Properties
    // 
    //--------------------------------------------------------------------------
    
    //----------------------------------
    // length
    //----------------------------------
    
    [Bindable("collectionChange")]
    
    /**
     *  Get the number of items in the list.  An ArrayList should always
     *  know its length so it shouldn't return -1, though a subclass may 
     *  override that behavior.
     *
     *  @return int representing the length of the source.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get length():int
    {
        if (source)
            return source.length;
        else
            return 0;
    }
    
    //----------------------------------
    // source
    //----------------------------------
    
    /**
     *  @private
     *  Storage for the source Array.
     */
    private var _source:Array;
    
    /**
     *  The source array for this ArrayList.  
     *  Any changes done through the IList interface will be reflected in the 
     *  source array.  
     *  If no source array was supplied the ArrayList will create one internally.
     *  Changes made directly to the underlying Array (e.g., calling 
     *  <code>theList.source.pop()</code> will not cause <code>CollectionEvents</code> 
     *  to be dispatched.
     *
     *  @return An Array that represents the underlying source.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function get source():Array
    {
        return _source;
    }
    
    public function set source(s:Array):void
    {
        var i:int;
        var len:int;
        if (_source && _source.length)
        {
            len = _source.length;
            for (i = 0; i < len; i++)
            {
                stopTrackUpdates(_source[i]);
            }
        }
        _source  = s ? s : [];
        len = _source.length;
        for (i = 0; i < len; i++)
        {
            startTrackUpdates(_source[i]);
        }
        
        if (_dispatchEvents == 0)
        {
           var event:CollectionEvent =
            new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
           event.kind = CollectionEventKind.RESET;
           dispatchEvent(event);
        }
    }
    
    //----------------------------------
    // uid -- mx.core.IPropertyChangeNotifier
    //----------------------------------
    
    /**
     *  @private
     *  Storage for the UID String. 
     */
    private var _uid:String;
    
    /**
     *  Provides access to the unique id for this list.
     *  
     *  @return String representing the internal uid. 
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */  
    public function get uid():String
    {
		if (!_uid) {
			_uid = UIDUtil.createUID();
		}
        return _uid;
    }
    
    public function set uid(value:String):void
    {
        _uid = value;
    }

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

	/**
	 *  Converts an Array List to JavaScript Object Notation (JSON) format.
	 * 	Called by the JSON.stringify() method and should not be called directly.
	 *  
	 *  @langversion 3.0
	 *  @playerversion Flash 11
	 *  @playerversion AIR 3.0
	 *  @productversion Apache Flex 4.12
	 */
	public function toJSON(s:String):*
	{
		return toArray();
	}
	
    /**
     *  Get the item at the specified index.
     * 
     *  @param  index the index in the list from which to retrieve the item
     *  @param  prefetch int indicating both the direction and amount of items
     *          to fetch during the request should the item not be local.
     *  @return the item at that index, null if there is none
     *  @throws ItemPendingError if the data for that index needs to be 
     *                           loaded from a remote location
     *  @throws RangeError if the index &lt; 0 or index &gt;= length
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getItemAt(index:int, prefetch:int = 0):Object
    {
        if (index < 0 || index >= length)
        {
            var message:String = resourceManager.getString(
                "collections", "outOfBounds", [ index ]);
            throw new RangeError(message);
        }
            
        return source[index];
    }
    
    /**
     *  Place the item at the specified index.  
     *  If an item was already at that index the new item will replace it and it 
     *  will be returned.
     *
     *  @param  item the new value for the index
     *  @param  index the index at which to place the item
     *  @return the item that was replaced, null if none
     *  @throws RangeError if index is less than 0 or greater than or equal to length
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function setItemAt(item:Object, index:int):Object
    {
        if (index < 0 || index >= length) 
        {
            var message:String = resourceManager.getString(
                "collections", "outOfBounds", [ index ]);
            throw new RangeError(message);
        }
        
        var oldItem:Object = source[index];
        source[index] = item;
        stopTrackUpdates(oldItem);
        startTrackUpdates(item);
        
        //dispatch the appropriate events 
        if (_dispatchEvents == 0)
        {
            var hasCollectionListener:Boolean = 
                hasEventListener(CollectionEvent.COLLECTION_CHANGE);
            var hasPropertyListener:Boolean = 
                hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE);
            var updateInfo:PropertyChangeEvent; 
            
            if (hasCollectionListener || hasPropertyListener)
            {
                updateInfo = new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
                updateInfo.kind = PropertyChangeEventKind.UPDATE;
                updateInfo.oldValue = oldItem;
                updateInfo.newValue = item;
                updateInfo.property = index;
            }
            
            if (hasCollectionListener)
            {
                var event:CollectionEvent =
                    new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
                event.kind = CollectionEventKind.REPLACE;
                event.location = index;
                event.items.push(updateInfo);
                dispatchEvent(event);
            }
            
            if (hasPropertyListener)
            {
                dispatchEvent(updateInfo);
            }
        }
        return oldItem;    
    }
    
    /**
     *  Add the specified item to the end of the list.
     *  Equivalent to addItemAt(item, length);
     * 
     *  @param item the item to add
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function addItem(item:Object):void
    {
        addItemAt(item, length);
    }
    
    /**
     *  Add the item at the specified index.  
     *  Any item that was after this index is moved out by one.  
     * 
     *  @param item the item to place at the index
     *  @param index the index at which to place the item
     *  @throws RangeError if index is less than 0 or greater than the length
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function addItemAt(item:Object, index:int):void
    {
        const spliceUpperBound:int = length;

        if (index < spliceUpperBound && index > 0)
        {
            source.splice(index, 0, item);
        }
        else if (index == spliceUpperBound)
        {
            source.push(item);
        }
        else if (index == 0)
        {
            source.unshift(item);
        }
        else
        {
            var message:String = resourceManager.getString(
                "collections", "outOfBounds", [ index ]);
            throw new RangeError(message);
        }

        startTrackUpdates(item);
        internalDispatchEvent(CollectionEventKind.ADD, item, index);
    }
    
    /**
     *  @copy mx.collections.ListCollectionView#addAll()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function addAll(addList:IList):void
    {
        addAllAt(addList, length);
    }
    
    /**
     *  @copy mx.collections.ListCollectionView#addAllAt()
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function addAllAt(addList:IList, index:int):void
    {
        const addListLength:int = addList.length;
        if (addListLength == 0)
            return;

        const addedItems:Array = [];
        
        disableEvents();
        for (var i:int = 0; i < addListLength; i++)
        {
            var item:Object = addList.getItemAt(i);
            this.addItemAt(item, i + index);
            addedItems.push(item);
        }
        enableEvents();
        
        if (_dispatchEvents == 0)
        {
            const event:CollectionEvent = new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
            event.kind = CollectionEventKind.ADD;
            event.location = index;
            event.items = addedItems;
            dispatchEvent(event);
        }
    }
    
    /**
     *  Return the index of the item if it is in the list such that
     *  getItemAt(index) == item.  
     *  Note that in this implementation the search is linear and is therefore 
     *  O(n).
     * 
     *  @param item the item to find
     *  @return the index of the item, -1 if the item is not in the list.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function getItemIndex(item:Object):int
    {
        return ArrayUtil.getItemIndex(item, source);
    }
    
    /**
     *  Removes the specified item from this list, should it exist.
     *
     *  @param  item Object reference to the item that should be removed.
     *  @return Boolean indicating if the item was removed.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function removeItem(item:Object):Boolean
    {
        var index:int = getItemIndex(item);
        var result:Boolean = index >= 0;
        if (result)
            removeItemAt(index);

        return result;
    }
    
    /**
     *  Remove the item at the specified index and return it.  
     *  Any items that were after this index are now one index earlier.
     *
     *  @param index The index from which to remove the item.
     *  @return The item that was removed.
     *  @throws RangeError if index &lt; 0 or index &gt;= length.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function removeItemAt(index:int):Object
    {
        const spliceUpperBound:int = length - 1;
        var removed:Object;

        if (index > 0 && index < spliceUpperBound)
        {
            removed = source.splice(index, 1)[0];
        }
        else if (index == spliceUpperBound)
        {
            removed = source.pop();
        }
        else if (index == 0)
        {
            removed = source.shift();
        }
        else
        {
            var message:String = resourceManager.getString(
                "collections", "outOfBounds", [ index ]);
            throw new RangeError(message);
        }

        stopTrackUpdates(removed);
        internalDispatchEvent(CollectionEventKind.REMOVE, removed, index);
        return removed;
    }
    
    /** 
     *  Remove all items from the list.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    public function removeAll():void
    {
        if (length > 0)
        {
            var len:int = length;
            for (var i:int = 0; i < len; i++)
            {
                stopTrackUpdates(source[i]);
            }

            source.splice(0, length);
            internalDispatchEvent(CollectionEventKind.RESET);
        }    
    }
    
    /**
     *  Notify the view that an item has been updated.  
     *  This is useful if the contents of the view do not implement 
     *  <code>IEventDispatcher</code>.  
     *  If a property is specified the view may be able to optimize its 
     *  notification mechanism.
     *  Otherwise it may choose to simply refresh the whole view.
     *
     *  @param item The item within the view that was updated.
     *
     *  @param property A String, QName, or int
     *  specifying the property that was updated.
     *
     *  @param oldValue The old value of that property.
     *  (If property was null, this can be the old value of the item.)
     *
     *  @param newValue The new value of that property.
     *  (If property was null, there's no need to specify this
     *  as the item is assumed to be the new value.)
     *
     *  @see mx.events.CollectionEvent
     *  @see mx.core.IPropertyChangeNotifier
     *  @see mx.events.PropertyChangeEvent
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
     public function itemUpdated(item:Object, property:Object = null, 
                                 oldValue:Object = null, 
                                 newValue:Object = null):void
    {
        var event:PropertyChangeEvent =
            new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
        
        event.kind = PropertyChangeEventKind.UPDATE;
        event.source = item;
        event.property = property;
        event.oldValue = oldValue;
        event.newValue = newValue;
        
        if(!property)
        {
            stopTrackUpdates(oldValue);
            startTrackUpdates(newValue);
        }

        itemUpdateHandler(event);
    }    
    
    /**
     *  Return an Array that is populated in the same order as the IList
     *  implementation.  
     *
     *  @return An Array populated in the same order as the IList
     *  implementation.
     * 
     *  @throws ItemPendingError if the data is not yet completely loaded
     *  from a remote location
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */ 
    public function toArray():Array
    {
        return source.concat();
    }
    
    /**
     *  Ensures that only the source property is seralized.
     *  @private
     */
    public function readExternal(input:IDataInput):void
    {
        source = input.readObject();
    }
    
    /**
     *  Ensures that only the source property is serialized.
     *  @private
     */
    public function writeExternal(output:IDataOutput):void
    {
        output.writeObject(_source);
    }

    /**
     *  Pretty prints the contents of this ArrayList to a string and returns it.
     *
     *  @return A String containing the contents of the ArrayList.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    override public function toString():String
    {
        if (source)
            return source.toString();
        else
            return getQualifiedClassName(this); 
    }   
    
    //--------------------------------------------------------------------------
    //
    // Internal Methods
    // 
    //--------------------------------------------------------------------------

    /**
     *  Enables event dispatch for this list.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    private function enableEvents():void
    {
        _dispatchEvents++;
        if (_dispatchEvents > 0)
            _dispatchEvents = 0;
    }
    
    /**
     *  Disables event dispatch for this list.
     *  To re-enable events call enableEvents(), enableEvents() must be called
     *  a matching number of times as disableEvents().
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    private function disableEvents():void
    {
        _dispatchEvents--;
    }
    
    /**
     *  Dispatches a collection event with the specified information.
     *
     *  @param kind String indicates what the kind property of the event should be
     *  @param item Object reference to the item that was added or removed
     *  @param location int indicating where in the source the item was added.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    private function internalDispatchEvent(kind:String, item:Object = null, location:int = -1):void
    {
        if (_dispatchEvents == 0)
        {
            if (hasEventListener(CollectionEvent.COLLECTION_CHANGE))
            {
                var event:CollectionEvent =
                    new CollectionEvent(CollectionEvent.COLLECTION_CHANGE);
                event.kind = kind;
				if(kind != CollectionEventKind.RESET && kind != CollectionEventKind.REFRESH)
				    event.items.push(item);
                event.location = location;
                dispatchEvent(event);
            }

            // now dispatch a complementary PropertyChangeEvent
            if (hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE) && 
               (kind == CollectionEventKind.ADD || kind == CollectionEventKind.REMOVE))
            {
                var objEvent:PropertyChangeEvent =
                    new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE);
                objEvent.property = location;
                if (kind == CollectionEventKind.ADD)
                    objEvent.newValue = item;
                else
                    objEvent.oldValue = item;
                dispatchEvent(objEvent);
            }
        }
    }
    
    /**
     *  Called when any of the contained items in the list dispatches a
     *  <code>PropertyChangeEvent</code>.
     *  Wraps it in a <code>CollectionEventKind.UPDATE</code> object.
     *
     *  @param event The event object for the <code>PropertyChangeEvent</code>.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */    
    protected function itemUpdateHandler(event:PropertyChangeEvent):void
    {
        internalDispatchEvent(CollectionEventKind.UPDATE, event);
        // need to dispatch object event now
        if (_dispatchEvents == 0 && hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
        {
            var objEvent:PropertyChangeEvent = PropertyChangeEvent(event.clone());
            var index:uint = getItemIndex(event.target);
            objEvent.property = index.toString() + "." + event.property;
            dispatchEvent(objEvent);
        }
    }
    
    /** 
     *  If the item is an IEventDispatcher, watch it for updates.  
     *  This method is called by the <code>addItemAt()</code> method, 
     *  and when the source is initially assigned.
     *
     *  @param item The item passed to the <code>addItemAt()</code> method.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function startTrackUpdates(item:Object):void
    {
        if (item && (item is IEventDispatcher))
        {
            IEventDispatcher(item).addEventListener(
                                        PropertyChangeEvent.PROPERTY_CHANGE, 
                                        itemUpdateHandler, false, 0, true);
        }
    }
    
    /** 
     *  If the item is an IEventDispatcher, stop watching it for updates.
     *  This method is called by the <code>removeItemAt()</code> and 
     *  <code>removeAll()</code> methods, and before a new
     *  source is assigned.
     *
     *  @param item The item passed to the <code>removeItemAt()</code> method.
     *  
     *  @langversion 3.0
     *  @playerversion Flash 9
     *  @playerversion AIR 1.1
     *  @productversion Flex 3
     */
    protected function stopTrackUpdates(item:Object):void
    {
        if (item && item is IEventDispatcher)
        {
            IEventDispatcher(item).removeEventListener(
                                        PropertyChangeEvent.PROPERTY_CHANGE, 
                                        itemUpdateHandler);    
        }
    }
    
}

}
