/**
 * Gallery - a web based photo album viewer and editor
 * Copyright (C) 2000-2010 Bharat Mediratta
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA  02110-1301, USA.
 */
package org.gallery3.rest {
	import mx.collections.ArrayCollection;
	import mx.collections.IList;
	import mx.collections.Sort;
	import mx.collections.SortField;
	
	[Bindable]
	// @todo don't automatically load the children just when selected
	public class GalleryAlbum extends GalleryItem implements IList {
		private var _albums:ArrayCollection = new ArrayCollection();
		
		public function GalleryAlbum(item:Object=null) {
			super(item);
			_albums.sort = new Sort();
			_albums.sort.fields = [new SortField("title")];
		}		

		[Bindable(event="childrenChanged")]
		public override function get children():ArrayCollection {
			if (!_childrenLoaded && _members.length > 0) {
				loadChildren();
			}
			return _children;
		}
		
		//[Bindable(event="labelChanged")]
		public override function get label(): String {
			return title + " (" + _members.length + ")";
		}

		[Bindable(event="albumsChanged")]
		public function get albums(): ArrayCollection {
			if (!_childrenLoaded && _members.length > 0) {
				loadChildren();
				dispatchEvent(new Event("albumsChanged"));
			}
			return _albums;
		}

		public function insert(at:int, items: Vector.<Object>): void {
			_members.removeAll()
//			var newMembers: ArrayCollection = new ArrayCollection();
//			var newChildren: ArrayCollection = new ArrayCollection();
//			var updatedWeight: int = 0;
			for (var idx:int = 0; idx < at; idx++) {
				var child: GalleryItem = _children[idx] as GalleryItem;
				if (items.indexOf(child) == -1) {
					_members.addItem(child.url);
				}
			}
			for (idx = 0; idx < items.length; idx++) {
				child = items[idx] as GalleryItem;
				_members.addItem(child.url);
			}
			for (idx = at; idx < _children.length; idx++) {
				child = _children[idx] as GalleryItem;
				if (items.indexOf(child) == -1) {
					_members.addItem(child.url);
				}
			}
			_dirty.push("children");
			sortColumn = "weight";
			sortOrder = "ASC";
		}
		
		public function loadChildren(items:Object=null):void {
			if (!isLoading) {
				isLoading = true;
				
				try {
				if (items == null) {
					if (_members.length > 0) {
						var params:Object = {"url": _members.source};
						
						Rest.factory()
							.uri("items/" + id )
							.onLoad(function(items: Object): void {
								try {
								_updateCollections(items);
								} catch (e: Error) {
									trace(e);
								}
							})
							.load(params);
					} else {
						_updateCollections(null);
					}
				} else {
					_updateCollections(items);
				}
				} catch (e: Error) {
					trace(e);
				}
	  		}
		}
		
		private function _updateCollections(items:Object):void {
			_children.removeAll();
			for each (var element:Object in items) {
				_children.addItem(element);
			}
			dispatchEvent(new Event("childrenChanged"));
			
			_albums.removeAll();
			for each (var child:GalleryItem in _children) {
				if (child.type == "album") {
					_albums.addItem(child);
				}
			}
			_albums.refresh();
			dispatchEvent(new Event("albumsChanged"));
			
			isLoading = false;
			_childrenLoaded = true;
		}

		//--------------------------------------------------------------------------
		//  IList Interface Implementation
		//--------------------------------------------------------------------------
		/**
		 *  @see mx.collections.IList
		 */
		[Bindable("childrenChanged")]
		public function get length():int {
			return isLoading ? 0 : _children.length;
		}
			
		/**
		 *  @see mx.collections.IList
		 */
		public function addItem(item:Object):void {
			_members.addItem(item.url);
			if (_childrenLoaded) {
				_children.addItem(item);
				if (GalleryItem(item).type == "album") {
					_albums.addItem(item);
				}
				itemUpdated(item);
			}
			_dirty.push("children");
		}
			
		/**
		 *  @see mx.collections.IList
		 */
		public function addItemAt(item:Object, index:int):void {
			_members.addItemAt(item.url, index);
			if (_childrenLoaded) {
				_children.addItemAt(item, index);
				if (GalleryItem(item).type == "album") {
					_albums.addItem(item);
				}
				itemUpdated(item);
			}
			_dirty.push("children");
		}
			
		/**
		 *  @see mx.collections.IList
		 */
		[Bindable("childrenChanged")]
		public function getItemAt(index:int, prefetch:int = 0):Object {
			return _children.getItemAt(index, prefetch);
		}
			
		/**
		 *  @see mx.collections.IList
		 */
		public function getItemIndex(item:Object):int {
			return _children.getItemIndex(item);
		}
			
		/**
		 *  @see mx.collections.IList
		 */
		public function itemUpdated(item:Object, property:Object = null, 
							 oldValue:Object = null, 
							 newValue:Object = null):void {
			dispatchEvent(new Event("childrenChanged"));				
			if (GalleryItem(item).type == "album") {
				dispatchEvent(new Event("albumsChanged"));				
			}
		}
		
		/** 
		 *  @see mx.collections.IList
		 */
		public function removeAll():void {
			_members.removeAll();
			_children.removeAll();
			_albums.removeAll();
			dispatchEvent(new Event("childrenChanged"));				
			dispatchEvent(new Event("albumsChanged"));				
			_dirty.push("children");
		}
		
		/**
		 *  @see mx.collections.IList
		 */
		public function removeItemAt(index:int):Object {
			_members.removeItemAt(index);
			var o:GalleryItem = _children.removeItemAt(index) as GalleryItem;
			if (o.type == "album") {
				var idx:int = _albums.getItemIndex(o);
				_albums.removeItemAt(idx);
			}
			itemUpdated(o);
			_dirty.push("children");
			return o;
		}
		
		/**
		 *  @see mx.collections.IList
		 */
		public function setItemAt(item:Object, index:int):Object {
			_members.addItemAt(item.url, index);
			var o:GalleryItem = _children.setItemAt(item, index) as GalleryItem;
			if (GalleryItem(item).type == "album") {
				_albums.addItem(item);
			}
			
			itemUpdated(o);
			_dirty.push("children");
			return o;
		}
			
		/**
		 *  @see mx.collections.IList
		 */ 
		public function toArray():Array {
			return _children.toArray();
		}
	}
}