function hw$(id) {return HW.ext(document.getElementById(id));}
function hw$$(c,o,t) {return HW.getElementsByClassName(c,o,t).each(HW.ext);}
function _hw$(c,s) {return HW.ext(HW.querySelector(c,s));}
function _hw$$(c,s) {return HW.querySelectorAll(c,s).each(HW.ext);}

var HW = {
	ext:function (o) {if(o) {return HW.extendObject(o,HW._proto);}return null;},
	isIE:false,
	isMacFF:false,
	dom:{ready:false,timer:null,loaded:false},
	toRun:[],

	log:function(a) {
		if(window.console&&console.log) {console.log.apply(console,arguments);}
		return a;
	},

	error:function(a) {
		if(window.console&&console.error) {console.error.apply(console,arguments);}
		else {alert(a);}
	},

	getElementsByClassName:function(cls,n,t) {
		var rtn = [];
		n=n===null?document:n;
		t=t===null?'*':t;
		var els = n.getElementsByTagName?n.getElementsByTagName(t):document.all;
		els = (!els||!els.length) && document.all?document.all:els;
		if(cls==null){return els;}
		for (var i=0,j=0; i<els.length;i++) {
			if(this.hasClass(els[i],cls)) {
				rtn[j++] = els[i];
			}
		}
		return rtn;
	},

	querySelectorAll:function(css,scope) {
		scope = scope || document;
		return HW.CssParser(css,scope);
	},

	querySelector:function(css,scope) {
		scope = scope || document;
			var o = HW.CssParser(css,scope);
			return o.length?o[0]:null;
	},

	createNode:function(t,p,c,opts) {
		var n = document.createElement(t);
		if(c) {n.innerHTML = c;}
		n = HW.extendObject(n,opts);
		HW.ext(n);
		return p.appendChild(n);
	},

	attachEvent:function(obj,evt,fnc,def) {
		if(def === false) {
			var _f = fnc;
			fnc = function(e){HW.preventDefault(e);_f(e);}
		}
		if(window.addEventListener) {obj.addEventListener(evt, fnc, false);}
		else if(window.attachEvent) {obj.attachEvent('on'+evt, fnc);}
		else if (obj.getElementById && evt=='load') {obj.onload = fnc;}
		return obj;
	},

	detachEvent:function(obj,evt,fnc,def) {
		if(def === false) {
			var _f = fnc;
			fnc = function(e){HW.preventDefault(e);_f(e);}
		}
		if(window.removeEventListener) {obj.removeEventListener(evt, fnc, false);}
		else if(window.detachEvent) {obj.detachEvent('on'+evt, fnc);}
		return obj;
	},

	preventDefault:function(e) {
		e=e||window.event;
		if(e.preventDefault) {e.preventDefault();}
		else {e.returnValue = false;}
	},

	cancelBubble:function(e) {
		e=e||window.event;
		if(e.stopPropogation) {e.stopPropogation();}
		else {e.cancelBubble = true;}
	},

	extendObject:function(d,s) {
		d=d||{};
		for (var p in s) {d[p] = s[p];}
		return d;
	},

	addClass:function(o,c) {
		if (!this.hasClass(o,c)){
			if (o.className == "") {o.className = c;}
			else {o.className += " " + c;}
		}
		return o;
	},

	hasClass:function(o,c) {
		var p = new RegExp("(^| )" + c + "( |$)");
		if (p.test(o.className)) {return true;}
		return false;
	},

	removeClass:function(o,c) {
		var p = new RegExp("(^| )" + c + "( |$)");
		o.className = o.className.replace(p, "$1");
		o.className = o.className.replace(/ hw$/, "");
		return o;
	},

	swapClass:function(o,c) {
		HW.hasClass(o,c)?HW.removeClass(o,c):HW.addClass(o,c);
		return o;
	},

	setFade:function(o,n) {
		var agt = navigator.userAgent.toLowerCase();
		if((agt.indexOf("msie") != -1) && (agt.indexOf("opera") == -1)) {
			if (n == 100) {o.style.filter = "";}
			else if (n < 0) {o.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity=0);";}
			else {o.style.filter = "progid:DXImageTransform.Microsoft.Alpha(opacity="+ Math.round(n) + ");";}
		}
		else {			
			o.style.MozOpacity = (Math.round(n) / 100);
			o.style.opacity = (Math.round(n) / 100);
		}
		o._alpha = n;
		return o;
	},

	setStyle:function(o,s) {
		if(o) {
			for(var i in s) {
				o.style[i] = s[i];
			}
		}
		return o;
	},

	empty:function(o) {
		while(o.firstChild) {
			o.removeChild(o.firstChild);
		}
		return o;
	},

	show:function(e,t,c,time) {
		time = time?time:this.transitionTime;
		
		if(!HW.Animate) {t = null;}
		if(e) {
			switch(t) {
				case 'slide':
					var h1 = e.offsetHeight;
					var h2 = this.getTotalSize(e);
					var s = {display:'block',height:h1+'px',overflow:'hidden'};
					HW.setStyle(e,s);
					var cb = function(){
						var s = {height:'',overflow:'',position:''};
						HW.setStyle(e,s);
						e.hidden = false;
						if(c){c();}
					};
					new HW.Animator(e,h1,h2,function(e,v){e.style.height=v+'px';},time,cb);
					break;
				default:
					e.style.display = '';
					e.hidden = false;
					if(c) {c();}
					break;
			}
		}
		return e;
	},

	hide:function(e,t,c,time) {
		time = time?time:this.transitionTime;
		
		if(!HW.Animate) {t = null;}
		
		if(e) {
			switch(t) {
				case 'slide':
					var h1 = e.offsetHeight;
					var h2 = 0;
					var s = {display:'block',height:h1+'px',overflow:'hidden'};
					HW.setStyle(e,s);
					var cb = function(){
						var s = {display:'none',height:'',overflow:'',position:''};
						HW.setStyle(e,s);
						e.hidden = true;
						if(c){c();}
					};
					new HW.Animator(e,h1,h2,function(e,v){e.style.height=v+'px';},time,cb);
					break;
				default:
					e.style.display = 'none';
					e.hidden = true;
					if(c) {c();}
					break;
			}
		}
		return e;
	},

	toggle:function(e,t,c,time) {
		if(e) {
			if(e.hidden) {
				return this.show(e,t,c,time);
			}
			else {
				return this.hide(e,t,c,time);
			}
		}
	},

	getTotalSize:function(e) {
		var newStyle = {height:'',visibility:'hidden',display:'',position:'absolute'};
		var tmp = {};
		for(s in newStyle) {
			tmp[s] = e.style[s];
			e.style[s] = newStyle[s];
		}
		var h = e.offsetHeight;
		HW.setStyle(e,tmp);
		return h;
	},

	fixIE6flicker:function() {
		var m = document.uniqueID && document.compatMode && !window.XMLHttpRequest && document.execCommand ; 
		try { 
			if(!!m) { 
				m("BackgroundImageCache", false, true);
			} 
		}
		catch(e) {};
	},

	checkLoaded:function() {
		if(HW.dom.ready){return true;}
		if(document && document.getElementsByTagName && document.getElementById && document.body) {
			clearInterval(HW.dom.timer);
			HW.dom.timer = null;
			HW.dom.ready = true;
			return true;
		}
		else {return false}
	},

	onload:function(f) {
		HW.toRun.push(f);
		if(HW.dom.loaded) {
			f();
		}
	},

	load:function() {
		if(HW.checkLoaded() && !HW.dom.loaded) {
			HW.dom.loaded = true;
			for(var i=0,j=HW.toRun.length;i<j;i++) {
				HW.toRun[i]();
			}
			if(HW.isIE) {HW.fixIE6flicker();}
		}
		else if(HW.dom.timer === null) {
			HW.dom.timer = setInterval(HW.load,10);
		}
	},

	_proto:{
		log:function() {
			return HW.log(this);
		},
		addClass:function(c) {
			return HW.addClass(this,c);
		},
		removeClass:function(c) {
			return HW.removeClass(this,c);
		},
		swapClass:function(c) {
			return HW.swapClass(this,c);
		},
		hasClass:function(c) {
			return HW.hasClass(this,c);
		},
		createNode:function(t,h,p) {
			return HW.createNode(t,this,h,p);
		},
		before:function(n) {
			return this.parentNode.insertBefore(this,n);
		},
		extendObject:function(o) {
			return HW.extendObject(this,o);
		},
		setStyle:function(s) {
			return HW.setStyle(this,s);
		},
		setFade:function(n) {
			return HW.setFade(this,n);
		},
		show:function(t,c,time) {
			return HW.show(this,t,c,time);
		},
		hide:function(t,c,time) {
			return HW.hide(this,t,c,time);
		},
		toggle:function(t,c,time) {
			return HW.toggle(this,t,c,time);
		},
		empty:function() {
			return HW.empty(this);
		},
		bind:function(e,f,c) {
			return HW.attachEvent(this,e,f,c);
		},
		unbind:function(e,f,c) {
			return HW.detachEvent(this,e,f,c);
		},
		fade:function(alpha,time,callback) {
			HW.Animate.fade(this,alpha,time,callback);
			return this;
		},
		move:function(to,time,callback) {
			HW.Animate.move(this,to,time,callback);
			return this;
		}
	}

};

