/*
	Base, version 1.1
	Copyright 2006, Dean Edwards
	License: http://creativecommons.org/licenses/LGPL/2.1/
*/

/* end Base */
var Base=function(){};Base.prototype={extend:function(c){if(arguments.length>1){var d=this[c];var e=arguments[1];if(typeof e=="function"&&d&&/\bbase\b/.test(e)){var f=e;e=function(){var a=this.base;this.base=d;var b=f.apply(this,arguments);this.base=a;return b};e.method=f;e.ancestor=d}this[c]=e}else if(c){var g=Base.prototype.extend;if(Base._prototyping){var h,i=0,members=["constructor","toString","valueOf"];while(h=members[i++])if(c[h]!=Object.prototype[h]){g.call(this,h,c[h])}}else if(typeof this!="function"){g=this.extend||g}for(h in c)if(!Object.prototype[h]){g.call(this,h,c[h])}}return this},base:Base};Base.extend=function(b,c){var d=Base.prototype.extend;Base._prototyping=true;var e=new this;d.call(e,b);delete Base._prototyping;var constructor=e.constructor;var f=e.constructor=function(){if(!Base._prototyping){if(this._constructing||this.constructor==f){this._constructing=true;constructor.apply(this,arguments);delete this._constructing}else{var a=arguments[0];if(a!=null){(a.extend||d).call(a,e)}return a}}};for(var i in Base)f[i]=this[i];f.ancestor=this;f.base=Base.base;f.prototype=e;f.toString=this.toString;d.call(f,c);if(typeof f.init=="function")f.init();if(typeof f.pageReady=="function"&&Event)Event.pageReady?f.pageReady():Event.onDOMReady.add(f.pageReady,f);return f};Base=Base.extend({constructor:function(){this.extend(arguments[0])}},{ancestor:Object,base:Base,implement:function(a){if(typeof a=="function"){a(this.prototype)}else{this.prototype.extend(a)}return this}});
// Object
Object.extend = function (dest, src, bOverride) {
	if ( src ) {
		for (var prop in src) {
			if( dest[prop] && bOverride===false );
			else dest[prop] = src[prop];
		}	
	}
	return dest;
};
var Fp = Function.prototype;
Fp.bind = function(thisObj) {
	var __method = this, args = $A(arguments), obj = args.shift();
	return function() { return __method.apply(obj, args); };
};
Fp.delay = function(ms, thisObj) {
	var args = $A(arguments), ms = args.shift();
	return setTimeout(this.bind.apply(this, args),ms);
};

var Aris = Base.extend(null,{
	
	extend: function (obj) {
		return this.base(null,obj);
	},
	_guid: 0,
	
	version: "1.0.0",
	
	guid: function () { 
		return (typeof arguments[0] == 'string' ? arguments[0] + ++this._guid : ++this._guid);
	},
	
	popWin: function (url, name, width, height, center) {
		var win, opt = [];
		if (width || height) {
			height = height || 570;
			width = width || 770;
			opt.push('height='+ height,'width='+ width);
			if (center===false) { 
				opt.push('top=' + ( (screen.width) ? (screen.width-width)/2 : 0 )); 
				opt.push('left=' + ( (screen.height) ? (screen.height-height)/2 : 0 ));
			}
			opt.push('scrollbars=yes','resizable','menubar=1');
		}
		win = window.open(url,name,opt.join(',') );
		if (win) win.focus();
		return win;
	}
});

var Observer = function(name) {
	this.name = name;
	this.fns = [];
	this.locked = false;
};
Observer.prototype = {
	add: function(f,thisObj) {
		if (!f) return;
		if ( !this.fns.some( function (obj) { return obj.fn === f; }) )
			this.fns.push({fn:f, context:thisObj});
	},
	remove: function(fn) {
		this.fns = this.fns.filter( function(el) {
			if ( typeof fn == 'undefinded' || (el.fn && el.fn !== fn) ) {
				delete el;
				return false;
			}
			return true;
		});
	},
	fire: function(sender, args) {
		if ( this.locked ) this.fire.delay(this, 10);
		var i = this.fns.length, el;
		if ( i == 0 ) return;
		this.locked = true;
		while(el = this.fns[--i]) {
			if ( el.fn.call(el.context, sender, args) === false ) break;
		}
		this.locked = false;
	}
};

