var AutoPlay=new Class({
	options:{
		autoplay:true,
		interval:3500,     
		pauseOnHover:true    //鼠标悬停停止播放
	},
	_autoInit:function(fn){              
		if(!this.options.autoplay)return;
		this.autofn=fn||$empty;       
		this.autoEvent().startAutoplay();
	},
	autoEvent:function(){             //悬停时停止播放
		if(this.options.pauseOnHover&&this.container){
			this.container.addEvents({'mouseenter':this.stopAutoplay.bind(this),
			'mouseleave':function(){
				this.startAutoplay();
			}.bind(this)});	
		}	
		return this;
	},
	startAutoplay:function(){
		this.paused=false;
		this.autoTimer=function(){
			if(this.paused)return;	
			this.autofn();
		}.periodical(this.options.interval,this);
	},
	stopAutoplay:function(){
		if(this.autoTimer){
			$clear(this.autoTimer);	
			this.autoTimer=undefined;
		}	
		this.paused=true; 
	}
});

var LazyLoad=new Class({                    //延时加载基类
	Implements:[Options,Events],	
	options:{
		img:'img-lazyload',                   //存图象地址的属性
		textarea:'textarea-lazyload',        //textarea的class
		lazyDataType:'textarea',            //延时类型
		execScript:true,                   //是否执行脚本
		islazyload:true,                  //是否执行延时操作
		lazyEventType:'beforeSwitch'     //要接触延时的事件
	},
	loadCustomLazyData: function(containers, type) {                
		var area, imgs,area_cls=this.options.textarea,img_data=this.options.img;
		if(!this.options.islazyload)return;
		$splat(containers).each(function(container){
			switch (type) {
				case 'img':
					imgs=container.nodeName === 'IMG'?[container]:container.getElements('img');
					imgs.each(function(img){
						this.loadImgSrc(img, img_data);
					},this);
					break;
				default:
					area=container.getElement('textarea');	
					if(area && area.hasClass(area_cls))
					this.loadAreaData(area);
					break;
			}
		},this);
	},
	loadImgSrc: function(img, flag ,cb) {
		flag = flag || this.options.img;
		var dataSrc = img.getProperty(flag);
		img.removeProperty(flag);
		if (dataSrc && img.src != dataSrc) {
			var pic= new Image();    
			pic.onload = function(){
				pic.onload = null;
				img.src = dataSrc;
				cb && cb();
			}
			pic.src = dataSrc; 
		//	new Asset.image(dataSrc,{onload:function(image){
		//		img.src = dataSrc;
		//	}.bind(this)});
		}
    },
	loadAreaData: function(area ,cb) {
			//area.setStyle('display','none').className='';
            var content = new Element('div').inject(area,'before');
			this.stripScripts(area.value,content);
			area.destroy();
			cb && cb();
	},
	isAllDone:function(){                         
		var type=this.options.lazyDataType,flag=this.options[type],
			elems, i, len, isImgSrc = type === 'img';
		if (type) {
			elems = this.container.getElements(type);
			for (i = 0, len = elems.length; i < len; i++) {
				if (isImgSrc ?elems[i].get(flag): elems[i].hasClass(flag)) return false;
			}
		}
		return true;
	},
	stripScripts: function(v,content){
		var scripts = '';
		var text = v.replace(/<script[^>]*>([\s\S]*?)<\/script>/gi, function(){
			scripts += arguments[1] + '\n';				
			return '';
		});
		content.set('html',this.options.execScript?text:v);
		this.options.execScript && $exec(scripts);	
	},
	_lazyloadInit:function(panel){           
		var loadLazyData=function(){
			var containers=$type(panel)=='function'?panel(arguments):panel;
			this.loadCustomLazyData(containers,this.options.lazyDataType); 
			if (this.isAllDone()) {
				this.removeEvent(this.options.lazyEventType,arguments.callee);
			}
		};
		this.addEvent(this.options.lazyEventType,loadLazyData.bind(this));
	}
});

