/*
*  AWUtilities
*  Dan Lynn et al.
*  September 2006 -- 
*  
*  Provides a set of functions to assist in ajax web development.  Requires
*  the Prototype library version 1.4+
*/

// check for prototype  (thanks script.aculo.us)
if((typeof Prototype=='undefined') ||
  parseFloat(Prototype.Version.split(".")[0] + "." +
			 Prototype.Version.split(".")[1]) < 1.4)
  throw("AWUtilities requires the Prototype JavaScript framework >= 1.4.0");

var AWUtilities = {
	version: 0.3,
	
	Graphics: {},
	DOM: {},
	URL: {},
	Test: {}
};


// various tests
AWUtilities.Test = {

	isAlien: function(a) {
	   return this.isObject(a) && typeof a.constructor != 'function';
	},
	
	isArray: function(a) {
		return this.isObject(a) && a.constructor == Array;
	},
	
	isBoolean: function(a) {
		return typeof a == 'boolean';
	},
	
	isEmpty: function(o) {
		var i, v;
		if (this.isObject(o)) {
			for (i in o) {
				v = o[i];
				if (this.isUndefined(v) && this.isFunction(v)) {
					return false;
				}
			}
		}
		return true;
	},
	
	isFunction: function(a) {
		return typeof a == 'function';
	},
	
	isNull: function(a) {
		return a === null;
	},
	
	isNumber: function(a) {
		return typeof a == 'number' && this.isFinite(a);
	},
	
	isObject: function(a) {
		return (a && typeof a == 'object') || this.isFunction(a);
	},
	
	isString: function(a) {
		return typeof a == 'string';
	},
	
	isUndefined: function(a) {
		return typeof a == 'undefined';
	},
	
	isEmail: function(a) {
		var tester = new RegExp("^[\\w-_\.]*[\\w-_\.]\@[\\w]\.+[\\w]+[\\w]$");
		return tester.test(a);
	}
};

// DOM utilities
AWUtilities.DOM = {
	getElementsByAttribute: function(attribute, attributeValue) {
		var elementArray = new Array();
		var matchedArray = new Array();
		
		if (document.all) {
			elementArray = document.all;
		} else {
			elementArray = document.getElementsByTagName("*");
		}
		
		for (var i = 0; i < elementArray.length; i++) {
			if (attribute == "class") {
				//var pattern = new RegExp("(^| )" + attributeValue + "( |$)");
		
				//if (pattern.test(elementArray[i].className)) {
				if (elementArray[i].className.indexOf(attributeValue) > -1) {
					matchedArray.push(elementArray[i]);
				}
			} else if (attribute == "for") {
				if (elementArray[i].getAttribute("htmlFor") || elementArray[i].getAttribute("for")) {
					if (elementArray[i].htmlFor == attributeValue) {
						matchedArray.push(elementArray[i]);
					}
				}
			} else if (elementArray[i].getAttribute(attribute) == attributeValue) {
				matchedArray.push(elementArray[i]);
			}
		}
		
		return matchedArray;
	}
};

// graphics and positioning functions
AWUtilities.Graphics = {
	// retunrs available screen size
	getAvailableSize: function() {
		var myWidth = 0, myHeight = 0;
		if( typeof( window.innerWidth ) == 'number' ) {
			//Non-IE
			myWidth = window.innerWidth;
			myHeight = window.innerHeight;
		} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
			//IE 6+ in 'standards compliant mode'
			myWidth = document.documentElement.clientWidth;
			myHeight = document.documentElement.clientHeight;
		} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
			//IE 4 compatible
			myWidth = document.body.clientWidth;
			myHeight = document.body.clientHeight;
		}
		return {
			x: myWidth,
			y: myHeight
		};
	},
	
	// finds the position of el
	getAbsolutePosition: function(el) {
		var SL = 0, ST = 0;
		var is_div = /^div$/i.test(el.tagName);
		if (is_div && el.scrollLeft)
			SL = el.scrollLeft;
			
		if (is_div && el.scrollTop)
			ST = el.scrollTop;
			
		var r = { x: el.offsetLeft - SL, y: el.offsetTop - ST };
		if (el.offsetParent) {
			var tmp = AWUtilities.Graphics.getAbsolutePosition(el.offsetParent);
			r.x += tmp.x;
			r.y += tmp.y;
		}
		return r;
	},
	
	//finds the amount scrolled
	getScrollSize: function() {
		var scrOfX = 0, scrOfY = 0;
		if( typeof( window.pageYOffset ) == 'number' ) {
			//Netscape compliant
			scrOfY = window.pageYOffset;
			scrOfX = window.pageXOffset;
		} else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
			//DOM compliant
			scrOfY = document.body.scrollTop;
			scrOfX = document.body.scrollLeft;
		} else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
			//IE6 standards compliant mode
			scrOfY = document.documentElement.scrollTop;
			scrOfX = document.documentElement.scrollLeft;
		}
		
		return [ scrOfX, scrOfY ];
	}
};


// url parsing and formatting functions
AWUtilities.URL = {
	buildQueryString: function(paramsObject){
		var query = "";
		for(par in paramsObject){
			if(paramsObject[par] || paramsObject[par] == 0){
				query += (query.length > 0 ? "&" : "") + escape(par) + "=" + escape(paramsObject[par]);
			}		
		}
		return query;
	},
	ParameterCollection: {}
};

// Provides a wrapper class for building and parsing querystrings
// accepts data like this: { parameter: value, parameter2: "value2", ..... }
// or like this:  "parameter=value&parameter2=value2......"
AWUtilities.URL.ParameterCollection = Class.create();
AWUtilities.URL.ParameterCollection.prototype =  {
	initialize: function(params) {
		this.params = {};
		if (params) {
			
			// accept a parameter object
			if (typeof(params) == "object") {
				this.params = params;
			}
			
			// accept a querystring
			else if (typeof(params) == "string") {
				var vars = params.split("&");
				for (var i=0;i<vars.length;i++) {
					 var pair = vars[i].split("=");
					 this.params[pair[0]] = pair[1] ? pair[1] : null;
				}				
			}
		}
	},
	add: function(name, value) {
		this.params[name] = value;
		return this.params;
	},
	remove: function(name) {
		this.params[name] = null;
		delete this.params[name];
		return this.params;
	},
	toString: function() {
		return AWUtilities.URL.buildQueryString(this.params);
	}
};