/*
	Base, version 1.0.2
	Copyright 2006, Dean Edwards
	License: http://creativecommons.org/licenses/LGPL/2.1/
*/
function Base(){if (arguments.length){if(this==window){Base.prototype.extend.call(arguments[0],arguments.callee.prototype);}else{this.extend(arguments[0]);}}};Base.version="1.0.2";Base.prototype={extend:function(s,v){var e=Base.prototype.extend;if(arguments.length==2){var a=this[s];if((a instanceof Function)&&(v instanceof Function)&&a.valueOf()!=v.valueOf()&&/\bbase\b/.test(v)){var m=v;v=function(){var p=this.base;this.base=a;var r=m.apply(this,arguments);this.base=p;return r};v.valueOf=function(){return m};v.toString=function(){return String(m)}}return this[s]=v}else if(s){var p={toSource:null};var x=["toString","valueOf"];if(Base._)x[2]="constructor";for(var i=0;(n=x[i]);i++){if(s[n]!=p[n]){e.call(this,n,s[n])}}for(var n in s){if(!p[n]){e.call(this,n,s[n])}}}return this},base:function(){}};Base.extend=function(i,s){var e=Base.prototype.extend;if(!i)i={};Base._=1;var p=new this;e.call(p,i);var constructor=p.constructor;p.constructor=this;delete Base._;var k=function(){if(!Base._)constructor.apply(this,arguments);this.constructor=k};k.prototype=p;k.extend=this.extend;k.implement=this.implement;k.toString=function(){return String(constructor)};e.call(k,s);var o=constructor?k:p;if(o.init instanceof Function)o.init();return o};Base.implement=function(_i){if (_i instanceof Function)_i=_i.prototype;this.prototype.extend(_i);};
/* end Base */
Base(Function);
Base(Array);

Function.prototype.bind = function() {//(c)[prototype]
	var __method = this, args = $A(arguments), obj = args.shift(); 
	return function() { return __method.apply(obj,args); };
};

/// Object
Object.extend = function (dest, src, bOverride) {
	if ( src ) {
		for (var prop in src) {
			if ( prop == "style" ) DOM.setStyle(dest,src[prop]);
			else if ( dest.tagName ) dest.setAttribute(prop,src[prop]);
			else if( dest[prop] && bOverride===false );
			else dest[prop] = src[prop];
		}	
	}
	return dest;
};


var Aris = Base.extend({
	
	_guid: 0,
	
	version: "1.0.0",
	
	constructor: null, // no more than one Aris
	
	guid: function () { 
		return (typeof arguments[0] == 'string' ? arguments[0] + ++this._guid : ++this._guid);
	},

	popWin: function (url, name, width, height) {
		var win, s;
		if (width || height) {
			var h = height || 570;
			var w = width || 770;
			var lp = (screen.width) ? (screen.width-w)/2 : 0;
			var tp = (screen.height) ? (screen.height-h)/2 : 0;
			s = 'height='+ h +',width='+ w +',top='+tp+',left='+lp+',scrollbars=yes,resizable,menubar=1';
		} else s = '';
		win = window.open(url,name||'_blank',s);
		if (win) win.focus();
		return win;
	}
	
});


var Iterate = Base.extend({
	//javascript 1.6 array functions forEach, every, some, filter
	forEach: function(fn,context) {
		for(var i=0; i< this.length; i++) {
			fn.call(context, this[i], i, this );
		}
	},

	filter: function(fn,context) {
		var rv = [];
		for (var i=0;i < this.length; i++) {
			if ( fn.call(context,this[i],i,this) )
				rv.push( el );
		}
		return rv;
	},

	every: function(fn,context) {
		var rv = true
		for (var i=0;i < this.length; i++) {
			rv = rv && !!fn.call(context,this[i],i,this);
			if(!rv) return false;
		}
		return true;
	},

	some: function(fn,context) {
		for (var i=0;i < this.length; i++) {
			if( rv = !!fn.call(context,this[i],i,this) )
				return true;
		}
		return false;
	},

	map: function(fn,context) {
		var rv = [];
		for (var i=0;i < this.length; i++) {
			rv.push( fn.call(context,this[i],i,this) );
		}
		return rv;
	},

	indexOf: function(obj) {
		for (var i=0;i < this.length; i++) {
			if (this[i]===obj) 
				return i;
		}
		return -1;
	}
});

Object.extend(Array.prototype, new Iterate,false);

var $A = Array.from = function(iterable) { //(c)[prototype]
	var n = [];
	if ( !iterable ) return n;
	for(var i=0;i<iterable.length;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; i < object.length; 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);
    }
};

//Aris.require(Array)

Function.prototype.bindListener =  function(obj,orig) {//(c)[prototype]
	var __method = this;
	return function(e) { return __method.call(obj,e||window.event,orig); };
};

