﻿(function(){

var L = chromeplus.Lang;

var Collections = {

	_comparators:null,

	toArray:function(nodeList,comparator){

		var nominees = [];

		if(nodeList){

			for(var i=0,len=nodeList.length;i<len;i++)

				nominees.push(nodeList[i]);

			if(L.isFunction(comparator))

				nominees.sort(comparator);

		}

		return nominees;

	},

	forEach:function(nodeList,fn,scope){

		if(L.isArray(nodeList))

			nodeList.forEach(fn,scope);

		else{

			for(var i=0,len=nodeList.length>>>0;i<len;i++){

				fn.call(scope,nodeList[i],i,this);

			}

		}

	},

	comparator:function(type,reverse){

		var C = L.Constraint, anwser = null;

		if(!this._comparators)

			this._comparators = [];

		switch(type){

			case C.NUMBER:

				if(!this._comparators[type])

					this._comparators[type] = [];

				anwser = (reverse === true) ? 

						( this._comparators[type][1] ? this._comparators[type][1] : (this._comparators[type][1] = function(a,b){return b - a;}) ) : 

							( this._comparators[type][0] ? this._comparators[type][0] : (this._comparators[type][0] = function(a,b){return a - b;}) );

				break;

			case C.STRING:

				if(!this._comparators[type])

					this._comparators[type] = [];

				anwser = (reverse === true) ? 

						( this._comparators[type][1] ? this._comparators[type][1] : (this._comparators[type][1] = function(a,b){return b.localeCompare(a);}) ) : 

							( this._comparators[type][0] ? this._comparators[type][0] : (this._comparators[type][0] = function(a,b){return a.localeCompare(b);}) );

				break;

			case C.DATE:

				if(!this._comparators[type])

					this._comparators[type] = [];

				anwser = (reverse === true) ? 

						( this._comparators[type][1] ? this._comparators[type][1] : (this._comparators[type][1] = function(a,b){return b.getTime()-a.getTime();}) ) : 

							( this._comparators[type][0] ? this._comparators[type][0] : (this._comparators[type][0] = function(a,b){return a.getTime()-b.getTime();}) );

				break;

			default:

		}

		return anwser;

	}

}



var Cookie = {

	setCookie:function(name,value,expires,path,domain,secure){

		if(!name || !value)

			return;

		var candidate = [];

		candidate.push(name+"="+encodeURIComponent(value));

		if(expires)

			candidate.push("expires="+expires.toGMTString());	

		if(path)

			candidate.push("path="+path);	

		if(domain)

			candidate.push("domain="+domain);

		if(secure)

			candidate.push("secure");

		document.cookie = candidate.join(";");	

	},

	getCookie:function(name){

		var res = "(?:; )?"+name+"=([^;]*);?";

		var re = new RegExp(res);

		if(re.test(document.cookie))

			return decodeURIComponent(RegExp["$1"]);

		else

			return null;	

	},

	deleteCookie:function(name,path,domain){

		this.setCookie(name,"",new Date(0),path,domain);

	}

}



var Toolkit = {

	validate:function(){

		var hd = document.getElementById("hd"),bd = document.getElementById("bd"),ft = document.getElementById("ft");

		bd.style.paddingBottom = "0";

		var remaining = document.documentElement.clientHeight - hd.offsetHeight - bd.offsetHeight - ft.offsetHeight;

		if(remaining > 0)

			bd.style.paddingBottom = remaining + "px";

	},

	hasTransformFeature:function(){

		return !chromeplus.Lang.isUndefined(document.body.style.webkitTransform);

	},

	anonymousInvoke:function(fn){

		fn.call(this);

	},

	announce:function(b,callback){

		var ui = document.getElementById("inform");

		if(!ui)

			return;

		if(!b){

			ui.style.display = "none";

		}else{

			window.scrollTo(0,0);

			var kid = chromeplus.Lang.isUndefined(document.querySelector) ? ui.getElementsByTagName("div")[0] : document.querySelector("#inform>div");

			ui.style.display = "block";

			var increment = kid.offsetHeight/(300/10);

			var to = kid.offsetHeight,dynamic = 0;

			var thread = new Timer(10,function(){

				if(dynamic + increment >= to){

					ui.style.height = to + "px";

					if(chromeplus.Lang.isFunction(callback))

						callback.call(this);

				}else{

					dynamic += increment;

					ui.style.height = dynamic+"px";

					this.start();

				}

			});

			thread.start();

		}

	},

	switchHL:function(hl){

		var PATTERN = /^([^?#]+)((?:\?)*)((?:(?:&*(?!hl)[\w-]+)=(?:[\w-\.]+))*)((?:&*hl=[\w-]+)*)((?:(?:&*(?!hl)[\w-]+)=(?:[\w-\.]+))*)((?:#.+)*)$/gi;

		PATTERN.lastIndex = 0;

		if(PATTERN.test(window.location.href)){

			//capture the os quanlifier at index 4 if it's present

			var quanlifierBefore = RegExp.$1+RegExp.$2+RegExp.$3,osQuanlifier = "&hl="+hl;

			if(quanlifierBefore.endsWith("?")){

				osQuanlifier = osQuanlifier.substring(1);

			}else{

				if(RegExp.$4.empty() && !quanlifierBefore.contains("?")){

					osQuanlifier = "?"+osQuanlifier.substring(1);

				}else{

				}

			}

			Cookie.setCookie("_hl",hl,new Date(new Date().getTime() + 2*31*24*60*60*1000));

			location.assign(RegExp.$1+RegExp.$2+RegExp.$3+osQuanlifier+RegExp.$5+RegExp.$6);

		}else{

		}

	},

	switchOS:function(os){

		var PATTERN = /^([^?#]+)((?:\?)*)((?:(?:&*(?!os)[\w-]+)=(?:[\w-\.]+))*)((?:&*os=[\w-]+)*)((?:(?:&*(?!os)[\w-]+)=(?:[\w-\.]+))*)((?:#.+)*)$/gi;

		PATTERN.lastIndex = 0;

		if(PATTERN.test(window.location.href)){

			//capture the os quanlifier at index 4 if it's present

			var quanlifierBefore = RegExp.$1+RegExp.$2+RegExp.$3,osQuanlifier = "&os="+os;

			if(quanlifierBefore.endsWith("?")){

				osQuanlifier = osQuanlifier.substring(1);

			}else{

				if(RegExp.$4.empty() && !quanlifierBefore.contains("?")){

					osQuanlifier = "?"+osQuanlifier.substring(1);

				}else{

				}

			}

			location.assign(RegExp.$1+RegExp.$2+RegExp.$3+osQuanlifier+RegExp.$5+RegExp.$6);

		}

	}

}



var ClassAttributeList = function(node){

	this._node = node;

}

ClassAttributeList.prototype = {

	add:function(cls){

		if(this._validityCheck(cls) && !this.has(cls))

			this._node.className = this._node.className.btrim() + " " + cls;

		return this;

	},

	has:function(cls){

		if(!this._validityCheck(cls))

			return false;

		return this._node.className.indexOf(cls) != -1;

	},

	remove:function(cls){

		if(this._validityCheck(cls) && this.has(cls)){

			var pattern = new RegExp("((?:\\s*[\\w-]*\\s*)*)\\b("+cls+")\\b((?:\\s*[\\w-]*\\s*)*)","gi");

			if(pattern.test(this._node.className)){

				var cls = (RegExp.$1.btrim() ? RegExp.$1.btrim()+" " : "") + RegExp.$3.btrim();

				this._node.className = cls.btrim();

			}

		}

		return this;

	},

	replace:function(cls,newCls){

		if(this._validityCheck(cls) && this._validityCheck(newCls) && this.has(cls))

			this._node.className = this._node.className.replace(cls,newCls);

		return this;

	},

	toggle:function(cls){

		if(this.has(cls))

			this.remove(cls);

		else

			this.add(cls);

	},

	setNode:function(node){

		this._node = node;

		return this;

	},

	getNode:function(){

		return this._node;

	},

	_validityCheck:function(cls){

		if(!cls)

			return false;

		return true;

	}

}



function Timer(interval,actionListener){

	this._timer = null;

	this._interval = interval;

	this._actionListener = actionListener;

	this._isAlive = false;

	this._startTime = 0;

}

Timer.prototype = {

	isAlive:function(){

		return this._isAlive;

	},

	interrupt:function(){

		if(this._timer)

			clearTimeout(this._timer);

		this._timer = null;

		this._isAlive = false;

		this._startTime = 0;

	},

	setActionListener:function(l){

		if(typeof l == "function")

			this._actionListener = l;

	},

	start:function(){

		var _this = this;

		this._timer = setTimeout(function(){

			_this.interrupt();

			_this._actionListener.call(_this);

		},this._interval);

		this._startTime = (new Date()).getTime();

		this._isAlive = true;

	},

	getElapsed:function(){

		return (new Date()).getTime() - this._startTime;

	},

	setInterval:function(interval){

		if(typeof interval == "number")

			this._interval = interval;

	},

	getInterval:function(){

		return this._interval;

	}

}



var FeatureShowcase = function(UI,option){

	this._UI = UI;

	this._option = option || {};

	

	this._elements = [];

	this._selectedIndex = 0;

	this._unitIncrement = 0;

	

	this.onIndexChange = null;

	

	this._init();

}

FeatureShowcase.PREVIOUS = -2<<1;

FeatureShowcase.NEXT = -2<<2;

FeatureShowcase.prototype = {

	_init:function(){

		var R = this;

		for(var i=0,len=this._UI.list.length;i<len;i++)

			this.add(this._UI.list[i].getAttribute("alias"),this._UI.list[i]);

		if(this._elements.length)

			this._unitIncrement = this._elements[0][1].offsetWidth;

		this._UI.previous.onclick = function(){

			R.present(FeatureShowcase.PREVIOUS);

		}

		this._UI.next.onclick = function(){

			R.present(FeatureShowcase.NEXT);

		}

	},

	add:function(name,element){

		this._elements.push([name,element]);

	},

	present:function(index){

		if(index == FeatureShowcase.PREVIOUS){

			this.activate(this._selectedIndex-1<0 ? this._elements.length-1 : this._selectedIndex-1);

		}else if(index == FeatureShowcase.NEXT){

			this.activate(this._selectedIndex+1>=this._elements.length ? 0 : this._selectedIndex+1);

		}else{

			this.activate(index);

		}

	},

	getIndexByAlias:function(alias){

		for(var i=0,len=this._elements.length;i<len;i++){

			if(alias.toLowerCase() == this._elements[i][0].toLowerCase()){

				return i;

			}

		}

		return -1;

	},

	getAlias:function(index){

		if(this._rangeCheck(index))

			return this._elements[index][0];

		return null;

	},

	_translate:function(index){

		return this._rangeCheck(index) ? index*this._unitIncrement : 0;

	},

	activate:function(index){

		if(this._rangeCheck(index) && index != this._selectedIndex){

			var elapsed = this._selectedIndex;

			if(!chromeplus.Lang.isUndefined(document.body.style.webkitTransform)){

				this._UI.container.style.webkitTransform = "translate(-"+this._translate(index)+"px,0)";

			}else{

				var decrease = index < elapsed,R = this;

				//finish in 300 millseconds

				var increment = Math.floor(Math.abs(index - elapsed)*this._unitIncrement / (300/10));

				var to = this._translate(index),from = this._translate(elapsed);

				var timer = new Timer(10,function(){

					if(decrease){

						if(from - increment <= to){

							R._UI.container.style.marginLeft = -to + "px";

						}else{

							from -= increment;

							R._UI.container.style.marginLeft = -from + "px";

							this.start();

						}

					}else{

						if(from + increment >= to){

							R._UI.container.style.marginLeft = -to + "px";

						}else{

							from += increment;

							R._UI.container.style.marginLeft = -from + "px";

							this.start();

						}

					}

				});

				timer.start();

			}

			this._selectedIndex = index;

			if(chromeplus.Lang.isFunction(this.onIndexChange))

				this.onIndexChange.call(this,elapsed,this._selectedIndex);

		}

	},

	_rangeCheck:function(index){

		if(chromeplus.Lang.isNumber(index) && index in this._elements)

			return true;

		return false;

	}

}



var FlashShowcase = function(UI,option){

	this._UI = UI;

	this._option = option || {};

	

	this._elements = [];

	this._selectedIndex = -1;

	this._unitIncrement = 0;

	

	this.onIndexChange = null;

	

	this._init();

}

FlashShowcase.PREVIOUS = -2<<1;

FlashShowcase.NEXT = -2<<2;

FlashShowcase.prototype = {

	_init:function(){

		var R = this;

		for(var i=0,len=this._UI.list.length;i<len;i++)

			this.add(this._UI.list[i].getAttribute("alias"),this._UI.list[i]);

		if(this._elements.length)

			this._unitIncrement = this._elements[0][1].offsetWidth;

		this._UI.previous.onclick = function(){

			R.present(FeatureShowcase.PREVIOUS);

		}

		this._UI.next.onclick = function(){

			R.present(FeatureShowcase.NEXT);

		}

	},

	add:function(name,element){

		this._elements.push([name,element]);

	},

	present:function(index){

		if(index == FeatureShowcase.PREVIOUS){

			this.activate(this._selectedIndex-1<0 ? this._elements.length-1 : this._selectedIndex-1);

		}else if(index == FeatureShowcase.NEXT){

			this.activate(this._selectedIndex+1>=this._elements.length ? 0 : this._selectedIndex+1);

		}else{

			this.activate(index);

		}

	},

	currentItemUI:function(){

		return this._elements[this._selectedIndex][1];

	},

	currentIndex:function(){

		return this._selectedIndex;

	},

	activate:function(index){

		if(this._rangeCheck(index) && index != this._selectedIndex){

			if(!chromeplus.Lang.isUndefined(document.body.style.webkitTransform)){

				var elapsed = ((this._selectedIndex==-1) ? null : this._elements[this._selectedIndex][1]),current = this._elements[index][1];

				if(this._selectedIndex < index){
					
					if(elapsed){
						
						elapsed.style.zIndex = "10";

						if(!elapsed.getAttribute("_installed")){
							
							elapsed.addEventListener("webkitTransitionEnd",function(){

								this.style.visibility = "hidden";

								this.style.zIndex = "3";

								(new ClassAttributeList(this)).remove("rotate-left").remove("rotate-right");

							},false);

							elapsed.setAttribute("_installed","true");

						}

						var parser = new ClassAttributeList(elapsed);

						parser.add("rotate-left");

					}

					current.style.visibility = "visible";

				}else{
					
					if(elapsed){
						
						if(!elapsed.getAttribute("_installed")){

							elapsed.addEventListener("webkitTransitionEnd",function(){

								this.style.visibility = "hidden";

								this.style.zIndex = "3";

								(new ClassAttributeList(this)).remove("rotate-left").remove("rotate-right");

							},false);

							elapsed.setAttribute("_installed","true");

						}

						var parser = new ClassAttributeList(elapsed);

						parser.add("rotate-right");	

					}

					current.style.visibility = "visible";

				}

			}else{
				
				if(this._selectedIndex != -1){

					this._elements[this._selectedIndex][1].style.visibility = "hidden";

					this._elements[this._selectedIndex][1].style.zIndex = "3";

				}

				this._elements[index][1].style.visibility = "visible";

				this._elements[index][1].style.zIndex = "10";

			}

			this._selectedIndex = index;

			if(chromeplus.Lang.isFunction(this.onIndexChange))

				this.onIndexChange.call(this,elapsed,this._selectedIndex);

		}

	},

	_rangeCheck:function(index){

		if(chromeplus.Lang.isNumber(index) && index in this._elements)

			return true;

		return false;

	}

}







var TabbedPane = function(option){

	this._tabUIs = [];

	this._tabContentUIs = [];

	this._tabStates = [];

	

	this._selectedIndex = -1;

	this._elapsedIndex = -1;

	

	this._option = option || {};

	this._onStyle = this._option.onStyle?this._option.onStyle:"on";

	

	this.onTabChange = null;

}

TabbedPane.prototype = {

	_checkIndex:function(index){

		return index >= 0 && index < this._tabUIs.length;

	},

	add:function(tab,tabContent){

		tab.setAttribute("index",this._tabUIs.length);

		this._tabUIs.push(tab);

		this._tabContentUIs.push(tabContent);

		this._tabStates.push(true);

		var _this = this;

		tab.onclick = function(){

			var index = parseInt(this.getAttribute("index"));

			_this.setSelectedIndex(index);

		}

	},

	setEnabled:function(index,b){

		if((index in this._tabUIs) && (typeof b == "boolean")){

			this._tabStates[index] = b;

			var D = YAHOO.util.Dom;

			if(b)

				D.removeClass(this._tabUIs[index],"disabled");

			else

				D.addClass(this._tabUIs[index],"disabled");

		}

	},

	getSelectedIndex:function(){

		return this._selectedIndex;

	},

	setSelectedIndex:function(index,silent){

		if(index == this._selectedIndex || !this._checkIndex(index))

			return;

		if(!this._tabStates[index])

			return;

		if(this._selectedIndex != -1)

			this.setUIActiveByIndex(this._selectedIndex,false);

		this.setUIActiveByIndex(index,true);

		this._elapsedIndex = this._selectedIndex;

		this._selectedIndex = index;

		if(!silent && typeof this.onTabChange == "function")

			this.onTabChange.call(this,this._elapsedIndex,this._selectedIndex);

	},

	setUIActiveByIndex:function(index,b){

		if(!this._checkIndex(index))

			return;

		var C = chromeplus.org.chromeplus.net.ClassAttributeList;

		if(b){

			(new C(this._tabUIs[index])).add(this._onStyle);

			if(!this._option.triggerOnly)

				this._tabContentUIs[index].style.display = "block";

		}else{

			(new C(this._tabUIs[index])).remove(this._onStyle);

			if(!this._option.triggerOnly)

				this._tabContentUIs[index].style.display = "none";

		}

	},

	getTabUIByIndex:function(index){

		return !this._checkIndex(index)? null:this._tabUIs[index];

	},

	getTabLabelByIndex:function(index){

		return !this._checkIndex(index)? null:(this._tabUIs[index].textContent?this._tabUIs[index].textContent:this._tabUIs[index].innerText);

	},

	getTabContentUIByIndex:function(index){

		return !this._checkIndex(index)? null:this._tabContentUIs[index];

	},

	getTabUIs:function(){

		return this._tabUIs;

	}

}



chromeplus.parcel("org.chromeplus.net").bundle(Cookie,"Cookie");

chromeplus.parcel("org.chromeplus.net").bundle(Toolkit,"Toolkit");

chromeplus.parcel("org.chromeplus.net").bundle(ClassAttributeList,"ClassAttributeList");

chromeplus.parcel("org.chromeplus.net").bundle(FeatureShowcase,"FeatureShowcase");

chromeplus.parcel("org.chromeplus.net").bundle(FlashShowcase,"FlashShowcase");

chromeplus.parcel("org.chromeplus.net").bundle(Timer,"Timer");

chromeplus.parcel("org.chromeplus.net").bundle(TabbedPane,"TabbedPane");

chromeplus.parcel("org.chromeplus.net").bundle(Collections,"Collections");

})();