var DataLazyLoad = new Class({          
	Extends:LazyLoad,	       
	options:{
		threshold:null,               //获取要延时的窗口距离
		syncEl:null,                  //images ,areas
		config:{
			mod:'manual',             //延时模式
			diff:'default',           //默认取为两屏窗口的延时元素
			placeholder:'none'         //默认延时图片地址
		}
	},
	initialize:function(options,containers){
		this.containers=$splat($(containers)||document);	
		if(!this.containers)return;
		this.setOptions(options);
		this.lazyinit();
	},	
	lazyinit:function(){
		this.threshold=this.getThreshold();
		this.filterItems().getItemsLength();
		this.initLoadEvent();
	},
	filterItems:function(){                    
		var containers=this.containers,imgs,areas,i,len,img,area,
		lazyImgs=[],lazyAreas=[];
		containers.each(function(n){
			lazyImgs=lazyImgs.combine(n.getElements('img').filter(this.filterImg,this));
			lazyAreas=lazyAreas.combine(n.getElements('textarea').filter(this.filterArea,this));
		},this);	
		this.images=lazyImgs;
		this.areas=lazyAreas;
		return this;
    },
	filterImg:function(img){
		var img_data=this.options.img, dataSrc=img.getAttribute(img_data),		   
		threshold=this.threshold,placeholder=this.options.config.placeholder,
		isManualMod=this.options.config.mod==='manual';
		if(isManualMod){
			if(dataSrc){
				if(placeholder!=='none')img.src=placeholder;
				return true;
			}	
		}else{
			if($(img).getOffsets().y> threshold && ! dataSrc){
				img.set(img_data,img.src);	
				placeholder !== 'none'? img.src=placeholder:img.removeAttribute('src');	
				return true;	
			}	
		}
    },
	filterArea:function(area){
		return area.hasClass(this.options.textarea);
    },
	initLoadEvent:function(){
		var timer,self=this,win =window;				   
		win.addEvent('domready',this.loadItems.bind(this));	

		if(!this.getItemsLength())return;
		win.addEvents({'scroll':loader,'resize':resizeloader});
				
		function resizeloader(){
			self.threshold=self.getThreshold();			
			loader();
		};
		function loader(){
			if(timer) return;	
			timer = function(){
				self.loadItems.call(self);
				if(!self.getItemsLength())
				win.removeEvents({'scroll':loader,'resize':resizeloader})
				timer = null;
			}.delay(100);
		}
    },
	loadItems: function() {
		var syncEl= this.options.syncEl;
		if(syncEl)return this.loadsync(this[syncEl],syncEl);

		this.initItems(this.images.concat(this.areas));
		this.fireEvent('callback');
	},
	initItems:function(items){
		var scrollTop = window.getScroll().y, threshold = this.threshold + scrollTop,
			obj = {images:[],areas:[]}, 
			fnObj = {'areas':'loadAreaData','images':'loadImgSrc'};

		items.each(function(el){
			var isArea=el.tagName=='TEXTAREA'?'areas':'images',ele =el;
			if(isArea) el= $(el.getStyle('display')=='none'?el.parentNode:el);

			if (el.getOffsets().y<= threshold) {
				this[fnObj[isArea]](ele);
			}else{
				obj[isArea].push(ele);	
			}
		},this); 

		this.images=obj.images; this.areas=obj.areas;
    },
	loadsync:function(els,tag){
		if(!els.length)return;	
		var scrollTop = window.getScroll().y, threshold = this.threshold + scrollTop,
			isArea = tag=='areas';

if(this.options.trigger) $(trigger).addEvent('click', this.show.bind(this));
		else this.show();
		els = els.filter(function(el){
			if(isArea) el = el.getStyle('display')=='none'?el.parentNode:el;
			return el.getOffsets().y<= threshold;
		});

		if(!els.length)return;	
		var el= els.shift(),
			callback= this.loadsync.bind(this, [this[tag].erase(el),tag]);

		if(isArea) return this.loadAreaData(el,callback);
		this.loadImgSrc(el,false,callback);
	},
	getThreshold:function(){
		if(this.options.threshold)return this.options.threshold;
		var diff=this.options.config.diff,vh=window.getSize().y;				  
		if(diff==='default')return 1 * vh;			  
		return vh + diff;
    },		
	getItemsLength:function(){
		return this.images.length+this.areas.length;	
	}
});