var Event = Base.extend(null,{

	all: [],

	_isValidCollection: function(o) {
		return ( o && o.length && !o.tagName && !o.alert && o.length > 0 );
	},
	
	_getCacheIndex: function(el, eType, fn) {
		for (var i=0; i < this.all.length; 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 = new 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 = new Function;
		}
		return removeEvent;
	}(),
	
	add: function(el, eType, fn, scope) {
		if ( !el || !fn || !fn.call ) return false;
		
		if ( typeof el == "string" ) { 
			if ( pageLoaded ) { return this.add( document.getElementByID(el), eType, fn, scope ); }
			else {  return false; } //delay not supported
		}
		else if ( this._isValidCollection(el) ) {
			var ok = $A(el).map( function(eli) { return Event.add(eli,eType,fn,scope); });
			return ok.every(function(b){ return !!b; });
		}
		
		var wFn = (scope) ? fn.bindListener(scope,el) : fn.bindListener(el);
		
		var li = [el,eType,fn,wFn,scope];
		
		this.all.push(li)
		
		this._on(el,eType,wFn);
		
		return true;
		
	}, //end add
	
	init: function() {
		this.add(window,'unload',this.unLoad,this);
	},

	pageLoaded: false,
	
	preventDefault: function(ev) {
		if ( ev.preventDefault) { ev.preventDefault(); }
		else {ev.returnValue = false;}
	},
	
	remove: function(el,eType,fn,idx) {
		if (!fn || !fn.call) return false;

		if ( this._isValidCollection(el) ) {
			var ok = $A(el).map( function(eli) { this.remove(eli,eType,fn) } );
			return ok.every(function(b){ return !!b; });
		}

		var cacheItem = null;
		if (typeof idx == "undefined") idx = this._getCacheIndex(el, eType, fn);
		if (idx >= 0) cacheItem = this.all[idx];
		if (!el || !cacheItem) return false;
		
		this._rem(el, eType, cacheItem[3]);

		delete this.all[idx][3];
		delete this.all[idx][2];
		delete this.all[idx];
		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) {
		if (this.all) {
			this.all.forEach( function(l,idx) {
				if (l) this.remove(l[0],l[1],l[2],idx);
			},this);
		}
	}
	
		
});

var DOM = Base.extend(null, {

	addClass: function(o, c1) { if(!this.checkClass(o,c1)){o.className+=o.className?' '+c1:c1;} },

	checkClass: function(o, c1) { return new RegExp('\\b'+c1+'\\b').test(o.className) },

	getEl: function() {
	  var els = new Array();
	  for (var i=0,el; el=arguments[i]; i++) {
		if (typeof el == 'string')
		  el = document.getElementById(el);
		if (arguments.length == 1) 
		  return el;
		els.push(el);
	  }
	  return els;
	},
	
	getElementsByClass: function (searchClass,node,tag) {
		var cEls = new Array();
		if (!node) node = document;
		if (!tag) tag = '*';
		var els = node.getElementsByTagName(tag);
		if( !els.length && (tag == '*' && node.all) ) els = node.all;
		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(o, prop) {
		val = null;
		if(o.style[prop]) return o.style[prop];
		else if (o.currentStyle) return o.currentStyle[prop];
		else if (document.defaultView && document.defaultView.getComputedStyle) {
			var s = document.defaultView.getComputedStyle(o,null);
			return s.getPropertyValue(prop);
		}
		else
			return null;
	},
	
	removeClass: function(o, c1) { var rep=o.className.match(' '+c1)?' '+c1:c1; o.className=o.className.replace(rep,''); },
	
	setOpacity: function(o,val) {
		o.style.opacity = (val<1) ? val:.999;
		if(window.ActiveXObject) o.style.filter = "alpha(opacity:"+val*100+")";
		return o;
	},
	
	setStyle: function(el, style, val) {
		if (arguments.length ==3)
			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.checkClass(o,c1) ? o.className.replace(c2,c1) : o.className.replace(c1,c2); },
	
	getPos: function(tEl) {
		var el = $(tEl);
		var pos = { top: 0, left: 0 };
		do {
			pos.top += el.offsetTop;
			pos.left += el.offsetLeft;
		} while( el = el.offsetParent );
		return pos;
	},
	
	getDim: function(tEl) {
		var el = $(tEl);
		var $style = DOM.setStyle;
		if(el.origin) return el.origin;
		var dim = { width: 0, height: 0 };
		$style(el, {visibility:'hidden',display:'block'});
		dim.width = el.offsetWidth;
		dim.height = el.offsetHeight;
		$style(el, {width: dim.width+'px', height: dim.height+'px' });
		var w = el.offsetWidth;
		var h = el.offsetHeight;
		if ( w != dim.width || h != dim.height ){ 
			dim.width = dim.width - (w - dim.width);
			dim.height = dim.height - (h - dim.height);
		}		
		$style(el, {width:'', height:'', visibility:'', display:'' });
		el.origin = dim;
		return dim;
	},
	
	getLayout: function(el) { return Object.extend( this.getPos(el), this.getDim(el) ); }
	
});
var $ = DOM.getEl;

