﻿(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-]+)*)((?:&[^#]+)*)((?:#.+)*)$/gi;
		if(pattern.test(window.location.href)){
			window.location.assign(RegExp.$1+"?hl="+hl+RegExp.$3+RegExp.$4);
			Cookie.setCookie("_hl",hl,new Date(new Date().getTime() + 2*31*24*60*60*1000));
		}
	}
}

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");
})();