var Tabs = new Class({                        
	Implements:[AutoPlay,LazyLoad],	
	options:{
		onLoad:$empty,                          
		onInit:$empty,                        //初始化时调用
		onBeforeSwitch:$empty,               //tab切换前调用
		onSwitch:$empty,                     //切换时调用
		eventType:'mouse',                  //事件类型click和mouse
		hasTriggers:true,                  //是否有触点选择
		triggersBox:'.switchable-triggerBox',         //触点的父元素
		triggers:'.switchable-trigger',               //触点class
		panels:'.switchable-panel',                  //显示面板class
		content:'.switchable-content',              //显示区域class
		activeIndex:0,                             //默认显示的元素 索引
		activeClass:'active',                     //当前触点元素class
		steps:1,                              //一次显示一个panel
		delay:100,                           //mouse延时触发
		haslrbtn:false,                     //是否支持前后按钮
		prev:'.prev',                        
		next:'.next',
		autoplay:false,	
		disableCls:null                 
	},
	initialize:function(container,options){
		this.container=$(container);	
		if(!this.container)return;
		this.setOptions(options);
		this.activeIndex=this.options.activeIndex;
		this.init();
	},	
	init:function(){
		this.fireEvent('load');
		this.getMarkup();
		this.triggersEvent().extendPlugins();
		if(this.options.hasTriggers&&this.triggers[this.activeIndex])
		this.triggers[this.activeIndex].addClass(this.options.activeClass);
		if(this.options.islazyload)
		this.fireEvent('beforeSwitch',{toIndex:this.activeIndex});
		this.fireEvent('init');
    },
	extendPlugins:function(){                     
		var options=this.options;
		if(options.autoplay)this._autoInit(this.autofn.bind(this));
		if(options.islazyload)this._lazyloadInit(this.getLazyPanel.bind(this));
		Tabs.plugins.each(function(plugin){
			if(plugin.init)plugin.init.call(this);	
		},this);
    },
	autofn:function(){                        
		var index=this.activeIndex < this.length - 1 ? this.activeIndex + 1 : 0;
		this.switchTo(index, 'FORWARD');
    },
	getMarkup:function(){                   
		var container=this.container,options=this.options;	  

		if(options.hasTriggers)

		var triggersBox=$(options.triggersBox)||container.getElement(options.triggersBox);
		this.triggers=triggersBox?triggersBox.getChildren():container.getElements(options.triggers);	

		panels=this.panels=container.getElements(options.panels);

		this.content=$(options.content)||container.getElement(options.content)?container.getElement(options.content):panels[0]?panels[0].getParent():[];

		this.content=$splat(this.content);

		if(!panels.length&&this.content.length) this.panels=this.content[0].getChildren();

		if(!this.panels.length)return this;
		this.length=this.panels.length/options.steps;		
	},
	triggersEvent:function(){                 
		var options=this.options,triggers=this.triggers;
		if(options.hasTriggers)
		triggers.each(function(trigger,index){
			trigger.addEvent('click',function(e){
				if(!this.triggerIsValid(index))return;			
				this.cancelTimer().switchTo(index);
			}.bind(this));

			if(options.eventType==='mouse')
			trigger.addEvents({'mouseenter':function(e){
				if(!this.triggerIsValid(index))return;			
				this.switchTimer=this.switchTo.delay(options.delay,this,index);
			}.bind(this),'mouseleave':this.cancelTimer.bind(this)});
		},this);
		if(options.haslrbtn)this.lrbtn();
		return this;
    },
	lrbtn:function(){                    //前后按钮事件
		['prev','next'].each(function(d){
			this[d+'btn']=this.container.getElement(this.options[d]).addEvent('click',function(e){
				if(!$(e.target).hasClass(this.options.disableCls))this[d]();	
			}.bind(this));
		},this);  
		this.disabledBtn();	
	},
	disabledBtn:function(){
		var disableCls=this.options.disableCls;
		if(disableCls){
			this.addEvent('switch',function(ev){
				var i=ev.currentIndex,
				disableBtn=(i===0)?this['prevbtn']:(i===Math.ceil(this.length)-1)?this['nextbtn']:undefined;	
				this['nextbtn'].removeClass(disableCls);
				this['prevbtn'].removeClass(disableCls);
				if(disableBtn)disableBtn.addClass(disableCls);
			}.bind(this));		
		}		 
	},
	triggerIsValid:function(index){          
		return this.activeIndex!==index;
	},
	cancelTimer:function(){                   
		if(this.switchTimer){
			$clear(this.switchTimer);				 
			this.switchTimer=undefined;
		}
		return this;
    },
	switchTo:function(index,direction){           
		var options=this.options,triggers=this.triggers,panels=this.panels,
			activeIndex=this.activeIndex,steps=options.steps,
			fromIndex = activeIndex * steps, toIndex = index * steps;

			if(!this.triggerIsValid(index))return this; 

			this.fireEvent('beforeSwitch',{toIndex:index});

			if(options.hasTriggers)
			this.switchTrigger(activeIndex > -1 ? triggers[activeIndex] : null, triggers[index]);

            if (direction === undefined) 
			direction = index > activeIndex ? 'FORWARD' : 'BACKWARD';

            this.switchView(
                panels.slice(fromIndex, fromIndex + steps),
                panels.slice(toIndex, toIndex + steps),
                index, direction);

            this.activeIndex = index;
			
			return this.fireEvent('switch',{currentIndex:index});			
	},
	switchTrigger:function(fromTrigger,toTrigger,index){       
			var activeClass=this.options.activeClass;
			if (fromTrigger)fromTrigger.removeClass(activeClass);
            toTrigger.addClass(activeClass);
    },
	switchView:function(fromPanels,toPanels,index,direction){       
		fromPanels[0].setStyle('display','none');
		toPanels[0].setStyle('display','');
	},
	prev: function() {
        var activeIndex = this.activeIndex;
        this.switchTo(activeIndex > 0 ? activeIndex - 1 : this.length - 1, 'BACKWARD');
	},
	next: function() {
        var activeIndex = this.activeIndex;
        this.switchTo(activeIndex < this.length - 1 ? activeIndex + 1 : 0, 'FORWARD');
	},
	getLazyPanel:function(args){                      
		var steps = this.options.steps,from = args[0].toIndex * steps , to = from + steps;
		return this.panels.slice(from, to);
	}
});

Tabs.plugins=[];

