( function() {
	var $UI = window.$UI = function(type,JSON) {
		return new $UI.effect[type](JSON);
	}
	$UI.effect = {
		tabs:function(JSON) {
			this.options={
				id:JSON.id,
				tabId:JSON.tabId||JSON.id,
				tabTn:JSON.tabTn||'li',
				tabCn:JSON.tabCn,
				conId:JSON.conId||JSON.id,
				conTn:JSON.conTn||'div',
				conCn:JSON.conCn,
				focus:!!JSON.focus,
				current:JSON.current||0,
				eType:JSON.eType||'mouseover',
				interval:JSON.interval||3000,
				tempCn:[]
			}
			var opt=this.options,ready=true;

			opt.tabs = opt.tabCn?
			$('#'+opt.tabId+' .'+opt.tabCn):
			$('#'+opt.tabId+' '+opt.tabTn);

			opt.cons = opt.conCn?
			$('#'+opt.conId+' .'+opt.conCn):
			$('#'+opt.conId+' '+opt.conTn);

			// check if the number of tabs equals the cons's;
			if (opt.tabs.length != opt.cons.length) {
				throw new Error("Match Failed");
				return;
			} else
				opt.levels = opt.tabs.length;

			for (var i = 0,l=opt.levels;i<l;i++){
				( function() {
					var b = i;
					opt.tempCn[i] = opt.tabs[i].className;
					$fn.addEvent(opt.tabs[i],opt.eType,function() {
						ready=false;
						opt.current = b;
						opt.runId&&clearTimeout(opt.runId);
						opt.runId = setTimeout(opt.start, 10);
					})
					$fn.addEvent(opt.tabs[i],'mouseout',function() {
						ready=true;
						opt.current = b;
						opt.runId = setTimeout(opt.start, 10);
					})
				})()
			}

			(opt.start = function() {
				if (opt.current >= opt.levels)
					opt.current = 0;
				if (opt.current < 0)
					opt.current = opt.levels - 1;
				for (var i=0,l=opt.levels;i<l;i++){
					opt.tabs[i].className = (opt.current == i) ? opt.tempCn[i]+' current' : opt.tempCn[i];
					opt.cons[i].style.display = (opt.current == i) ? 'block' : 'none';
				}
				if(opt.focus&&ready){
					opt.current++;
					opt.runId = setTimeout(opt.start, opt.interval);
				}
			})()
		},
		drag:function(JSON){
			this.options={
				obj:JSON.id&&$('#'+JSON.id)[0]||JSON.obj,
				bar:JSON.barId&&$('#'+JSON.barId)[0]||JSON.bar,
				barCn:JSON.barCn,
				scope:JSON.scopeId&&$('#'+JSON.scopeId)[0]||JSON.scope,
				close:!!JSON.close,
				closeCn:JSON.closeCn,
				closeConCn:JSON.closeConCn,
				goX:!JSON.lockY,
				goY:!JSON.lockX,
				posX:JSON.posX,//if set randomPos,this value will be ignored
				posY:JSON.posY,//if set randomPos,this value will be ignored
				randomPos:!!JSON.randomPos,
				drag:false,
				zIndex:JSON.zIndex,
				limit:!!JSON.limit,
				maxTop:JSON.maxTop||0,
				maxRight:JSON.maxRight||0,
				maxBottom:JSON.maxBottom||0,
				maxLeft:JSON.maxLeft||0,
				init:JSON.init,
				start:JSON.start,
				move:JSON.move,
				stop:JSON.stop
			}
			var opt=this.options,obj=opt.obj,bar=opt.bar||(opt.barCn&&$fn.getByCn(opt.barCn,obj,true)[0])||obj;
			
			//if the limit is true, then reset the maxRight and maxBottom
			if(opt.limit){
				opt.maxRight=opt.maxRight&&(opt.maxRight-obj.offsetWidth);
				opt.maxBottom=opt.maxBottom&&(opt.maxBottom-obj.offsetHeight);
			}
			
			//if the scope obj is set ,then correct the limit scope
			if(opt.scope){
				var maxRight=opt.scope.clientWidth-obj.offsetWidth,
				maxBottom=opt.scope.clientHeight-obj.offsetHeight,
				maxLeft=maxBottom-obj.offsetHeight,
				maxTop=maxRight-obj.offsetWidth;
				opt.scope.style.position='relative';
				opt.maxTop=(opt.maxTop>=0&&opt.maxTop<=maxTop)?opt.maxTop:0;
				opt.maxRight=(opt.maxRight>=obj.offsetWidth&&opt.maxRight<=maxRight)?opt.maxRight:maxRight;
				opt.maxBottom=(opt.maxBottom>=obj.offsetHeight&&opt.maxBottom<=maxBottom)?opt.maxBottom:maxBottom;
				opt.maxLeft=(opt.maxLeft>=0&&opt.maxLeft<=maxLeft)?opt.maxLeft:0;
				opt.limit=true;
			}

			//if the close is on 
			if(opt.close){
				opt.closeObj=$fn.getByCn(opt.closeCn,obj,true)[0];
				opt.closeCon=$fn.getByCn(opt.closeConCn,obj,true)[0];
				if(opt.closeObj&&opt.closeCon){
					var hide=true;
					$fn.addEvent(opt.closeObj,'click',function(){
						(hide)?opt.closeCon.style.display='none':opt.closeCon.style.display='block';
						hide=!hide;
					})
				}
			}
			
			//if the randomPos is on, reset the position, ignoring the posX and posY value set before.
			if(opt.randomPos){
				opt.maxRight=(opt.maxRight==0)?($fn.viewWidth()-obj.offsetWidth):opt.maxRight;
				opt.maxBottom=(opt.maxBottom==0)?($fn.viewHeight()-obj.offsetHeight):opt.maxBottom;
				opt.posX=$fn.rdNum(opt.maxLeft,opt.maxRight);
				opt.posY=$fn.rdNum(opt.maxTop,opt.maxBottom);
			}
			
			//the position
			obj.style.left=(opt.posX||opt.maxLeft)+'px';
			obj.style.top=(opt.posY||opt.maxTop)+'px';
			obj.style.position='absolute';
			obj.style.zIndex=(opt.zIndex)?opt.zIndex:$fn.uniqueNum();
			
			//save the zIndex for later use
			$UI.temp.DzIndex=($UI.temp.DzIndex>parseInt(obj.style.zIndex))?$UI.temp.DzIndex:parseInt(obj.style.zIndex);

			//prevent the propagation when dragging
			$fn.addEvent(obj,'mousedown',function(e){
				e=e||window.event;
				if(e.stopPropagation) e.stopPropagation()
				else e.cancelBubble= true;}
			)

			$fn.addEvent(bar,'mousedown',function(e){
				opt.drag=true;
				e=e||window.event;
				obj.style.zIndex=(parseInt(obj.style.zIndex)<$UI.temp.DzIndex)?++$UI.temp.DzIndex:obj.style.zIndex;
				/* opt.offsetX=$fn.getX(e)-obj.offsetLeft;
				opt.offsetY=$fn.getY(e)-obj.offsetTop; */
				opt.offsetX=$fn.getX(e)-parseInt(obj.style.left);
				opt.offsetY=$fn.getY(e)-parseInt(obj.style.top);
				if(e.stopPropagation) e.stopPropagation()
				else e.cancelBubble= true;
				$fn.addEvent(document,'mousemove',function(e){
					if(!opt.drag||!opt.goX&&!opt.goY) return;
					e=e||window.event;
					var x=$fn.getX(e)-opt.offsetX,y=$fn.getY(e)-opt.offsetY;
					if(opt.limit){
						x=(x<opt.maxLeft)?opt.maxLeft:x;
						x=(x>opt.maxRight)?opt.maxRight:x;
						y=(y<opt.maxTop)?opt.maxTop:y;
						y=(y>opt.maxBottom)?opt.maxBottom:y;
					}
					obj.style.left=opt.goX?(x+'px'):obj.style.left;
					obj.style.top=opt.goY?(y+'px'):obj.style.top;
					opt.move&&opt.move(e);
				})
				$fn.addEvent(document,'mouseup',function(e){
					opt.drag=false;
					if($fn.getTarget(e)==bar)
					opt.stop&&opt.stop(e);
				})
			})
			
			//init over
			opt.init&&opt.init();
		},
		multiDrag:function(JSON){
			this.options={
				domSet:JSON.domSet,
				barCn:JSON.barCn,
				scopeId:JSON.scopeId,
				scope:JSON.scope,
				close:JSON.close,
				closeCn:JSON.closeCn,
				closeConCn:JSON.closeConCn,
				randomPos:JSON.randomPos
			}
			var opt=this.options;
			for(var i=0;i<opt.domSet.length;i++){
				$UI('drag',{
					obj:opt.domSet[i],
					barCn:opt.barCn,
					randomPos:opt.randomPos,
					scopeId:opt.scopeId,
					close:opt.close,
					closeCn:opt.closeCn,
					closeConCn:opt.closeConCn					
					});
			}
		},
		dragToList:function(JSON){
			/* this.options={
				cols:JSON.cols,
				containerId:JSON.containersId,
				modsCn:JSON.modsCn,//could be invalid if has set mods
				mods:JSON.mods,
				helper:null,
				helperCn:JSON.helperCn,
				dragingCn:JSON.dragingCn,
				close:JSON.close,
				closeCn:JSON.closeCn,
				closeConCn:JSON.closeConCn,
				z:0
			}
			var opt=this.options;

			opt.mods=(opt.mods)?opt.mods:$fn.getByCn(opt.modsCn,opt.containerId);

			for(var i=0;i<opt.mods.length;i++){
				$fn.addEvent(opt.mods[i],'mousedown',function(e){
					var o=this;
					drag=true;
					e=e||window.event;
					
					opt.z=o.style.zIndex;
					o.style.left=$fn.getL(o)+'px';
					o.style.top=$fn.getT(o)+'px';
					o.style.zIndex=1000;
					o.style.position='absolute';
					
					x=$fn.getX(e)-o.offsetLeft;
					y=$fn.getY(e)-o.offsetTop;
					o.className=JSON.dragingCN;
					tmpdiv=document.createElement('div');
					tmpdiv.className=JSON.tempCN;
					container.insertBefore(tmpdiv,o);
					document.body.appendChild(o);
				})
			} */

			var container=$('#'+JSON.id)[0];
			var mods=container.getElementsByTagName(JSON.tabTn),x=y=0,drag=false,tmpdiv=null,modsToDrag=[];
			for(var i=0;i<mods.length;i++){
				modsToDrag[i]=mods[i];
			}
			
			$fn.cleanWS(container);
			
			for(var i=0;i<mods.length;i++){
				modsToDrag[i]=mods[i];
			}
			
			for(var i=0;i<modsToDrag.length;i++){
				$fn.addEvent(modsToDrag[i],'mousedown',function(e){
					var o=this;
					drag=true;
					e=e||window.event;
					this.style.left=$fn.getL(this)+'px';
					this.style.top=$fn.getT(this)+'px';
					this.style.position='absolute';
					x=$fn.getX(e)-this.offsetLeft;
					y=$fn.getY(e)-this.offsetTop;
					this.className=JSON.dragingCN;
					tmpdiv=document.createElement('div');
					tmpdiv.className=JSON.tempCN;
					container.insertBefore(tmpdiv,this);
					document.body.appendChild(this);
					
					$fn.addEvent(document,'mouseup',function(){
						drag=false;
						container.insertBefore(o,tmpdiv);
						o.className=JSON.modCN;
						o.style.position='static';
						container.removeChild(tmpdiv);
					})
					
					$fn.addEvent(document,'mousemove',function(e){
						if(!drag) return;
						e=e||window.event;
						o.style.left=$fn.getX(e)-x+'px';
						o.style.top=$fn.getY(e)-y+'px';
						for(var j=0;j<modsToDrag.length;j++){
							if(
								parseInt(o.style.left)>$fn.getL(modsToDrag[j])
								&&parseInt(o.style.left)<$fn.getL(modsToDrag[j])+modsToDrag[j].offsetWidth
								&&parseInt(o.style.top)>$fn.getT(modsToDrag[j])
								&&parseInt(o.style.top)<$fn.getT(modsToDrag[j])+modsToDrag[j].offsetHeight
							){
								if(!modsToDrag[j].previousSibling)
									container.insertBefore(tmpdiv,modsToDrag[j])
								else{
									if(modsToDrag[j].nextSibling)
										container.insertBefore(tmpdiv,modsToDrag[j].nextSibling);
									else 
										container.appendChild(tmpdiv);
								}
								break;
							}
						}
					})
				})
			}
		},
		scroll:function(JSON){
			this.options={
				wrap:JSON.wrap,
				innerWrap:JSON.innerWrap,
				speed:JSON.speed||30,
				direction:JSON.direction||'left'
			}
			var opt=this.options,
				wrap=$('#'+opt.wrap)[0],
				innerWrap=$('#'+opt.innerWrap)[0],
				tid;
			
			innerWrap.innerHTML+=innerWrap.innerHTML;
			
			switch(opt.direction){
				case 'left':
					run=function(){
						if(wrap.scrollLeft>=(wrap.scrollWidth/2))  wrap.scrollLeft=0;
						else wrap.scrollLeft++;
						tid=setTimeout(arguments.callee,opt.speed);
					}
					break;
				case 'up':
					 run=function(){
						if(wrap.scrollTop>=(wrap.scrollHeight/2))  wrap.scrollTop=0;
						else wrap.scrollTop++;
						tid=setTimeout(arguments.callee,opt.speed);
					}
					break;
				case 'right':
					 run=function(){
						if(wrap.scrollLeft<=0)  wrap.scrollLeft=wrap.scrollWidth/2;
						else wrap.scrollLeft--;
						tid=setTimeout(arguments.callee,opt.speed);
					}
					break;
				case 'down':
					 run=function(){
						if(wrap.scrollTop<=0)  wrap.scrollTop=wrap.scrollHeight/2;
						else wrap.scrollTop--;
						tid=setTimeout(arguments.callee,opt.speed);
					}
			}
			run();
			$fn.addEvent(wrap,'mouseover',function(){clearTimeout(tid)})
			$fn.addEvent(wrap,'mouseout',function(){tid=setTimeout(run,opt.speed)})
		},
		resize:function(JSON){
			/*this.options={
				obj:JSON.obj||$('#'+JSON.id)[0],
				barCn:JSON.barCn,
				dragType:JSON.dragType||0
			}
			var opt=this.options, bars=$fn.getByCn(opt.barCn,opt.obj),obj=opt.obj,resize=false,w;

			for(var i=0;i<bars.length;i++){
				$fn.addEvent(bars[i],'mousedown',function(e){
					resize=true;
					e=e||window.event;
					opt.ex=$fn.getX(e);
					
					if(e.stopPropagation) e.stopPropagation()
					else e.cancelBubble= true;
					
					$fn.addEvent(document,'mousemove',function(e){
						if(!resize) return;
						e=e||window.event;
						obj.style.width=parseInt(obj.style.width)+$fn.getX(e)-opt.ex+'px';

					})
					$fn.addEvent(document,'mouseup',function(e){
						resize=false;
					})
				})
			}*/
		},
		alert:function(JSON){
			this.options={
				id:JSON.id,
				obj:JSON.obj,
				close:JSON.close,
				closeId:JSON.closeId,
				bcColor:JSON.bcColor||'#000',
				opacity:JSON.opacity||50,
				dragBar:JSON.dragBar
			}
			var opt=this.options,
				obj=opt.obj||$('#'+opt.id)[0],
				close=opt.close||$('#'+opt.closeId)[0],
				X=$fn.viewWidth(),
				Y=$fn.viewHeight(),
				x=Math.round((X-obj.offsetWidth)/2),
				y=Math.round((Y-obj.offsetHeight)/2),
				tmp=document.createElement('div');

				if(opt.dragBar){
					$UI('drag',{obj:obj,bar:opt.dragBar})
				}
				
				$fn.css(tmp,{
					position:'absolute',
					left:0,
					top:0,
					zIndex:1000,
					width:'100%',
					height:Y+'px',
					backgroundColor:opt.bcColor,
					opacity:opt.opacity
				})
				document.body.appendChild(tmp);

				$fn.css(obj,{
					position:'absolute',
					zIndex:1001,
					left:x+'px',
					top:y+'px'
				})
				
				$fn.addEvent(close,'click',function(){obj.parentNode.removeChild(obj)})
		}
	}
	//save the temp var for globle use.
	$UI.temp={
		DzIndex:0
	}
})()
