(function(){
	// «Øºc¦¡
	var Select = function(el,attr){
		attr = attr || {};
		if(arguments.length == 1 && !YAHOO.lang.isString(el) && !el.nodeName){
			attr = el;
			el = el.element || null;
		};
		if(!el && !attr.element){
			el = document.body;
		};
		Select.superclass.constructor.call(this, el, attr);
		_init.call(this);
	};
	YAHOO.extend(Select,YAHOO.util.Element);
	var proto = Select.prototype;
	var $E = YAHOO.util.Event;
	var $D = YAHOO.util.Dom;
	proto._dragLayer = null;
	proto._startDrag = false;
	proto.selectAll = function(){}
	proto.deselectAll = function(){
		var items = this.get('selectedItems');
		$D.removeClass(items,this.get('selectedClassName'));
		for(var i=items.length-1;i>=0;i--){items.splice(i,1);};	
	};
	proto.toString = function(){
		var sName = this.get('id') || this.get('tagName');
		return 'YAHOO.ACE.util.Select ' + sName;
	};
	proto.initAttributes = function(oAttribute){
		this.constructor.superclass.initAttributes.call(this, oAttribute);
		this.setAttributeConfig('selectedItems',{
			value:[],
			validator:YAHOO.lang.isArray
		});
		this.setAttributeConfig('items',{
			value:oAttribute.items||[],
			validator:YAHOO.lang.isArray
		});
		this.setAttributeConfig('itemClassName',{
			value:oAttribute.itemClassName||'item'
		});
		this.setAttributeConfig('selectedClassName',{
			value:oAttribute.selectedClassName||'yui-selected'
		});
		this.setAttributeConfig('dragLayerClassName',{
			value:oAttribute.dragLayerClassName||'yui-select-layer',
			method:function(value){
				$D.replaceClass(this.get('dragLayerClassName'),value);
			}
		});
		this.setAttributeConfig('maxSelect',{
			value:oAttribute.maxSelect || null,
			validator:YAHOO.lang.isNumber
		});		
		this.setAttributeConfig('enableDrag',{
			value:oAttribute.enableDrag||false,
			method:function(value){
				if(value){
					if(!this.get('items').length){
						YAHOO.log('You must provide selectable items.');
						this.set('enableDrag',false);
						YAHOO.log(this.get('enableDrag').toString())
					};
				}
				else {
				
				
				}
			},
			validator:YAHOO.lang.isBoolean
		});
		this.setAttributeConfig('callback',{
			value:oAttribute.callback||function(){},
			validator:YAHOO.lang.isFunction
		});
	};
	var _hideLayer = function(){
        $D.setStyle(this._dragLayer,'display','none');
        $D.setStyle(this._dragLayer,'width','0');
        $D.setStyle(this._dragLayer,'height','0');
    };
    var _setSelected = function() {
		var items = this.get('selectedItems');
		if(items.length){$D.addClass(items,this.get('selectedClassName'));}
    };
	var _createDragLayer = function(){
		YAHOO.log('layer created');	
		var layerEl = document.createElement('div');
		document.body.appendChild(layerEl);
		$D.addClass(layerEl,this.get('dragLayerClassName'));
		return layerEl;
	};
	var _stopEvent = function(e){
		$E.stopEvent(e);
		return false;
	};
	var _init = function(){
		var self = this;
		var startX,startY,endX,endY;		
		var itemClick = function(e){
			var el = $E.getTarget(e);
			var className = self.get('itemClassName');
			var selected = self.get('selectedClassName');
			if(!$D.hasClass(el,className)){el = el.parentNode;};
			if(!$D.hasClass(el,className)){
				$E.stopEvent(e);
				return false;
			};
			if(!el.id){$D.generateId(el);};
			var items = self.get('selectedItems');
			if($D.hasClass(el,selected)){$D.removeClass(el,selected)};
			for(var i=0,j=items.length;i<j;i++){
				if(items[i].id == el.id){
					items.splice(i,1);
					self.set('selectedItems',items);
					var callback = self.get('callback');
					callback(items);
					$E.stopEvent(e);
					return false;
				};
			};
			if(self.get('selectedItems').length === self.get('maxSelect')){
				YAHOO.log('Select error: the maximum quantity of selection are ' + self.get('maxSelect') + ' items');
				$E.stopEvent(e);
				return false;
			};			
			$D.generateId(el);
			items[items.length] = el;
			self.set('selectedItems',items);
			$D.addClass(el,selected);
			var callback = self.get('callback');
			callback(items);
			$E.stopEvent(e);
			return false;
		};
		var startDrag = function(e){
			if(self.get('enableDrag')){
				if(!self._dragLayer){self._dragLayer = _createDragLayer.call(self);};
				$D.setStyle(self._dragLayer,'display','block');
				
				startX = $E.getPageX(e);
				startY = $E.getPageY(e);
				$D.setXY(self._dragLayer,[startX,startY]);
			};
			self._startDrag = true;
			//$E.stopEvent(e);
			//return false;
		};
		var dragMove = function(e){
			if(!self._startDrag){
				$E.stopEvent(e);
				return false;
			};
			if(!((e.button||e.which)&1)){
				endDrag();
				$E.stopEvent(e);
				return false;
			};
			$D.setStyle(self._dragLayer,'display','block');
			var endX = $E.getPageX(e);
			var endY = $E.getPageY(e);
			if(Math.abs(startX-endX)+Math.abs(startY-endY)>16){
				$D.setStyle(self._dragLayer,'top',Math.min(startY,endY)+'px');
				$D.setStyle(self._dragLayer,'left',Math.min(startX,endX)+'px');
				$D.setStyle(self._dragLayer,'width',Math.abs(startX-endX) + 'px');
				$D.setStyle(self._dragLayer,'height',Math.abs(startY-endY) + 'px');
				var layerLeft = Math.min(startX,endX);
				var layerTop = Math.min(startY,endY);
				var layerRight = Math.max(startX,endX);
				var layerBottom = Math.max(startY,endY);
				// all selectable items
				var items = self.get('items');
				for(i=0,j=items.length;i<j;i++){
					var elLeft = $D.getX(items[i]);
					var elTop = $D.getY(items[i]);
					var elRight = elLeft + items[i].offsetWidth;
					var elBottom = elTop + items[i].offsetHeight;
					var x = [layerLeft,layerRight,elRight,elLeft].sort(function(a,b){return a-b});
					var y = [layerTop,layerBottom,elTop,elBottom].sort(function(a,b){return a-b});
					if(
						Math.abs(elLeft - elRight) + Math.abs(layerLeft - layerRight) > Math.abs(x[3] - x[0]) &&
						Math.abs(elTop - elBottom) + Math.abs(layerTop - layerBottom) > Math.abs(y[3] - y[0]) &&
						Math.abs(x[1] - x[2]) * Math.abs(y[1] - y[2]) / (items[i].offsetWidth * items[i].offsetHeight) > 0.1)
					{
						//
						var selected = self.get('selectedItems');
						if(!$D.hasClass(items[i],self.get('selectedClassName'))){
							selected[selected.length] = items[i];
						};
					};
					_setSelected.call(self);
				};
				var callback = self.get('callback');
				callback(self.get('selectedItems'));
			};
		};
		var endDrag = function(e){
			YAHOO.log('mouse up');		
			if(!self._startDrag){
				return;
			};
			_hideLayer.call(self);
			self._startDrag = false;
			if(self.get('selectedItems').length){
				var callback = self.get('callback');
				callback(self.get('selectedItems'));
			};
		};
	    var dragSelect = function(e){
	        $E.stopEvent(e);
	        return false;
	    };		
		$E.on(document,'mousedown',startDrag);
		$E.on(document,'mousemove',dragMove);
		$E.on(document,'mouseup',endDrag);
		$E.on(document,'selectstart',dragSelect);
		$E.on(this.get('element'),'click',itemClick,'class',this.get('itemClassName').toString(),false,1);
	};
	YAHOO.namespace('ACE.util');
	YAHOO.ACE.util.Select = Select;
}());
 