Tabs.Effects = {                                
	none: function(fromEls, toEls) {
		fromEls[0].setStyle('display','none');
		toEls[0].setStyle('display','block');
	},
	fade: function(fromEls, toEls ) {
		if (fromEls.length !== 1) {
			throw new Error('fade effect only supports steps == 1.');
		}
		var fromEl = fromEls[0], toEl = toEls[0];

		if(this.anim)this.anim.cancel();
		this.anim=new Fx.Tween(fromEl,{duration:this.options.duration,
			onStart:function(){toEl.setStyle('opacity',1);},
			onCancel:function(){
				this.element.setStyles({'opacity':0});
			    this.fireEvent('complete');
			},
			onComplete:function(){
				toEl.setStyle('zIndex',9);	
				fromEl.setStyle('zIndex',1);	
				this.anim = undefined; 
		}.bind(this)}).start('opacity',1,0);
	},
	scroll: function(fromEls, toEls, index, direction) {
		var self=this,options= this.options,activeIndex = this.activeIndex,
			isX = options.effect === 'scrollx',len = this.length,content=this.content[0],
			viewDiff = this.viewSize[isX ? 0: 1],steps = options.steps,panels=this.panels,
			prop=isX ? 'left': 'top', diff = -viewDiff * index,from,
            isCritical,isBackward = direction !== 'FORWARD';
	
			
		isCritical = (isBackward && activeIndex === 0 && index === len - 1) || (!isBackward && activeIndex === len - 1 && index === 0);

        if (isCritical) { diff = position.call(this,true); }

		fromp=content.getStyle(prop).toInt();
		fromp=isNaN(fromp)?0:fromp;

		if(this.anim)this.anim.cancel();

		this.anim=new Fx.Tween(content,{duration:this.options.duration,transition:Fx.Transitions.Circ.easeOut,
			onComplete:function(){
				if (isCritical) position.call(self);
				this.anim = undefined; 
		}.bind(this)}).start(prop,fromp,diff);

		function position(reset) {
            var start = isBackward ? len - 1 : 0, from = start * steps, to = (start + 1) * steps, i;

			for (i = from; i < to; i++) {
				var l=(isBackward ? -1 : 1) * viewDiff * len;
				panels[i].setStyle('position',reset?'relative':'').setStyle(prop,reset?l:'');
			}
			if(reset) return isBackward ? viewDiff : -viewDiff * len;
			return content.setStyle(prop,isBackward ? -viewDiff * (len - 1) :'');
		}
	}
};

Effects = Tabs.Effects;
Effects['scrollx'] = Effects['scrolly'] = Effects.scroll;

var Switchable=new Class({                     
	Extends:Tabs,	
	options:{
		autoplay:true,	
		effect:'none',
		circular:false,                         //是否开启循环滚动
		duration:500,
		direction:'FORWARD',                  //'BACKWARD'	
		viewSize:[]                           //显示区域的大小
	},
	extendPlugins:function(){
		this.parent();
		this.effInit();
	},
	effInit:function(){               
		var options=this.options,effect=options.effect,
		panels=this.panels,content=this.content[0],
		steps=options.steps,activeIndex=this.activeIndex,len=panels.length;
		this.viewSize = [
			options.viewSize[0] || panels[0].getSize().x * steps,
			options.viewSize[1] || panels[0].getSize().y * steps
		];
		if(effect!=='none'){
			switch (effect) {
				case 'scrollx': case 'scrolly':
					content.setStyle('position','absolute');
					content.getParent().setStyle('position','relative');
					if (effect === 'scrollx') {
						panels.setStyle('float','left');
						content.setStyle('width',this.viewSize[0] * (len/steps));
					}
					break;
				case 'fade':
					var min = activeIndex * steps, max = min + steps - 1, isActivePanel;

					panels.each(function(panel,i){
						isActivePanel = i >= min && i <= max;
						panel.setStyles({
							opacity: isActivePanel ? 1 : 0,
							position: 'absolute',
							zIndex: isActivePanel ? 9 : 1
						});	
					});
					break;
				default :
					break;
			}
		}	
	},
	switchView: function(fromEls, toEls, index, direction) {   
		var options= this.options, effect = options.effect,circular=options.circular,
		fn = $type(effect)=='function' ? effect : Effects[effect];
		if(circular)direction=options.direction;
		if(fn)fn.call(this, fromEls, toEls,index, direction);
	}	
});

Switchable.autoRender=function(autoClass,container){
		var cls=autoClass||'.J_mod',  clt=$(container||document.body).getElements(cls);
		if(clt.length)
		clt.each(function(el){
			 var type = el.get('mod-type'), config;	
			 if (type && ('Tabs Switchable DropMenu Accordion DataLazyLoad Popup'.indexOf(type) > -1)) {
				try {
					config = el.get('mod-config')||{};
					if(type=='DataLazyLoad')return 	new window[type](JSON.decode(config),el);
					new window[type](el, JSON.decode(config));
				} catch(e) {}
			 }
		}); 
};	