var Event = Base.extend(null,{

	all: [],
	onDOMReady: new Observer('DOMReady'),
	onPageUnloading: new Observer('PageUnloading'),
	onPageLoad: new Observer('PageLoad'),
	pageReady: false,
	_timer: null,

	_getCacheIndex: function(el, eType, fn) {
		for (var i=0,len=this.all.length; i<len; i++) {
			var li = this.all[i];
			if ( li && li[2] == fn && li[0] == el && li[1] == eType ) return i;
		}
		return -1;
	},
	
	_on: function() {
		var addEvent;
		if (document.addEventListener) {
			addEvent = function(element, type, handler) {
				element.addEventListener(type, handler, false);
			};
		} else if (document.attachEvent) {
			addEvent = function(element, type, handler) {
				element.attachEvent("on" + type, handler);
			};
		} else {
			addEvent = function(){}; // not supported
		}
		return addEvent;
	}(),
	
	_rem: function () {
		var removeEvent;
		if (document.removeEventListener) {
			removeEvent = function(element, type, handler) {
				element.removeEventListener(type, handler, false);
			};
		} else if (document.detachEvent) {
			removeEvent = function(element, type, handler) {
				element.detachEvent("on"+type, handler);
			};
		} else {
			removeEvent = function(){};
		}
		return removeEvent;
	}(),

	_ready: function() {
		if (!this.pageReady) {
			this.pageReady = true;
			this.onDOMReady.fire(this);
			this.onDOMReady.remove();
		}
	},

	
	add: function(el, eType, fn, scope) {
		if ( !el || !fn || !fn.call ) return false;
		
		if ( typeof el == "string" ) { 
			if ( this.pageReady ) { return this.add( document.getElementById(el), eType, fn, scope ); }
			else { this.onDOMReady.add( function() { Event.add(el, eType, fn, scope); } ); } 
		}

		var wFn = (scope) ? this.bind(fn, scope, el) : this.bind(fn,el);
		
		var li = [el,eType,fn,wFn,scope];
		
		this.all.push(li);
		
		this._on(el,eType,wFn);
		
		return true;
		
	}, //end add
	
	bind: function(fn, obj, orig) {
		var __method = fn;
		return function(e) {
			return __method.call(obj,e||window.event,orig);
		};
	},
	
	init: function() {
		// for Mozilla/Opera 9
		if (document.addEventListener) {
		    document.addEventListener("DOMContentLoaded", this.bind(this._ready,this), false);
		}

		// for Internet Explorer (using conditional comments)
		/*@cc_on @*/
		/*@if (@_jscript_version >= 5)
		document.write("<script id=__ie_onload defer src=//0><\/script>");
		var script = document.getElementById("__ie_onload");
		var _this = this;
		script.onreadystatechange = function() {
		    if (this.readyState == "complete") {
		    	_this._ready(); // call the onload handler
		    }
		};
		/*@end @*/

		//for Safari/KTHML based browsers
		if (/KHTML/i.test(navigator.userAgent)) { // sniff
		    this._timer = setInterval(function() {
		        if (/loaded|complete/.test(document.readyState)) {
		           this._ready(); // call the onload handler
	        	}
		    }, 10);
		}		
		
		this.add(window, 'unload', this.unLoad, this);
		this.add(window, 'load', this.load, this);
	},

	load: function() {
		if ( !this.pageReady ) {
			this._ready();
		}	
		this.onPageLoad.fire(this);
	},
	
	preventDefault: function(ev) {
		if ( ev.preventDefault) { ev.preventDefault(); }
		else {ev.returnValue = false;}
	},
	
	remove: function(el,eType,fn,idx) {
		if (!el || !fn || !fn.call) return false;

		var cacheItem = null;
		if (typeof idx == "undefined") idx = this._getCacheIndex(el, eType, fn);
		if (idx >= 0) cacheItem = this.all[idx];
		if (!cacheItem) return false;
		
		this._rem(el, eType, cacheItem[3]);

		delete cacheItem[3];
		delete cacheItem[2];
		delete cacheItem;
		return true;
	},

	stopEvent: function(ev) {
		this.stopPropagation(ev);
		this.preventDefault(ev);
	},
	
	stopPropagation: function(ev) {
		if (ev.stopPropagation)
			ev.stopPropagation();
		else
			ev.cancelBubble = true;
	},
	
	unLoad: function(e) {
		this.onPageUnloading.fire(Event);
		this.all.forEach( function(l,idx) {
			this.remove(l[0],l[1],l[2],idx);
		},this);
	}
});

