;(function($,undefined){
	var _timer=[],
		_fw=window._fw=function(){
			var argms=arguments
			this.each(function(){
				var th=$(this)					
				for(var i=0,opt={};i<argms.length;i++)
					if(typeof argms[i]==typeof '')
						if(_fw[argms[i]]!=undefined)
							$.extend(opt,_fw[argms[i]]),
							th.data(argms[i],opt)
						else
							void(0)//coming soon ajax script loader
					else
						if(typeof argms[i]==typeof {})
							$.extend(opt,argms[i])
				if(th.data('opt'))
					$.extend(opt,th.data('opt'))
				opt.init.call(th,opt)
			})			
			return this
		}
		
	//modules
	_fw=$.extend(_fw,{
		"_sliderCF":{
			show:false,
			items:'>ul>li',
			duration:400,
			easing:'',
			slideshow:false,
			changeEv:'_change',
			showEv:'_show',
			nextEv:'_next',
			prevEv:'_prev',
			pagEv:'click',
			pagination:false,
			currCl:'current',
			navLinks:'a[rel=nav]',
			pagActiveCl:'active',
			pagArea:'a',			
			animationCallback:function(){},
			preFu:function(){
				var opt=this,
					items=opt.itms,
					holder=opt.holder
				if(holder.css('position')!='absolute')
					holder.css({position:'relative'})
				holder.width(items.eq(0).width())
				holder.height(items.eq(0).height())
				items.each(function(i){
					$(this)
						.css({position:'absolute',left:0,top:0,zIndex:-1})
						.data({num:i})
				}).show()
			},
			changeFu:function(data){
				var opt=this,
					holder=opt.holder,
					items=opt.itms,
					tmp=(typeof data==typeof '')?$(data,holder)
						:(typeof data==typeof 1)?(function(){
													var ret
													items.each(function(){
														if($(this).data('num')==data)
														ret=this
													})
													return $(ret)
												})()
						:(data instanceof $)?data
						:$(data)
				clearTimeout(_timer[holder.data('_timer')])
				holder.data({curr:tmp,currN:tmp.data('num'),lastReq:data})
				opt.showFu()
				if(opt.slideshow)
					_timer[holder.data('_timer')]=setTimeout(function(){opt.nextFu()},opt.slideshow)
			},
			showFu:function(){
				var opt=this,
					holder=opt.holder,
					curr=holder.data('curr'),
					tmp
				if(opt.currCl)
					$(opt.items,holder).removeClass(opt.currCl),
					curr.addClass(opt.currCl)
				curr
					.show()
					.stop()
					.css({opacity:((tmp=curr.css('opacity'))==1)?0:tmp,left:0,top:0})
					.appendTo(curr.parent())
					.animate({opacity:1},{
							 duration:opt.duration,
							 easing:opt.easing,
							 complete:function(){
								 $(this).siblings().css({opacity:1}).hide()
								 opt.animationCallback.call(this)
							}
					})
					.siblings()
						.stop()
				holder.trigger(opt.showEv,curr.data('num'))
			},			
			nextFu:function(){
				var	opt=this,
					holder=opt.holder,
					items=opt.itms,
					currN=holder.data('currN')

				if(items.length>currN+1)
					holder.trigger(opt.changeEv,currN+1)
				else
					holder.trigger(opt.changeEv,0)
					
				return opt
			},			
			prevFu:function(){
				var opt=this,
					holder=opt.holder,
					items=opt.itms,
					currN=holder.data('currN')

				if(currN-1)
					holder.trigger(opt.changeEv,currN-1)
				else
					holder.trigger(opt.changeEv,-1)
			},
			pagFu:function(){
				var opt=this,
					holder=opt.holder,
					pags
				if(typeof opt.pagination==typeof '')
					pags=opt.pags=$(opt.pagination),
					pags.each(function(i){
						var th=$(this),
							tmp
						th.data({
							num:i
						})
					})
				pags.parent()
					.delegate(opt.pagination+':not(.'+opt.pagActiveCl+')'+(opt.pagArea?' '+opt.pagArea:''),opt.pagEv,function(){
						var th=$(this),
							li=opt.pagArea?th.praParent('li'):th
							holder.trigger(opt.changeEv,li.data('num'))
						return false
					})
					.delegate(opt.pagination+'.'+opt.pagActiveCl+(opt.pagArea?' '+opt.pagArea:''),opt.pagEv,function(){
						return false
					})
				holder.bind(opt.showEv,function(e,data){
					pags.eq(data).addClass(opt.pagActiveCl).siblings().removeClass(opt.pagActiveCl)
				})
			},
			init:function(opt){
				var holder=opt.holder=this,
					items=opt.itms=$(opt.items,holder)
				opt.preFu()
				if(opt.pagination!==false)
					opt.pagFu()
				if(opt.navLinks!==false)
					$(opt.navLinks).live(opt.pagEv,function(){
						holder.trigger(opt.changeEv,this.href)
						return false
					})
				
				holder
					.bind(opt.changeEv,function(e,data){
						opt.changeFu(data)
						return false
					})
					.bind(opt.nextEv,function(){
						opt.nextFu()
						return false
					})
					.bind(opt.prevEv,function(){
						opt.prevFu()
						return false
					})
				if(opt.show!==false)
					holder.trigger(opt.changeEv,opt.show)
				if(opt.slideshow)
					holder.data({_timer:_timer.length})
				return this
			}
		},
		"_ajaxSlider":{
			spinner:false,
			navLinks:'a[rel=nav]',
			pagArea:'>a',
			pagActiveCl:'active',
			pagEv:'click',
			showEv:'_show',
			changeEv:'_change',
			pagination:false,
			animationCallback:function(){},
			pagFu:function(){
				var opt=this,
					pags=opt.pags=$(opt.pagination)
				pags.parent()
					.delegate(opt.pagination+':not(.'+opt.pagActiveCl+')'+(opt.pagArea?' '+opt.pagArea:''),opt.pagEv,function(){
						var th=$(this)
						pags.removeClass(opt.pagActiveCl)
						th.praParent('li').addClass(opt.pagActiveCl)
						opt.changeFu(th)
						return false
					})
					.delegate(opt.pagination+'.'+opt.pagActiveCl+(opt.pagArea?' '+opt.pagArea:''),opt.pagEv,function(e){
						return false
					})
			},
			changeFu:function(data){
				var opt=this
				opt.holder.data({url:data.attr('href')})
				opt.showFu()
				opt.holder.trigger(opt.changeEv)
			},
			showFu:function(){
				var opt=this,
					holder=opt.holder,
					spinner=$(opt.spinner),
					url=holder.data('url')
				holder.append(spinner)
				holder.load(url,{},function(){
					spinner.remove()
					opt.animationCallback.call(holder,opt)
				})
				holder.trigger(opt.showEv,url)
			},
			init:function(opt){
				var holder=opt.holder=this
				if(opt.pagination)	
					opt.pagFu()
				if(opt.navLinks)
					$(opt.navLinks).live(opt.pagEv,function(){
						var th=$(this),
							tmp
						if((tmp=th.data('opt'))!=undefined&&tmp.clearPags)
							$(opt.pagination).removeClass(opt.pagActiveCl)
						opt.changeFu(th)
						return false
					})
				return this
			}
		},
		"_vSlider":{
			show:false,
			cloneCl:'_clone',
			clone:false,
			preFu:function(){
				var opt=this,
					holder=opt.holder,
					items=opt.itms,
					ul=opt.ul,
					itemH=items.outerHeight()+parseInt(items.css('marginBottom'))+parseInt(items.css('marginTop'))
				if(opt.clone)
					items.clone().addClass(opt.cloneCl).appendTo(ul),
					items=$(opt.items,opt.holder)
				holder.data({itemH:itemH})
				if(opt.show)
					holder
						.height(itemH*opt.show)
						.css({overflow:'hidden',zIndex:1})
				if(holder.css('position')!='absolute')
					holder.css({position:'relative',zIndex:1})
				ul.css({position:'relative'})
				var tmp=Math.round(items.length/2),
					i=tmp
				while(i--)
					items.eq(-1).prependTo(ul)
				ul.css({top:-Math.floor(tmp/2)*itemH})
					.data({sY:-Math.floor(tmp/2)*itemH})
				return opt
			},
			nextFu:function(opt){
				var opt=this
				opt.holder.trigger(opt.changeEv,'next')
			},
			prevFu:function(opt){
				var opt=this
				opt.holder.trigger(opt.changeEv,'prev')
			},
			changeFu:function(data){
				var opt=this
					holder=opt.holder,
					items=opt.itms=$(opt.items,holder),
					ul=opt.ul,
					itemH=holder.data('itemH')
				if(data=='next'||data=='prev')
					if(data=='next')
						items.eq(-1)
							.prependTo(items
									   	.parent().stop().css({
															top:parseInt(ul.css('top'))-itemH
															})
										)
					else
						items.eq(0)
							.appendTo(items
										.parent().stop().css({
															top:parseInt(ul.css('top'))+itemH
															})
										)
				opt.showFu.call(opt)
			},
			showFu:function(){				
				var opt=this,
					holder=opt.holder,
					items=opt.itms,
					ul=opt.ul,
					itemH=holder.data('itemH')
				ul.stop().animate({
					top:ul.data('sY')
					},{
					duration:opt.duration,
					easing:opt.easing,
					complete:function(){
						opt.animationCallback.call(holder)
					}
				})				
				holder.trigger(opt.showEv)
			},
			init:function(opt){
				var holder=opt.holder=this,
					items=opt.itms=$(opt.items,holder),
					ul=opt.ul=items.parent()
				opt.preFu(opt)

				holder
					.bind(opt.changeEv,function(e,data){
						opt.changeFu(data)
						return false
					})
					.bind(opt.nextEv,function(){
						opt.nextFu()
						return false
					})
					.bind(opt.prevEv,function(){
						opt.prevFu()
						return false
					})
				if(opt.show!==false)
					opt.changeFu('next')
				if(opt.slideshow)
					holder.data({_timer:_timer.length})
				return this
			}
		},
		"_tabs":{
			current:0,
			animationCallback:function(){},
			duration:400,
			easing:'',
			pagination:'>ul>li',
			items:'.items>li',
			currentCl:'current',
			pagActiveCl:'active',
			changeEv:'_change',
			showEv:'_show',
			pagEv:'click',
			preFu:function(){
				var opt=this
					holder=opt.holder,
					items=opt.itms,
					tagName=items.attr('tagName')
				items.each(function(i){
					$(this)
						.data({num:i})
						.hide()
				})
				
				return opt
			},
			pagFu:function(){
				var opt=this,
					holder=opt.holder,
					pags=opt.pags=$(opt.pagination)
				pags.each(function(i){
					$(this).data({num:i})
				})
				pags.parent()
					.delegate(opt.pagination+':not(.'+opt.pagActiveCl+')'+(opt.pagArea?' '+opt.pagArea:''),opt.pagEv,function(){
						var th=$(this)
						holder.trigger(opt.changeEv,th.data('num'))
						return false
					})
				holder.bind(opt.showEv,function(){
					var currN=holder.data('currN')
					pags.each(function(){
						var th=$(this)
						if(th.data('num')==currN)
							th.addClass(opt.pagActiveCl)
						else
							th.removeClass(opt.pagActiveCl)
					})
					return false
				})
				return opt
			},
			changeFu:function(data){
				var opt=this,
					holder=opt.holder,
					curr=opt.itms.eq(data)
				holder.data({curr:curr,currN:curr.data('num'),lastReq:data})
				opt.showFu()
				holder.trigger(opt.showEv,data)
			},
			showFu:function(){
				var opt=this,
					holder=opt.holder,
					items=opt.itms,
					currN=holder.data('currN')
				items.each(function(){
					var th=$(this)
					if(th.data('num')==currN)
						th
							.css({opacity:0})
							.show()
							.stop()
							.animate({opacity:1
									},{
									 duration:opt.duration,
									 easing:opt.easing,
									 complete:function(){
											 opt.animationCallback.call(this)
											}
									})
					else
						th.hide()
				})
			},
			init:function(opt){
				var holder=opt.holder=this,
					items=opt.itms=$(opt.items,holder)
				opt.preFu()
				holder
					.bind(opt.changeEv,function(e,data){
						opt.changeFu(data)
						return false
					})
				if(opt.pagination)
					opt.pagFu()
				if(opt.current!=undefined)
					holder.trigger(opt.changeEv,opt.current)
				return holder
			}
		},
		"_dropDownMenu":{
			showEv:"mouseenter",
			hideEv:'mouseleave',
			items:'>li',
			visibleCl:'_visible',
			hiddenCl:'_hidden',
			expandCl:'_active',
			area:false,
			easing:'',
			duration:666,
			wait:1000,
			enable:true,
			enableData:'dropDownEnable',
			animationCallback:function(){},
			preFu:function(opt){
				opt.ul.hide()
				return opt
			},
			showFu:function(opt){
				if($.browser.msie&&$.browser.version=='7.0')
				opt.ul.show()
				else
				opt.ul					
					.show()
					.stop()
					.animate({
						opacity:1
						},{
						duration:opt.duration,
						easing:opt.easing,
						complete:function(){
									opt.ul.removeClass(opt.hiddenCl).addClass(opt.visibleCl)
									opt.animationCallback.call(this)
								}
						})
			},
			hideFu:function(opt){
				if($.browser.msie&&$.browser.version=='7.0')
				opt.ul.hide()
				else
				opt.ul
					.stop()
					.animate({
						opacity:0
						},{
						duration:opt.duration,
						easing:opt.easing,
						complete:function(){
									opt.ul.hide().removeClass(opt.visibleCl).addClass(opt.hiddenCl)
									opt.animationCallback.call(this)
								}
						})
			},
			init:function(opt){
				var ul=opt.ul=this,
					holder=opt.holder=this.parent(),
					items=opt.items=$(opt.items,ul),
					area=opt.area?holder.find(opt.area):holder,
					timer=opt._timer=_timer[_timer.length]=''
				opt=opt.preFu.call(this,opt)||opt
				holder.data(opt.enableData,opt.enable)
				area
					.bind(opt.showEv,function(){
						if(holder.data(opt.enableData))
							clearTimeout(opt._timer),
							holder.addClass(opt.expandCl),
							opt.showFu.call(ul,opt)
						return false
					})
				ul
					.bind(opt.showEv,function(){
						if(holder.data(opt.enableData))
							clearTimeout(opt._timer),
							holder.addClass(opt.expandCl),
							opt.showFu.call(ul,opt)
						return false
					})
				holder
					.bind(opt.hideEv,function(){
						if(holder.data(opt.enableData))
							opt._timer=setTimeout(function(){
								holder.removeClass(opt.expandCl)
								opt.hideFu.call(ul,opt)
							},opt.wait)
					})
			}
		},
		"_spinnerGallery":{
			spinnerURL:false,
			fader:false,
			spinner:false,
			pagination:false,
			pagArea:'>a',
			pagEv:'click',
			navLinks:'a[rel=spinnerGallery]',
			spinnerClassName:'_spinner',
			faderClassName:'_fader',
			showEv:'_show',
			minSleep:400,
			faderOpacity:.6,
			faderColor:'#fff',
			css:{position:'absolute',left:0,top:0,right:0,bottom:0,zIndex:9999},
			pagFu:function(){
				var opt=this,
					pags=opt.pags=$(opt.pagination)
				pags.parent()
					.delegate(opt.pagination+':not(.'+opt.pagActiveCl+')'+(opt.pagArea?' '+opt.pagArea:''),opt.pagEv,function(){
						opt.showFu(this.href)
						return false
					})
			},
			showFu:function(data){
				var opt=this
				opt.fader=$('<div>')
							.css(opt.css)
							.css({
								backgroundColor:opt.faderColor,
								opacity:0
							})
							.appendTo(opt.holder)
							.stop()
							.animate({
									opacity:opt.faderOpacity
									 },{
									duration:opt.minSleep/2,
									complete:function(){
										opt.outOfSpace
											.load(function(){
												opt.pic.attr({src:this.src})
												setTimeout(function(){
												opt.hideFu()
											},opt.minSleep)
										})
										.attr({src:data})
									}
							})
				opt.spinner=$('<div>')
							.css(opt.css)
							.css({
								 background:'url('+opt.spinnerURL+') 50% 50% no-repeat'
							})
							.appendTo(opt.holder)				
			},
			hideFu:function(){
				var opt=this
				opt.spinner.remove()
				opt.fader.stop().animate({
										opacity:0
										 },{
										duration:opt.minSleep/2,
										complete:function(){
											opt.fader.remove()
										}
								})
			},
			init:function(opt){
				var holder=opt.holder=this,
					pic=opt.pic=$('img',holder),
					outOfSpace=opt.outOfSpace=$('<img>')					
				if(!opt.spinnerURL)
					return this
				if(holder.css('position')!='absolute')
					holder.css({position:'relative'})
				holder.bind(opt.showEv,function(e,data){
					opt.showFu(data)
					return false
				})
				if(opt.pagination)
					opt.pagFu()
			}
		},
		"_forms":{
			target:'input[type=text],input[type=password],input[type=tel],input[type=email],textarea',
			buttons:'a[rel=reset],a[rel=submit]',
			event:'click',
			init:function(opt){
				var form=opt.form=this,
					inputs=opt.inputs=$(opt.target,form)
				inputs.each(function(){
					var th=$(this)
					th.data({defValue:th.attr('value')})
					th
						.bind('focus',function(){
							if(th.attr('value')==th.data('defValue'))
								th.attr({value:''})
						})
						.bind('blur',function(){
							if(th.attr('value')=='')
								th.attr({value:th.data('defValue')})
						})					
				})
				$(opt.buttons,form).each(function(){
					var th=$(this)
					th.bind(opt.event,function(){											   
						form.attr(this.rel).call(form[0])
						return false
					})
				})
			}
		}
	})
	
	//jQuery methods
	$.fn.extend({
		"_fw":function(name,opt){
			return _fw.call(this,name,opt)
		},
		"_sliderCF":function(opt){
			return _fw.call(this,'_sliderCF',opt)
		},
		"_ajaxSlider":function(opt){
			return _fw.apply(this,['_ajaxSlider',opt])
		},
		"_vSlider":function(opt){
			return _fw.apply(this,['_sliderCF','_vSlider',opt])
		},
		"_tabs":function(opt){
			return _fw.call(this,'_tabs',opt)
		},
		"_dropDownMenu":function(opt){
			return _fw.call(this,'_dropDownMenu',opt)
		},
		"_spinnerGallery":function(opt){
			return _fw.call(this,'_spinnerGallery',opt)
		},
		"_forms":function(opt){
			return _fw.call(this,'_forms',opt)
		}
	})
	
	

})(jQuery)

//Helpers
;(function($){
	$.fn.extend({
		praParent:function(name){
			var th=$(this)
			while(th=th.parent())
				if(th.is(name))
					break
				else
					if(th.is('html'))
						return false
			return th
		},
		waitImgLoad:function(fn){
			var th=this,
				img=$('img',this),
				num=img.length
			img.each(function(){
				if(!this.complete)
					$(this).load(function(){
						if(!--num)
							fn.call(th)
					})					
				else
					if(!--num)
						fn.call(th)
			})
			return this
		}
	})
})(jQuery)

function clone(obj){
	if(!obj||typeof obj!=typeof {})
		return obj
	if(obj instanceof Array)
		return [].concat(obj)
	var tmp=new obj.constructor(),
		i
	for(i in obj)
		if(obj.hasOwnProperty(i))
			tmp[i]=clone(obj[i])
	return tmp
}