var Accordion= new Class({                   
	Extends:Tabs,	
	options:{
		eventType:'click',
		multiple:false
	},
	triggerIsValid:function(index){
	    return this.activeIndex !== index || this.options.multiple;
	},
	switchView: function(fromPanels, toPanels, index) {
		var  options= this.options,panel = toPanels[0];
			if (options.multiple) {
				this.triggers[index].toggleClass(options.activeClass);
				panel.setStyle('display',panel.getStyle('display')=='none'?'block':'none');
            } else {
				fromPanels[0].setStyle('display','none');
				panel.setStyle('display','block');
            }
	}
});

var DropMenu=new Class({
	Implements: [LazyLoad],
	options: {
		onLoad:$empty,
		onShow:$empty,
		onHide:$empty,
		showMode:function(menu){menu.setStyle('display','block');},
		hideMode:function(menu){menu.setStyle('display','none');},
		dropClass:'droping',
		eventType:'mouse',
		relative:false,
		stopEl:false,
		stopState:false,
		lazyEventType:'show',
		offset:{x:0,y:20}
	},
	initialize:function(el,options){
		this.element=$(el);
		if(!this.element)return;
		this.setOptions(options);
		var menu=this.options.menu;  
		this.menu=$(menu)||$(this.element.get('dropmenu'))||this.element.getParent().getElement('.'+menu);
		if(!this.menu)return;
		this.load().attach()._lazyloadInit(this.menu);
	},
	attach:function(){
		var options=this.options,stopState=options.stopState,
			dropClass=options.dropClass,eventType=options.eventType;
		if(eventType!='mouse'){
			this.element.addEvent('click',function(e){		
				if(this.showTimer)$clear(this.showTimer);
				if(stopState)e.stop();
				if(this.status)return;
				this.showTimer=this.show().outMenu.delay(200,this);
			}.bind(this)); 
		}else{
			$$(this.element,this.menu).addEvents({'mouseover':function(e){
				if(!this.status)this.show();					
				if(this.timer)$clear(this.timer);
			}.bind(this),'mouseleave':function(){
				if(!this.status)return;
				this.timer=this.hide.delay(200,this);
			}.bind(this)});	
		}
		this.menu.addEvent('click',function(e){
			if(options.stopEl)return e.stop();
			return this.hide();
		}.bind(this));
		return this;
	},
	load:function(){		
		if(this.options.relative)
		this.position({page: this.element.getPosition(this.options.relative)});
		return this.fireEvent('load',[this.element,this]);
	},
	show:function(){	
		this.element.addClass(this.options.dropClass);	
		this.options.showMode.call(this,this.menu);
		this.status=true;
		return this.fireEvent('show',this.menu);
	},
	hide:function(){		
		this.options.hideMode.call(this,this.menu);			
		this.element.removeClass(this.options.dropClass);
		this.status=false;
		this.fireEvent('hide',this.menu);
	},
	position:function(event){	
		var options=this.options,relative=$(options.relative),
			size = (relative||window).getSize(), scroll = (relative||window).getScroll();
		var menu = {x: this.menu.offsetWidth, y: this.menu.offsetHeight};
		var props = {x: 'left', y: 'top'};
		for (var z in props){
			var pos = event.page[z] + this.options.offset[z];
			if ((pos + menu[z] - scroll[z]) > size[z]) pos = event.page[z] - this.options.offset[z] - menu[z];
			this.menu.setStyle(props[z], pos);
		}		
	},
	outMenu:function(){
		var _this=this;
		document.body.addEvent('click',function(e){
			if(_this.options.stopEl!=e.target&&_this.menu){
				_this.hide.call(_this);
				$clear(_this.showTimer);
				this.removeEvent('click',arguments.callee); 			
			}
		});	
	}	
});