var DOM = {

	addClass: function(o, c1) { if(!this.hasClass(o,c1)){o.className+=o.className?' '+c1:c1;} },

	hasClass: function(o, c1) { return new RegExp('\\b'+c1+'\\b').test(o.className) },
	
	adopt: function(o, a) {
		o.appendChild( a.parentNode.removeChild(a) );
	},

	get: function(el) {
		if (typeof el == 'string')
			el = document.getElementById(el);
		return el;
	},
	
	getElementsByTagName: function(root, tag) {
		var node = root||document;
		tag = tag || '*';
		var els = node.getElementsByTagName(tag);
		if( !els.length && (tag == '*' && node.all) ) els = node.all;
		return els;
	},
	
	getElementsByClass: function (searchClass,node,tag) {
		var cEls = [];
		var els = this.getElementsByTagName(node, tag);
		var elsLen = els.length;
		var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
		for (var i=0,j=0; i < elsLen; i++) {
			if ( pattern.test(els[i].className) ) { cEls[j++] = els[i]; }
		}
		return cEls;
	},
	
	getStyle: function() {
		if (document.defaultView && document.defaultView.getComputedStyle) {
			return function(o,prop) {
				if (!o) return;
				prop = prop == 'float' ? 'cssFloat' : prop;
				var s = document.defaultView.getComputedStyle(o,'');
				return o.style[prop] || s ? s[prop] : null;
			};
		}
		else if (document.all) {
			return  function(o, prop) {
				if (!o) return;
				prop = prop == 'float' ? 'styleFloat' : prop;
				
				if ( prop == 'opacity' && window.ActiveXObject) {
					var val = 100;
                    try { // will error if no DXImageTransform
                        val = o.filters['DXImageTransform.Microsoft.Alpha'].opacity;
                    } catch(e) {
                        try { // make sure its in the document
                            val = o.filters('alpha').opacity;
                        } catch(e) { }
                    }
                    return val / 100;
				}
				else {
					return o.style[prop] || o.currentStyle[prop];
				}
			};
		}
		else {
			return function(o, prop) { if(!o) return; return o.style[prop] };
		}
	}(),
	
	removeClass: function(o, c1) { var rep=o.className.match(' '+c1)?' '+c1:c1; o.className=o.className.replace(rep,''); },
	
	setOpacity: function() {
		if (document.all) {
			return function(o, val) {
				o.style.filter = "alpha(opacity:"+val*100+")";
				if (!o.hasLayout) o.style.zoom = 1; 
			}
		}
		else {
			return function(o,val) {
				o.style.opacity = val<1 ? val : .999;
			};
		}
	}(),
	
	setStyle: function(el, style, val) {
		if ( !el ) return;
		if (arguments.length ==3)
			style == "opacity" ?  DOM.setOpacity(el, val) :  el.style[style] = val;
		else {
			for( var s in style) {
				s == "opacity" ? DOM.setOpacity(el, style[s]) :  el.style[s] = style[s];
			}
		}
	},

	swapClass: function(o,c1,c2) { o.className=!this.hasClass(o,c1) ? o.className.replace(c2,c1) : o.className.replace(c1,c2); },
	
	getPos: function(tEl, asArray) {
		var el = DOM.get(tEl);
		var pos = { top: 0, left: 0 };
		do {
			pos.top += el.offsetTop;
			pos.left += el.offsetLeft;
		} while( el = el.offsetParent );
		return asArray? [pos.top, pos.left] : pos;
	},
	
	getDim: function(tEl,asArray) {
		tEl = DOM.get(tEl);
		var dim = {};
		if(tEl) {
			dim.width = tEl.offsetWidth;
			dim.height = tEl.offsetHeight;
		}
		return asArray ? [dim.width,dim.height] : dim;
	},
	
	getLayout: function(el) { return Object.extend( this.getPos(el), this.getDim(el) ); }
	
};
var $ = DOM.get;

