if(!$chk(HKM)) {
	var HKM = {};
}

/**
 * HKM.List
 *
 * @classDescription HKM.List
 */
HKM.List = new Class({

	/**
	 * Options
	 * 
	 * @type {Object}
	 */
	options: {                      
		allowMutipleSelection: false,
		clickWillToggle: false,
		
        onSelectedEntry: Class.empty,
        onDeselectedEntry: Class.empty
	},
	
	target: null,
	
	listData: null,
	
	currentSelectedItem: null,
	
	currentSelectedItems: [],
	
	listElement: null,
	
	controller: null,
	
	/**
	 * HKM.List Constructor
	 * 
	 * @param {Object} target
	 * @param {Object} options
	 */
	initialize: function(options) {
		this.setOptions(options);
		// Create new ul element
		// var self = new Element('ul');
		this.listElement = new Element('ul');
		this.listElement['controller'] = this;
		this.controller = this;
		// $extend(self, this);
		// return self;s
	},
	
	injectInside: function(target) {
		this.listElement.injectInside(target);
	},
	
	setData: function(listData) {
		
		this.listData = listData;
		this.currentSelectedItems = [];
		this.layout();
	},
	
	layout: function() {
		
		// Clear		
		// this.setHTML('');
		this.listElement.empty(); //setHTML('');
		
		
		for(var i=0;i<this.listData.length;i++) {

			var newEntry = new HKM.ListEntry(
											this.listData[i],
											{
												onSelectedItem: this.selectedItem.bindAsEventListener(this)
											});

			newEntry.injectInside(this.listElement);
		
		}
	},
	
	selectItemAtIndex: function(index, animate) {
		if($chk(this.listElement.getChildren()[index])) {
			this.selectedItem(this.listElement.getChildren()[index], animate);
		}
	},
	
	selectedItem: function(item, animate) {

		if($type(item) == 'element') {
			item = item.controller;
		}

		if(this.options.allowMutipleSelection === false && this.getSelectedItem() !== null) {
			var tmpSelectedItem = this.getSelectedItem();
			this.removeSelectedItem(tmpSelectedItem, animate);
			this.fireEvent('onDeselectedEntry', [this, tmpSelectedItem.listEntryElement]);
		}

		if(this.options.clickWillToggle === true && this.isSelectedItem(item) === true) {
			this.removeSelectedItem(item, animate);
			this.fireEvent('onDeselectedEntry', [this, item]);
		} else {
			this.addSelectedItem(item, animate);
			this.fireEvent('onSelectedEntry', [this, item]);
		}

	},
	 
	isSelectedItem: function(item) {
 	   for(var i=0;i<this.currentSelectedItems.length;i++) {
			if(this.currentSelectedItems[i] == item.listEntryElement) {
				return true;
			}
		}        
		return false;
	},
	
	addSelectedItem: function(item, animate) {


		for(var i=0;i<this.currentSelectedItems.length;i++) {			
			if((this.currentSelectedItems[i] == item)) {
				return;
			}
		}
		
		if($chk(item.selectItem)) {
			item.selectItem(animate);			
		} else {
			item.controller.selectItem(animate);
		}

		this.currentSelectedItems.push(item);

	},

	removeSelectedItem: function(item, animate) {
		var newItemList = [];
		if($type(item) == 'element') {
			item = item.controller;
		}
		for(var i=0;i<this.currentSelectedItems.length;i++) {

			if(this.currentSelectedItems[i].controller != item) {
				newItemList.push(this.currentSelectedItems[i]);
			} else {
				if(this.currentSelectedItems[i])
			   this.currentSelectedItems[i].controller.deselectItem(animate);
			}
		}
		this.currentSelectedItems = newItemList;
	},
	
	getItems: function() {
  		return this.listElement.getChildren();
	},
	
	getSelectedItem: function() {
		return (this.currentSelectedItems.length > 0) ?  this.currentSelectedItems[0] : null;
	},

	getSelectedItems: function() {
		return this.currentSelectedItems;
	},

	getKeys: function() {

		var retval = [];
		for(var i=0;i<this.listData.length;i++) {
			retval.push(this.listData[i].key);
		}
		return retval;
	},

	getSelectedKeys: function() {
		var retval = [];
		for(var i=0;i<this.getSelectedItems().length;i++) {
			retval.push(this.getSelectedItems()[i].controller.getKey().toString());
		}        
		return retval;
		
	},
	
	setSelectedKeys: function(selectedKeys) {
		this.currentSelectedItems = [];

		var items = this.getItems();
		for(var i=0;i<items.length;i++) {            
			if(selectedKeys.contains(items[i].controller.getKey().toString())) {
				this.addSelectedItem(items[i], false);
			} else if(items[i].controller.isSelected === true) {
				 items[i].controller.deselectItem(false);
			}
		}
	},
	
	disable: function() {
	  var items = this.getItems();
	  for(var i=0;i<items.length;i++) {
			items[i].controller.disable();
	  }
	  this.listElement.setStyles({'opacity': 0.5});
	},
	
	enable: function() {

	  var items = this.getItems();
	  for(var i=0;i<items.length;i++) {
			items[i].controller.enable();
	  } 
	  this.listElement.setStyles({'opacity': 1});
	}
	
});
HKM.List.implement(new Options);
HKM.List.implement(new Events);