var Popup = new Class({
	Implements: [Events, Options],
    options: {
        trigger: null,
        eventType: 'click',
		type: 'dialog',
        template: null,
		width: 0,
		height: 0,
		title:'提示' ,
        autoHide: false,
		/* onLoad: function(){},
		 * onShow: function(){},
		 * onClose: function(){},*/
		modal: false,
		pins: false,
		single: false,
		minHeight:220,
		minWidth:270,
		effect: {
			style: 'opacity',
			duration: 400,
			from: 0,
			to: 1
		},
		position: {
			target: document,
			base: {x: 'center',	y: 'center'},
			to: {x: 'center',	y: 'center'},
			offset: {x: 0, y: 0},
            intoView: false
		},
        useIframeShim: false,
		async: false,
        frameTpl: '<iframe allowtransparency="allowtransparency" align="middle" frameborder="0" height="100%" width="100%" scrolling="auto" src="about:blank">请使用支持iframe框架的浏览器。</iframe>',
        ajaxTpl: '<div class="loading">loading...</div>',
		asyncOptions: {
			method: 'get',
			data: '',
			onSuccess: function() {},
			onError: function() {}
		},
		component: {
			container: 'popup-container',
			body: 'popup-body',
			header: 'popup-header',
			close: 'popup-btn-close',
			content: 'popup-content',
			mask: 'popup-modalMask'
		}
	},
	initialize: function(target, options) {
		if (!target) return;
        this.target = target;
		this.setOptions(options);
		options = this.options;

		var popUp = this.popUp = this.setTemplate(options.template);
        popUp.setStyle('display','none');
		var el = new Element('div');
		this.body = popUp.getElement('.' + options.component.body) || el;
		this.header = popUp.getElement('.' + options.component.header) || el;
		this.close = popUp.getElement('.' + options.component.close) || el;
		this.content = popUp.getElement('.' + options.component.content) || el;
		this.size = {
			x: options.width.toInt() ? options.width.toInt() : '',
			y: options.height.toInt() ? options.height.toInt() : ''
		};
		if(!(options.single && popUp.retrieve('instance'))) this.body.setStyles({
			width: this.size.x,
			height: this.size.y
		});
        if(!options.title) this.header.getElement('h2') && this.header.getElement('h2').destroy();
        if (typeOf(target) === 'string') {
            if (options.async === 'ajax') {
                new Request.HTML({
                    url: target + '',
                    update: this.content,
                    method: options.asyncOptions.method,
                    data: options.asyncOptions.data,
                    onSuccess: options.asyncOptions.onSuccess.bind(this),
                    onFailure: options.asyncOptions.onError.bind(this)
                }).send();
                if(!this.size.y && popUp.getSize().y >= document.body.getSize().y){
                    this.size.y = Math.min(options.minHeight.toInt(), document.body.getSize().y);
                    $(this.body).setStyle('height', this.size.y - this.popUp.getPatch().y);
                }
            }
            else this.content.getElement('iframe').set('src', target).addEvent('load', this.options.asyncOptions.onSuccess.bind(this));
        }
		if (options.modal && !document.getElement('div.' + options.component.mask)) {
			this.mask = new Mask({
				'class': options.component.mask,
				'effect': options.effect
			});
		}
		this.attach(); //执行初始化加载
	},
	getTemplate: function(template, type) {
        var options = this.options;
        template = template || options.template;
        if (template && typeOf(template) === 'string') {
			if(!document.id(template)) return template;
			template = $(template);
		}
        if (typeOf(template) === 'element' && (/^(?:script|textarea)$/i).test(template.tagName.toLowerCase())) return $(template).get('value') || $(template).get('html');
		type = type || options.type;
		var popUpTpl = [
			'<div class="{body}">',
			'<div class="{header}">',
			'<h2>{title}</h2>',
			'<span><button type="button" class="{close}" title="关闭" hidefocus><i>×</i></button></span>',
			'</div>',
			'<div class="{content}">{main}</div>',
			'</div>'
		];
		if (type === 'nohead') popUpTpl[1] = popUpTpl[2] = popUpTpl[3] = popUpTpl[4] = '';
		else if (type === 'notitle') popUpTpl[2] = '';
		else if (type === 'noclose' || !!options.autoHide) popUpTpl[3] = '';

        return popUpTpl.join('\n');
	},
    setTemplate: function(template) {
        var options = this.options,
            single = document.getElement('[data-single=true].' + options.component.container);
            main = '';

        if(options.single && single) return single;

        template = '<div class="{container}" data-single="'+ options.single +'">' + this.getTemplate(template) + '</div>';
        if (typeOf(this.target) === 'element') {
            main = this.target.get('html');
        }
        else if (typeOf(this.target) === 'string') {
            main = options.async === 'ajax' ? options.ajaxTpl : options.frameTpl;
        }

		var component = Object.merge(options.component, {
			title: options.title,
			main: main
		});
        return new Element('div', {html: template.substitute(component)}).getFirst().inject(document.body);
    },
	attach: function() {
        this.fireEvent('load', this);
        var trigger = $$(this.options.trigger);
        if(trigger.length){ 
            trigger.addEvent(this.options.eventType, this.show.bind(this));
        } else {// add
Element.implement({
    //获取padding,margin,border值
	getPatch: function() {
		var args = arguments.length ? Array.from(arguments) : ['margin', 'padding', 'border'];
		var _return = {
			x: 0,
			y: 0
		};

		Object.each({x: ['left', 'right'], y: ['top', 'bottom']}, function(p2, p1) {
			p2.each(function(p) {
				try {
					args.each(function(arg) {
						arg += '-' + p;
						if (arg == 'border') arg += '-width';
						_return[p1] += this.getStyle(arg).toInt() || 0;
					}, this);
				} catch(e) {}
			}, this);
		}, this);
		return _return;
	},
    // the elements outer size
	outerSize: function(){
        if(this.getStyle('display') === 'none') return {x: 0, y: 0};
		return {
			x: (this.getStyle('width').toInt() || 0) + this.getPatch().x,
			y: (this.getStyle('height').toInt() || 0) + this.getPatch().y
		};
	}
});

            this.show();
        }
		//绑定关闭事件
		var closeBtn = this.popUp.getElements('.' + this.options.component.close);
		if (closeBtn.length) closeBtn.addEvent('click', this.hide.bind(this));
		this.popUp.store('instance', this);
	},
    position: function(){
        console.info(this.options);
        var options = this.options, element;
		if (options.single && this.popUp.retrieve('instance')) return;
        if (!this.size.x && Browser.ie && Browser.version < 8 && (this.body.getSize().x >= window.getSize().x)) this.body.setStyle('width', this.options.minWidth.toInt());
        if (this.size.y) element = this.popUp;
        else if(this.popUp.getSize().y >= document.body.getSize().y) element = document.body;
        if(typeOf(element) === 'element') this.setHeight(element);
        console.info(options.position);
        this.popUp.position(options.position);
        if (options.pins) this.popUp.pin();
    },
	setHeight: function(el) {
		this.content.setStyle('height', el.getSize().y - this.popUp.getPatch().y - $(this.body).getPatch().y - $(this.header).outerSize().y - this.content.getPatch().y);
	},
	//弹出可见
	show: function() {
        if(this.displayed) return this;
        this.popUp.setStyle('display', 'block');

		if(window.ie6 && this.options.useIframeShim) {
			new Element('iframe', {
				src: 'about:blank',
				style: 'position:absolute;z-index:-1;border:0 none;filter:alpha(opacity=0);top:-' + (this.popUp.getPatch().y || 0) + ';left:-' + (this.popUp.getPatch().x || 0) + ';width:' + (this.popUp.getSize().x || 0) + 'px;height:' + (this.popUp.getSize().y || 0) + 'px;'
			}).inject(this.popUp);
		}

		this.position();
		var eff = this.options.effect;
		if(eff) {
			if(eff === true || eff.style === 'opacity') this.popUp.setOpacity(eff.from || 0);
			new Fx.Tween(this.popUp,{duration:eff.duration || 400}).start(eff.style || 'opacity', eff.from || 0, eff.to || 1);
		}
		this.displayed = true;
		this.fireEvent('show', this);

		if (this.mask) this.mask.show();
        if (this.options.autoHide) this.hide.delay(this.options.autoHide.toInt() * 1000, this);

		return this;
	},
	//弹出隐藏
	hide: function() {
        if (!this.displayed) return this;
		this.fireEvent('close', this);
		if(this.options.pins) this.popUp.pin(false, false, false);
		var eff = this.options.effect;
		if(eff) {
          	new Fx.Tween(this.popUp, {
				duration: eff.duration || 400,
				onComplete: function(){
					this.popUp.setStyle('display','none');
				}.bind(this)
			}).start(eff.style || 'opacity', eff.to || 1, eff.from || 0);
		}
		else {
			this.popUp.setStyle('display','none');
		}
		this.displayed = false;
		if (this.mask && ($$('.' + this.options.component.container).every(function(el) {
			return !this.displayed;
		}.bind(this)))) this.mask.hide();
        return this;
	},
	toElement: function() {
		return this.popUp;
	}
});