var IConfigurable = Base.extend({
	config: null,
	setConfig: function(config) {
		if (!this.config ) this.config = {};
		forEach(config,function(opt,name) {
			this.config[name] = opt;
		},this);
		return this.config;
	}
});


Object.extend(Array.prototype,{
	//javascript 1.6 array functions forEach, every, some, filter
	forEach: function(fn,context) {
		for(var i=0,len=this.length;i < len; i++) {
			fn.call(context, this[i], i, this );
		}
	},

	filter: function(fn,context) {
		var rv = [];
		for (var i=0,len=this.length;i < len; i++) {
			if ( fn.call(context,this[i],i,this) )
				rv.push( this[i] );
		}
		return rv;
	},

	every: function(fn,context) {
		var rv = true;
		for (var i=0,len=this.length;i < len; i++) {
			if (!fn.call(context,this[i],i,this) )
				return false;
		}
		return true;
	},

	some: function(fn,context) {
		for (var i=0,len=this.length;i < len; i++) {
			if( !!fn.call(context,this[i],i,this) )
				return true;
		}
		return false;
	},

	map: function(fn,context) {
		var rv = [];
		for (var i=0,len=this.length;i < len; i++) {
			rv.push( fn.call(context,this[i],i,this) );
		}
		return rv;
	},

	indexOf: function(obj,start) {
		var start = start || 0;
		for (var i=start,len=this.length;i < len; i++) {
			if (this[i]===obj) 
				return i;
		}
		return -1;
	}
},false);

var $A = Array.from = function(iterable) {
	var n = [];
	if ( !iterable ) return n;
	for(var i=0,len=iterable.length;i<len;i++) n.push(iterable[i]);
	return n;
};

// array-like enumeration
if (!Array.forEach) { // mozilla already supports this
    Array.forEach = function(object, fn, context) {
        for (var i=0,len=object.length; i < len; i++) {
            fn.call(context, object[i], i, object);
        }
    };
}

// generic enumeration
Function.prototype.forEach = function(object, fn, context) {
    for (var key in object) {
        if (typeof this.prototype[key] == "undefined") {
            fn.call(context, object[key], key, object);
        }
    }
};

// globally resolve forEach enumeration
var forEach = function(object, fn, context) {
    if (object) {
        var resolve = Object; // default
        if (object instanceof Function) {
            // functions have a "length" property
            resolve = Function;
        } else if (object.forEach instanceof Function) {
            // the object implements a custom forEach method so use that
            object.forEach(fn, context);
            return;
        } else if (typeof object.length == "number") {
            // the object is array-like
            resolve = Array;
        }
        resolve.forEach(object, fn, context);
    }
};

