////////////////////////////////////////////////////////////////////////////////
//
//  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.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();
        _uid = UIDUtil.createUID();
    }
    
    //--------------------------------------------------------------------------
    //
    // 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
    {
        return _uid;
    }
    
    public function set uid(value:String):void
    {
        _uid = value;
    }

    //--------------------------------------------------------------------------
    //
    // Methods
    // 
    //--------------------------------------------------------------------------

    /**
     *  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
    {
        if (index < 0 || index > length) 
        {
            var message:String = resourceManager.getString(
                "collections", "outOfBounds", [ index ]);
            throw new RangeError(message);
        }
            
        source.splice(index, 0, item);

        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
    {
        var length:int = addList.length;
        for (var i:int = 0; i < length; i++)
        {
            this.addItemAt(addList.getItemAt(i), i+index);
        }
    }
    
    /**
     *  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
    {
        if (index < 0 || index >= length)
        {
            var message:String = resourceManager.getString(
                "collections", "outOfBounds", [ index ]);
            throw new RangeError(message);
        }

        var removed:Object = source.splice(index, 1)[0];
        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;

		//This handler was intended to handle events from child objects, not to be called directly
		//itemUpdateHandler(event);        

		internalDispatchEvent(CollectionEventKind.UPDATE, event);
		
		// need to dispatch object event now
		if (_dispatchEvents == 0 && hasEventListener(PropertyChangeEvent.PROPERTY_CHANGE))
		{
			dispatchPropertyChangeEventClone( event, item );
		}
    }    
    
    /**
     *  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
    // 
    //--------------------------------------------------------------------------

	/**
	 *  Dispatches a PropertyChangeEvent clone either from a child object whose event needs to be redispatched
	 *  or when a PropertyChangeEvent is faked inside of this class for the purposes of informing the view
	 *  of an update to underlying data.
	 *
	 *  @param event The PropertyChangeEvent to be cloned and dispatched
	 *  @param item The item within the view that was updated.
	 *
	 *  @see mx.core.IPropertyChangeNotifier
	 *  @see mx.events.PropertyChangeEvent
	 */
	
	private function dispatchPropertyChangeEventClone( event:PropertyChangeEvent, item:Object ):void {
		var objEvent:PropertyChangeEvent = PropertyChangeEvent(event.clone());
		
		var index:int = getItemIndex( item );
		objEvent.property = index.toString() + "." + event.property;
		dispatchEvent(objEvent);
	} 

    /**
     *  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;
                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 dispatch an
     *  ObjectChange event.  
     *  Wraps it in a <code>CollectionEventKind.UPDATE</code> object.
     *
     *  @param event The event object for the ObjectChange event.
     *  
     *  @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))
		{
			dispatchPropertyChangeEventClone( event, event.target );
		}
    }
    
    /** 
     *  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);    
        }
    }
    
}

}