// pin
(function(){
	Element.implement({
		pin: function(enable, forceScroll, restore){
			//if(this.getStyle('display') == 'none') this.setStyle('display', '');
			if (enable !== false){
				if (!this.retrieve('pin:_pinned')){
					var scroll = window.getScroll();
					this.store('pin:_original', this.getStyles('position', 'top', 'left'));
					var pinnedPosition = this.getPosition(!window.ie6 ? document.body : this.getOffsetParent());
					var currentPosition = {
						left: pinnedPosition.x - scroll.x,
						top: pinnedPosition.y - scroll.y
					};
					if (!window.ie6){
						this.setStyle('position', 'fixed').setStyles(currentPosition);
					} else {
						if(!!forceScroll) this.setPosition({
							x: this.getOffsets().x + scroll.x,
							y: this.getOffsets().y + scroll.y
						});
						if (this.getStyle('position') == 'static') this.setStyle('position', 'absolute');

						var position = {
							x: this.getLeft() - scroll.x,
							y: this.getTop() - scroll.y
						};
						var scrollFixer = function(){
							if (!this.retrieve('pin:_pinned') || this.getStyle('left').toInt() >= document.body.clientWidth || this.getStyle('top').toInt() >= document.body.clientHeight) return;
							var scroll = window.getScroll();
							this.setStyles({
								left: position.x + scroll.x,
								top: position.y + scroll.y
							});
						}.bind(this);

						this.store('pin:_scrollFixer', scrollFixer);
						window.addEvent('scroll', scrollFixer);
					}
					this.store('pin:_pinned', true);
				}
			} else {
				if (!this.retrieve('pin:_pinned')) return this;
				if(!!restore) this.setStyles(this.retrieve('pin:_original', {}));
				this.eliminate('pin:_original');
				this.store('pin:_pinned', false);
				if (window.ie6) {
					window.removeEvent('scroll', this.retrieve('pin:_scrollFixer'));
					this.eliminate('pin:_scrollFixer');
				}
			}
			return this;
		},
		togglePin: function(){
			return this.pin(!this.retrieve('pin:_pinned'));
		}
	});
}).call(this);