/**
 * HKM.ListEntry
 *
 * @classDescription HKM.ListEntry
 */
HKM.ListEntry = new Class({

	/**
	 * Options
	 * 
	 * @type {Object}
	 */
	options: {
		baseColor: '#FFF',
		hoverColor: '#CCC',
		selectedColor: '#edeeef',
		selectedClass: 'selected',
		
		sublabelMaxChars: 10,
		sublabelSuffix: '...',
		
		// Events
		onSelectedItem: Class.empty
	},
	
	data: null,
	
	isSelected: false,
	
	listEntryElement: null,
	
	controller: null,
	
	/**
	 * HKM.ListEntry Constructor
	 * 
	 * @param {Object} data
	 * @param {Object} options
	 */
	initialize: function(data, options) {
		this.setOptions(options);
		
		this.data = data;
		
		// Create li
		// var self = new Element('li');
		this.listEntryElement = new Element('li');
		this.listEntryElement['controller'] = this;
		this.listEntryElement.addEvent('click', this.onclick.bindAsEventListener(this));
		// $extend(self, this);
		this.setUp();
		this.controller = this;
		// return self;
	},
	
	injectInside: function(target) {
		this.listEntryElement.injectInside(target);
	},
	
	getData: function() {
		return this.data;
	},
	
	setUp: function() {

	    var sublabel = new Element('span');
		sublabel.injectInside(this.listEntryElement);
		
	    var label = new Element('label');
		label.setText(this.data.displayName);
		label.injectInside(this.listEntryElement);

	},
	         
	selectItem: function(animate) {
		this.isSelected = true;
		this.listEntryElement.addClass(this.options.selectedClass);
		this.cancelItemFx();                      
		if(animate !== false) {
			this.itemFx = new Fx.Styles(this.listEntryElement, {duration:200});
			this.itemFx.start({'backgroundColor': [this.listEntryElement.getStyle('backgroundColor'), this.options.selectedColor]});
		} else {
			this.listEntryElement.setStyles({'backgroundColor': this.options.selectedColor});
		}
	},

	deselectItem: function(animate) {
		this.isSelected = false;
		this.listEntryElement.removeClass(this.options.selectedClass); 
		this.cancelItemFx(); 
		
		if(animate !== false) {
			this.itemFx = new Fx.Styles(this.listEntryElement, {duration:300});
			this.itemFx.start({'backgroundColor': [this.listEntryElement.getStyle('backgroundColor'), this.options.baseColor]});
		} else {
			this.listEntryElement.setStyles({'backgroundColor': this.options.baseColor});
		}
	},
	
	onclick: function() {
		if(this.enabled == true) {
			this.fireEvent('onSelectedItem', this);
		}
	},
	    
	itemFx: null,

	cancelItemFx: function() {
		if(this.itemFx != null) {
			if($chk(this.itemFx.cancel)) {
	   			this.itemFx.cancel();      
			}
			this.itemFx = null;
	   }
	},
	
	onmouseover: function(e) {

	},
	
	onmouseout: function(e) {

	},
	
	getKey: function() {
		return this.data.key;
	},
	
	getLabel: function() {
		return this.data.displayName;
	},
	
	setSubLabel: function(label) {

		var subLabelCandidates = $ES('span', this.listEntryElement);
		var displayLabel = label;
		if(subLabelCandidates.length > 0) {
			if(label.length > this.options.sublabelMaxChars) {
				displayLabel = '';
				displayLabel = label.substring(0, (this.options.sublabelMaxChars-this.options.sublabelSuffix.length));
				displayLabel += this.options.sublabelSuffix;
			}
			
			subLabelCandidates[0].setText(displayLabel)
		}
		
	},
	         
	enabled: true,
	
	enable: function() {
		this.enabled = true;
		this.listEntryElement.setStyle('cursor', 'pointer');
	},
	
	disable: function() {
		this.enabled = false;
		this.listEntryElement.setStyle('cursor', 'default');
	}
	

});
HKM.ListEntry.implement(new Options);
HKM.ListEntry.implement(new Events);

