var ItemSelector = (function(){
	//var myLogReader = new YAHOO.widget.LogReader();
	var Dom = YAHOO.util.Dom,
		Event = YAHOO.util.Event;

	function selectList(targetElem,cfg){
		this.targetElem 		= this.is_string(targetElem) ? Dom.get(targetElem) : targetElem;
		this.cfg 				= cfg;//{css:{selectedClass:'selected-pic'}};
		this.items 				= [];
	    this.selection 			= [];
		this.isLoaded 			= false;
		this.placeholderElem 	= null;
		this.hasSelection 		= new YAHOO.util.CustomEvent("hasSelection");
		this.noSelection 		= new YAHOO.util.CustomEvent("noSelection");
		this.noItems 			= new YAHOO.util.CustomEvent("noItems");
		this.lengthChanged 		= new YAHOO.util.CustomEvent("lengthChanged");
		this.itemDoubleClick	= new YAHOO.util.CustomEvent("itemDoubleClick");
		this.init();
	}
	
	selectList.prototype = {
		init: function(){
			// maybe if there were already li's in the ul I could sweep them up and make items
			var items = this.targetElem.getElementsByTagName('li');
			if(items.length){
				for (var i=0; i < items.length; i++) {
					this.initListElem(items[i]);
				};
			}	
			Event.on(this.targetElem,'click',this.clearSelection,this,true);
		},
		setPlaceHolder: function(liElem){
			if(!this.is_element(liElem,'li') || this.placeholderElem != null) return;
			this.targetElem.appendChild(liElem);
			this.isLoaded = true;
			this.placeholderElem = liElem;
		},
		loadListCollection: function(liCollection){ // where liCollection is an Array of LI elements
			if(liCollection.length){
				for (var i=0; i < liCollection.length; i++) {
					this.addListElem(liCollection[i],true);
				};
				this.isLoaded = true;
			}
		},
		initListElem: function(liElem){
			if(!this.is_element(liElem,'li')) return;
			var item = {elem:liElem,orderIndex:null,parentObj:this};
			Event.on(liElem,"dblclick",this.handleItemDblClick,item);
			Event.on(liElem,"click",this.handleItemClick,item);
			this.items.push(item);
			this.setOrder();
		},
		addListElem: function(liElem,last){ // where liElem is an LI element
			if(!this.is_element(liElem,'li')) return;
			if(this.placeholderElem){
				this.targetElem.removeChild(this.placeholderElem);
				this.placeholderElem = null; 
			}
			var item = {elem:liElem,orderIndex:null,parentObj:this};
			Event.on(liElem,"dblclick",this.handleItemDblClick,item);
			Event.on(liElem,"click",this.handleItemClick,item);
			if(last || this.items.length < 1){
				this.targetElem.appendChild(liElem);
				this.items.push(item);
			}else{
				Dom.insertBefore(liElem,this.items[0].elem);
				this.items.unshift(item);
			}
			this.lengthChanged.fire(this.items.length);
			this.setOrder();
			
		},
		removeListElem: function(item){
			this.doUnSelect(item);
			var idx = this.findItem(item);
	        if(idx >= 0){
	            this.items.splice(idx,1);
	        }
			this.lengthChanged.fire(this.items.length);
			this.setOrder();
			if(!this.selection.length){
				this.noSelection.fire();
			}
			if(!this.items.length){
				this.noItems.fire();
			}
		},
		handleItemClick: function(evt,item_Obj){
			Event.stopEvent(evt);
			if(evt.shiftKey){
				item_Obj.parentObj.getInterSelection(item_Obj);
			}else if(evt.ctrlKey || evt.metaKey){
				item_Obj.parentObj.toggleSelect(item_Obj);	
			}else{
		        if(!item_Obj.parentObj.isSelected(item_Obj)){
		            item_Obj.parentObj.clearSelection();
		            item_Obj.parentObj.toggleSelect(item_Obj);
		        }				
			}
		},
		handleItemDblClick: function(evt,item_Obj){
			Event.stopEvent(evt);  
			item_Obj.parentObj.itemDoubleClick.fire(item_Obj);
		    item_Obj.parentObj.clearSelection();
		},
		isSelected: function(item){
			return Dom.hasClass(item.elem,this.cfg.css.selectedClass);
		},
		toggleSelect: function(item){
			this.isSelected(item) ? this.doUnSelect(item) : this.doSelect(item);
		},
		doUnSelect: function(item){
			if(!this.selection.length) return;
			var idx = this.findSelectItem(item);
	        if(idx >= 0){
	            Dom.removeClass(this.selection[idx].elem,this.cfg.css.selectedClass);
	            this.selection.splice(idx,1);
	        }
	   		if(this.selection.length < 1){
				this.noSelection.fire();
			}
		},
		doSelect: function(item){
			Dom.addClass(item.elem,this.cfg.css.selectedClass); 
	        this.selection.push(item);
	        this.sorted();
			this.hasSelection.fire();
		},
		clearSelection: function(){
			//YAHOO.log('clearSelection');
			if(!this.selection.length) return;
			for (var i=this.selection.length - 1; i >= 0; i--) {
                Dom.removeClass(this.selection[i].elem,this.cfg.css.selectedClass);
                this.selection.splice(i,1);
            };
			this.noSelection.fire();
		},
		selectFromTo: function(from, to){
			for (var i=from; i <= to; i++) {
                this.doSelect(this.items[i]);
            };
		},
		getInterSelection: function(item){
			if(!this.selection.length){ this.doSelect(item); return; }
            var min = this.selection[0].orderIndex;
            var max = this.selection[this.selection.length-1].orderIndex;
            this.clearSelection();
            if(item.orderIndex > max){
                this.selectFromTo(min,item.orderIndex);
            }
            if(item.orderIndex < min){
                this.selectFromTo(item.orderIndex,max);
            }
            if(item.orderIndex >= min && item.orderIndex <= max){
                this.selectFromTo(min,item.orderIndex);
            }
		},
		sorted: function(){
			this.selection.sort(function(a,b){ return a.orderIndex - b.orderIndex; });
		},
		findItem: function(item){
			if(!this.items.length) return false;
			for(var i = 0; i < this.items.length; i++) {
	    		if(this.items[i] == item) {
	    			return i;
	    		}
	    	}			
		},
	    findSelectItem: function(item){
			if(!this.selection.length) return false;
			for(var i = 0; i < this.selection.length; i++) {
	    		if(this.selection[i] == item) {
	    			return i;
	    		}
	    	}
		},
		setOrder: function(){
			if(!this.items.length) return false;
			for (var i=0; i < this.items.length; i++) {
				this.items[i].orderIndex = i;
			};
		},
		is_string:function(input){
			return typeof(input)=='string';
		},
		is_element: function(el, tag) {
		    if (el && el.tagName && (el.tagName.toLowerCase() == tag)) {
		        return true;
		    }
		    if (el && el.getAttribute && (el.getAttribute('tag') == tag)) {
		        return true;
		    }
		    return false;
		}
	};
	return {selectList:selectList};
})();