//Mask
var Mask = new Class({
	Implements: [Options, Events],
	options: {
		target:null,
		'class': 'mask',
		width: 0,
		height: 0,
		effect: {
			style: 'opacity',
			duration: 400,
			from: 0,
			to: 0.3
		}
	},
	initialize: function(options) {
		this.target = (options && options.target) || document.id(document.body);
		//this.target.store('mask', this);
		this.setOptions(options);

		this.element = new Element('div.' + this.options['class']).inject(this.target);
		this.hidden = true;
	},
	setSize: function() {
		this.element.setStyles({
			width: this.options.width.toInt() || Math.max(this.target.getScrollSize().x, this.target.getSize().x, this.target.clientWidth),
			height: this.options.height.toInt() || Math.max(this.target.getScrollSize().y, this.target.getSize().y, this.target.clientHeight)
	});
	},
	show: function() {
		if (!this.hidden) return;
		window.addEvent('resize', this.setSize.bind(this));
		this.setSize();

		this.element.setStyle('display','block');
		var eff = this.options.effect;
		if(eff) {
			this.opacity = this.element.get('opacity');
			if(eff === true || eff.style == 'opacity') this.element.setOpacity(eff.from || 0);
			new Fx.Tween(this.element,{duration:eff.duration || 400}).start(eff.style || 'opacity', eff.from || 0, this.opacity);
		}
		this.hidden = false;
	},
	hide: function() {
		if (this.hidden) return;
		window.removeEvent('resize', this.setSize.bind(this));

		var eff = this.options.effect;
		if(eff) {
			new Fx.Tween(this.element, {
				duration:eff.duration || 400,
				onComplete: function(){
					this.element.setStyle('display','none');
				}.bind(this)
			}).start(eff.style || 'opacity', this.opacity, eff.from || 0);
		}
		else {
			this.element.setStyle('display','none');
		}
		this.hidden = true;
	},
	toggle: function() {
		this[this.hidden ? 'show' : 'hide']();
	}
});

(function(){
Element.implement({
    //the elements position
	position: function(options){
		options = Object.merge({
			target: document.body,
			to: {x:'center', y:'center'}, //定位到目标元素的基点
			base: {x:'center', y:'center'}, //此元素定位基点 --为数值时类似offset
			offset: {
				x: 0,
				y: 0
			},
            // true 或 to:滑动使this可视。in:把this限制在视窗内
            intoView: false
		}, options);

		this.setStyle('position', 'absolute');

		var el = options.target;
		var base = getOffset(this, options.base);
		var to = getOffset(el, options.to);
		var x = to.x - base.x + el.getPosition().x + el.getScroll().x + options.offset.x;
		var y = to.y - base.y + el.getPosition().y + el.getScroll().y + options.offset.y;

        if(options.intoView === 'in'){
            x = x.limit(0, window.getScroll().x + window.getSize().x - this.getSize().x);
            y = y.limit(0, window.getScroll().y + window.getSize().y - this.getSize().y);
        }

		this.setStyles({
			left: x,
			top: y
		});
        if(options.intoView === true || options.intoView === 'to') new Fx.Scroll(document).scrollIntoView(this);
        return this;
	}
});
//取得九点定位的坐标
function getOffset(el, base) {
	var size = el.getSize(), x, y;
	base = base || {x: 'center', y: 'center'};
	switch(base.x.toString().toLowerCase()) {
	case '0':
	case 'left':
		x = 0;
		break;
	case '100%':
	case 'right':
		x = size.x;
		break;
	case '50%':
	case 'center':
		x = size.x / 2;
		break;
	default:
		x = base.x.toInt();
        break;
	}
	switch(base.y.toString().toLowerCase()) {
	case '0':
	case 'top':
		y = 0;
		break;
	case '100%':
	case 'bottom':
		y = size.y;
		break;
	case '50%':
	case 'center':
		y = size.y / 2;
		break;
	default:
		y = base.y.toInt();
        break;
	}

	return {x: x, y: y};
}
})();

// add
Element.implement({
    //获取padding,margin,border值
	getPatch: function() {
		var args = arguments.length ? Array.from(arguments) : ['margin', 'padding', 'border'];
		var _return = {
			x: 0,
			y: 0
		};

		Object.each({x: ['left', 'right'], y: ['top', 'bottom']}, function(p2, p1) {
			p2.each(function(p) {
				try {
					args.each(function(arg) {
						arg += '-' + p;
						if (arg == 'border') arg += '-width';
						_return[p1] += this.getStyle(arg).toInt() || 0;
					}, this);
				} catch(e) {}
			}, this);
		}, this);
		return _return;
	},
    // the elements outer size
	outerSize: function(){
        if(this.getStyle('display') === 'none') return {x: 0, y: 0};
		return {
			x: (this.getStyle('width').toInt() || 0) + this.getPatch().x,
			y: (this.getStyle('height').toInt() || 0) + this.getPatch().y
		};
	}
});

window.addEvent('domready',Switchable.autoRender.bind(Switchable));