(function(){
	var userAgent = navigator.userAgent.toLowerCase();
	HW.isIE  = (navigator.appVersion.indexOf("MSIE") != -1)?true:false;
	HW.isMacFF  = (userAgent.indexOf('mac') != -1 && userAgent.indexOf('firefox')!=-1)?true:false;
	
	if(HW.isIE) (function(){
		try {
			document.documentElement.doScroll("left");
		} catch(e) {
			setTimeout(arguments.callee,0);
			return;
		}
		HW.load();
	})();
	HW.attachEvent(document,'DOMContentLoaded',HW.load);
	HW.attachEvent(window,'load',HW.load);
})();


HW.CssParser = (function() {
	var B = /\s*,\s*/;
	var A = /\s*([\s>+~(),]|^|$)\s*/g;
	var L = /([\s>+~,]|[^(]\+|^)([#.:@])/g;
	var F = /(^|\))[^\s>+~]/g;
	var M = /(\)|^)/;
	var K = /[\s#.:>+~()@]|[^\s#.:>+~()@]+/g;
	
	function Parser(css, scope) {
		scope = scope || document.documentElement;
		var selectors = css.split(B);
		var a = [];
		for (var i = 0; i < selectors.length; i++) {
			var o = [scope];
			var sel = Parser.clean(selectors[i]);
			for (var j = 0; j < sel.length;) {
				var prefix = sel[j++];
				var fragment = sel[j++];
				var paren = "";
				if (sel[j] == "(") {
					while (sel[j++] != ")" && j < sel.length) {
						paren += sel[j];
					}
					paren = paren.slice(0, -1);
				}
				o = Parser.get(o, prefix, fragment, paren);
			}
			a = a.concat(o);
		}
		return Parser.util.unique(a);
	}
	Parser.clean = function(selector) {
		var o = selector.replace(A, "$1")
		o = o.replace(L, "$1*$2")
		o = o.replace(F, function(s){return s.replace(M, "$1 ")});
		return o.match(K) || []
	}
	Parser.get = function(scope, prefix, fragment, paren) {
		return (Parser.selectors[prefix]) ? Parser.selectors[prefix](scope, fragment, paren) : []
	}
	Parser.util = {
		toArray: function(o) {
			var a = [];
			for (var i = 0; i < o.length; i++) {
				a.push(o[i])
			}
			return a;
		},
		unique: function(o) {
			var a = [];
			for(var i=0;i<o.length;i++) {
				if(!this.inArray(o[i],a)) {a.push(o[i]);}
			}
			return a;
		},
		inArray:function(o,a) {
			for(var j=0;j<a.length;j++) {
				if(a[j] == o) {return true;}
			}
			return false;
		}
	};
	Parser.dom = {
		isTag: function(O, N) {
			return (N == "*") || (N.toLowerCase() == O.nodeName.toLowerCase())
		},
		previousSiblingElement: function(o) {
			while ( o && o.nodeType != 1 ) {
				o = o.previousSibling
			}
			return o;
		},
		nextSiblingElement: function(o) {
			while ( o && o.nodeType != 1 ) {
				o = o.nextSibling;
			}
			return o;
		},
		hasClass: function(cls, o) {
			return (o.className || "").match("(^|\\s)" + cls + "(\\s|$)");
		},
		getByTag: function(tag, o) {
			return o.getElementsByTagName(tag);
		}
	};
	Parser.selectors = {
		"#": function(scope, id) {
			for(var i=0;i<scope.length;i++) {
				if (scope[i].getAttribute("id") == id) {
					return [scope[i]];
				}
			}
			return [];
		},
		" ": function(scope, tag) {
			var a = [];
			for(var i=0;i<scope.length;i++) {
				a = a.concat(Parser.util.toArray(Parser.dom.getByTag(tag,scope[i])));
			}
			return a
		},
		">": function(scope,child) {
			var a = [];
			for (var i=0;i<scope.length;i++) {
				var parent = scope[i];
				for (var j=0;j<parent.childNodes.length;j++) {
					var node = parent.childNodes[j];
					if (node.nodeType == 1 && Parser.dom.isTag(node, child)) {
						a.push(node);
					}
				}
			}
			return a;
		},
		".": function(scope,cls) {
			var a = [];
			for (var i=0;i<scope.length;i++) {
				var node = scope[i];
				if (Parser.dom.hasClass([cls], node)) {
					a.push(node);
				}
			}
			return a;
		},
		":": function(scope,pseudo,paren) {
			return (Parser.pseudoClasses[pseudo]) ? Parser.pseudoClasses[psuedo](scope, paren) : []
		}
	};
	Parser.pseudoClasses = {};
	return Parser;
})();



HW.Ajax = function(url,callback,vars,opts) {
	var obj = this;
	opts = HW.extendObject(HW.extendObject({},HW.Ajax.Defaults),opts);
	vars = vars?vars:null;
	this.req = new HW.Ajax.Request(url,vars,opts);
	if(typeof(callback) == 'function') {this._passResponse = callback;}
	this.req._statechange(function(o) {obj._handle(o);});
	this.req._sendRequest();
};

HW.Ajax.prototype = {
	req:{},
	_handle:function(o) {
		if(this.req.xmlHttp.readyState == 4) {
			if(this.req.xmlHttp.status.toString().match(/(2|3)([0-9]{2})/)) {
				var r = new HW.Ajax.Response(this.req.xmlHttp);
				if(this.req.cache) {
					HW.Ajax.Cache.add(this.req,r);
				}
				
				this._passResponse(r);
				return;
			}
		}
		if(o && o.constructor == Object) {
			this._passResponse(o);
		}
	},
	_passResponse:function() {return;}
};

HW.Ajax.Request = function(href,vars,opts) {
	this.href = href;
	this.vars = vars;
	this.method = opts.method;
	this.cache = opts.cache;
	this.createXmlHttpRequestObject();
};

HW.Ajax.Request.prototype = {
	xmlHttp:null,
	createXmlHttpRequestObject:function() {
		try {
			this.xmlHttp = new XMLHttpRequest();
		} catch(e) {
			var XmlHttpVersions = new Array("MSXML2.XMLHTTP.6.0",
										"MSXML2.XMLHTTP.5.0",
										"MSXML2.XMLHTTP.4.0",
										"MSXML2.XMLHTTP.3.0",
										"MSXML2.XMLHTTP",
										"Microsoft.XMLHTTP");
			for (var i=0; i<XmlHttpVersions.length && !this.xmlHttp; i++) {
				try { 
					this.xmlHttp = new ActiveXObject(XmlHttpVersions[i]);
				}  catch(e){}
			}
		}
	},
	_sendRequest:function(method,vars) {
		if(this.cache) {
			var c = HW.Ajax.Cache.get(this);
			if(c != null) {
				this._onreadystatechange(c);
				return;
			}
		}
		if(this.xmlHttp) {
			try {
				if (this.xmlHttp.readyState == 4 || this.xmlHttp.readyState == 0) {
					this.xmlHttp.open(this.method, this.href+(this.method=='GET'&&this.vars?'?'+this.vars:''), true);
					if(this.method == 'POST') {
						this.xmlHttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
						this.xmlHttp.setRequestHeader("Content-length", this.vars.length);
						this.xmlHttp.setRequestHeader("Connection", "close");
					}
					this.xmlHttp.send(this.vars);
				}
				else {
					if(timeoutId != -1) clearTimeout(timeoutId);  
					var obj = this;
					timeoutId = setTimeout(function(){obj.sendRequest();}, 500);
				}
			} catch(e){}
		}
	},
	_statechange:function(f) {
		this.xmlHttp.onreadystatechange = f;
		this._onreadystatechange = f;
	}
};

HW.Ajax.Response = function(xml) {
	this.contentType = xml.getResponseHeader('Content-Type')?xml.getResponseHeader('Content-Type'):'text/html';
	if(this.contentType.substr(0,4) == 'text') {
		this.xml = xml.responseXML?xml.responseXML:null;
		this.text = xml.responseText?xml.responseText:'';
	}
};
HW.Ajax.Response.prototype = {xml:null,text:null,contentType:null};

HW.Ajax.Defaults = {
	cache:false,
	method:'GET'
}

HW.Ajax.Cache = {
	_store:{},
	add:function(request,response) {
		if(!this._store[request.href]) {
			this._store[request.href] = {}
		}
		this._store[request.href][request.vars?request.vars:'__novars__'] = response;
	},
	get:function(request) {
		try{
			var response = this._store[request.href][request.vars?request.vars:'__novars__'];
		}catch(e){var response=null;}
		return response?response:null;
	}
}

HW.Animate = {
	fade:function(elm,to,time,c) {
		if(!elm._alpha && elm._alpha !== 0) {elm._alpha = 100;}
		new HW.Animator(elm,elm._alpha,to,HW.setFade,time,c);
	},
	move:function(elm,to,time,c) {
		var p = {x:elm.offsetLeft,y:elm.offsetTop}
		var f = function(o,v) {
			var dx = p.x + (to.x - p.x)*v;
			var dy = p.y + (to.y - p.y)*v;
			HW.setStyle(o,{left:dx+'px',top:dy+'px'});
		}
		var a = new HW.Animator(elm,0,1,f,time,c);
	}
};

HW.Animator = function(o,v0,v1,s,t,c) {
	if(o) {this.target = o;}
	this.setFunc = s;
	this.startValue = v0;
	this.endValue = v1;
	if(t) {this.time = t;}
	if(typeof(c) == 'function') {this.callback = c;}
	this.steps = Math.ceil(this.time/this.stepLength);
	this.stepLength = this.time/this.steps;
	this.animate();
};

HW.Animator.prototype = {
	stepLength:30,
	time:500,
	steps:20,
	setFunc:function(){},
	callback:function(){},
	set:function(v) {
		this.setFunc(this.target,v);
	},
	animate:function() {
		this.timers = [];
		var obj = this;
		var df = (this.endValue - this.startValue)/this.steps;
		if(df != 0) {
			for(var i=1,j=this.steps;i<=j;i++) {
				(function(){
					var j=i;
					obj.timers.push(setTimeout(function(){
						obj.set(obj.startValue + j*df);
					},j*obj.stepLength));
				})();
			}
			this.timers.push(setTimeout(function(){obj.callback();},this.stepLength*this.steps));
		}
		else {
			this.callback();
		}
	},
	stop:function() {
		this.timers.each(function(o){clearTimeout(o);});
	}
};

Array.prototype.each = function(f) {
	if(typeof(f) == 'function') {
		for(var i=0,j=this.length;i<j;i++) {
			f(this[i]);
		}
	}
	return this;
}