// If IE is used, create a wrapper for the XMLHttpRequest object
if ( !window.XMLHttpRequest )
	XMLHttpRequest = function(){
		return new ActiveXObject("Microsoft.XMLHTTP");
	};
var HttpClient = IConfigurable.extend({
	constructor: function(url, config){
		this.url = url;
		this.xhr = null;
		this.onComplete = new Observer;
		this.onError = new Observer;
		this.config = {
			method: 'POST',
			data: '',
			async: true,
			update: null,
			contentType: "application/x-www-form-urlencoded"
		};
		var c = this.setConfig(config);
		c.data = this.serialize(c.data);
		var oc = c.onComplete;
		this.onComplete.add(oc);
		delete c.onComplete;
		if (c.id) HttpClient.register(c.id, this);
	},
	request: function(data) {
		this.xhr = new XMLHttpRequest();
		var c = this.config;
		var xhr = this.xhr;
		if (data) c.data = this.serialize(data);
		
		if (c.method == 'GET') {
			this.url += ((this.url.indexOf("?") > -1) ? "&" : "?") + c.data;
			// IE likes to send both get and post data, prevent this
			c.data = null;
		}
		xhr.open(c.method, this.url, c.async);
		xhr.onreadystatechange = this._onStateChange.bind(this);
		
		xhr.setRequestHeader('Content-type', c.contentType);

		// Not necessary, but good to have
		xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
		xhr.setRequestHeader('Referer', location);
		
		// Make sure the browser sends the right content length
		if ( xhr.overrideMimeType )
			xhr.setRequestHeader("Connection", "close");
		xhr.send(c.data);
	},
	_onStateChange: function(){
		var xhr = this.xhr;
		if ( !xhr ) return;
		
		if (xhr.readyState == 4) {
			if (xhr.status == 200 || xhr.status == 0 || xhr.status == 304){
				xhr.onreadystatechange = function(){};;
				this.onComplete.fire(this, {xhr: xhr, xml: xhr.responseXML, text: xhr.responseText} );
				this.xhr = null;
			}
			else {
				this.onError.fire(this, {xhr: xhr});
			}
		}
	},
	serialize: function(obj) {
		if ( typeof obj == 'string' ) return obj;
		if ( typeof obj == 'undefined') return '';
		var data = [];
		if ( obj.getElementsByTagName ) {
		forEach(['input','textarea','select'], function(tag) {
			forEach(DOM.getElementsByTagName(obj,tag), function(o) {
				var n, v;
				if (/select/i.test(o.tagName) ) { n = o.name; v = o.options[o.selectedIndex].value; }
				else if ((o.name && o.value  && (/text|hidden|password/.test(o.type)|| typeof o.type=='undefined')) || ( /radio|checkbox/.test(o.type) && o.checked) ){ n = o.name; v = o.value; }
				if (n) data.push(encodeURIComponent(n)+'='+encodeURIComponent(v));
			});
		});
		}
		else
			forEach(obj, function(o,name) {
				if ( o ) {
					var val = o;
					if (o.constructor == Array) val = o.join(',');
					data.push(encodeURIComponent(name)+'='+encodeURIComponent(o));
				}
			});
		return data.join('&')
	}
}, {
	getText: function (node) {
		if (node.textContent ) return node.textContent;
		var s = [], rv = [];
		var i = 0;
		var n;
		while(node && (n = node.childNodes[i++]) ) {
			if ( n.nodeType == 3 || n.nodeType == 4 ) {
				rv.push(n.nodeValue);
				if (i == node.childNodes.length && s.length > 0 ) {
					node = node.parentNode;
					i = s[s.length - 1];
					s.length--;
				}	
			} else if (n.nodeType == 1) {
				s.push(i);
				i = 0;
				node = n;
			}
		}
		return rv.join('');
	},
	
	register: function(name, obj) {
		this[name] = function() { obj.request.apply(obj, arguments); };
		this[name].obj = obj;
	}
});
