
/*
	Object extentions that make my life easier
*/

window.definitions = [];
window.False = function () { return false }
window.True = function () { return true }
window.Void = function () { }

Element.addMethods({
	
	registerDefinition : function ( element, obj ) {
		if ( typeof(element.definitions) != 'object' ) {
			element.definitions = [];	
		}
		element.definitions.push(obj);
	},
	
	findDefinition : function ( element, defname ) {
		found = null;
		if ( typeof(element.definitions) == 'object' && element.definitions.length ) {
			element.definitions.each ( function (d) {
				if ( d.name == defname ) {
					found = d;
					$break;
				}	
			});
		}
		return found;
	},
	
	setErrorState : function ( element ) {
		if ( element.label != null ) { 
			element.label.addClassName('error');
			element.addClassName('error'); 
		} else { 
			element.addClassName('error') 
		} 
	},
	
	unsetErrorState : function ( element ) {
		if ( element.label != null ) { 
			element.label.removeClassName('error') ;
			element.removeClassName('error'); 
		} else { 
			element.removeClassName('error') 
		} 
	},
	center: function( element , options) {
		var options = Object.extend({
			zIndex: 999,
			update: false
		}, options || {});

		element = $(element);
		if(!element._centered){
			Element.setStyle(element, {position: 'absolute', zIndex: options.zIndex });
			element._centered = true;
		}
		var dims = Element.getDimensions(element);
		Position.prepare();
		var winWidth  = options['winWidth'] || self.innerWidth ||
						document.documentElement.clientWidth || document.body.clientWidth || 0;
		var winHeight = options['winHeight'] || self.innerHeight ||
						document.documentElement.clientHeight || document.body.clientHeight || 0;
		
		var offLeft = ( winWidth  > dims.width  ? (Position.deltaX + Math.floor((winWidth-dims.width)/2)) : Position.deltaX );
		var offTop  = ( winHeight > dims.height ? (Position.deltaY + Math.floor((winHeight-dims.height)/2)) : Position.deltaY );
		
		element.style.top = ((offTop != null && offTop > 0) ? offTop : '0') + 'px';
		element.style.left = ((offLeft != null && offLeft > 0) ? offLeft : '0') + 'px';
		if(options.update){
			Event.observe(window, 'resize', function(evt){
				element.center(this.options);
			}, false);
			/* WDR: shut off recentering for scrolling cuz it's a bit annoying 
			 * when you're _trying_ to get to the bottom of a form!
			Event.observe(window, 'scroll', function(evt){
				element.center(this.options);
			}, false);
			*/
		}
	}
	
	
});

Object.extend( Number.prototype, {

	toCurrency: function(symb, after) {
		num = this.toFixed(2);
		if (after) {
			return num+symb;
		} else {
			return symb+num;
		}

	}

});

Object.extend( String.prototype, {

	toInt: function() {
	/* elm.getStyle('height').toInt(); returns 25 instead of 25px */
		return parseInt(this);
	},
	parseUri: function () { 
		/*
			parseUri 1.2.1
			(c) 2007 Steven Levithan <stevenlevithan.com>
			MIT License
		*/ 
		var	o   = {
				strictMode: false,
				key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
				q:   {
					name:   "queryKey",
					parser: /(?:^|&)([^&=]*)=?([^&]*)/g
				},
				parser: {
					strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
					loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
				}
			},
			m   = o.parser[o.strictMode ? "strict" : "loose"].exec(this),
			uri = {},
			i   = 14;
		
		while (i--) uri[o.key[i]] = m[i] || "";
		
		uri[o.q.name] = {};
		uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
			if ($1) uri[o.q.name][$1] = $2;
		});
		
		return uri;
	},
	stripQuotes: function () {
		return this.gsub(/['"]/,'');	
	}

});

var $S = Form.Element.Methods.setValue;

/*
	Cookie Object
*/

var Cookie = {
	set: function(name,value,seconds){
		if(seconds){
			var d = new Date();
			d.setTime(d.getTime() + (seconds * 1000));
			var expiry = '; expires=' + d.toGMTString();
		}else
			var expiry = '';
		document.cookie = name + "=" + value + expiry + "; path=/";
	},
	get: function(name){
		var nameEQ = name + "=";
		var ca = document.cookie.split(';');
		for(var i = 0; i < ca.length; i++){
			var c = ca[i];
			while(c.charAt(0) == ' ')
				c = c.substring(1,c.length);
			if(c.indexOf(nameEQ) == 0)
				return c.substring(nameEQ.length,c.length);
		}
		return null;
	},
	unset: function(name){
		Cookie.set(name,'',-1);
	}
};

/*
	Definition object
*/

var Definition = {

	version: '0.9.1',
	/* Limit the list to those items your site will use */
	includes: $w('FormHandler Sidebar NextField Rollover'),
	registrations: [],
	require: function(libraryName) {
		document.write('<script type="text/javascript" src="'+libraryName+'"><\/script>');
	},
	register: function( classDefinition ) {
		Definition.registrations.push( classDefinition );
	},
	start: function () { 
		var path = $$('script').pluck('src').find( 
			function (s) { return s.match('definition.js') } ).stripQuotes().parseUri().directory;
		Definition.includes.each( function(include) { Definition.require( path + include.toLowerCase() + '.js' ) });
		this.addLoadEvent( function() {
			this.applyDefinitions();
		});
	},
	addLoadEvent: function(func){
		document.observe ( 'dom:loaded', 
						func.bindAsEventListener(this) )
	},
	removeDefinition: function (dClass,element) {
		element = $(element);
		// use stopObserving to finish this.
	},
	applyDefinition: function (dClass,element) {
		element = $(element);
		
		var DefinitionClass = Class.create(dClass);
						
		try {
			
			var obj = new DefinitionClass(element);
			
			window.definitions.push (obj);
			element.registerDefinition (obj);
			
			if ( element.id == '' ) {
				// Make sure every element has an id
				element.id = generateGuid();
			}
			 	
		} catch(e) {
			
			// console.log( 'Error loading ('+element.id+'): '+e.message );
			
		}		
	},
	applyDefinitions: function(){
		
		while ( def = Definition.registrations.shift() ) {

			var rootElementList = Element.select( 'body', def.classIndicator );
			if ( rootElementList.length ) { //if there is no need, dont load!
				
				var DefinitionClass = Class.create(def);
								
				rootElementList.each(function (elm){
					try {
						
						var obj = new DefinitionClass(elm);
						
						window.definitions.push (obj);
						elm.registerDefinition (obj);
						
						if ( elm.id == '' ) {
							// Make sure every element has an id
							elm.id = generateGuid();
							generatedID = true;
						}
						 	
					} catch(e) {
						
						// console.log( 'Error loading ('+elm.id+'): '+e.message );
						
					}
				});
				
			} else {
				// console.log ( 'Found no elements for definition ' + def.name + ', please remove.'  );
			};
			
		};
		
	},
	findByElement: function( element, definition ) {
		element = $(element);
		found = new Array;
		window.definitions.each( function(d){
			if ( d.element.id == element.id ) 
				if ( definition != null ){
					if ( d.name == definition ) {
						found.push(d);
					}
				} 
				else 
				{ found.push(d); }
		});
		if (found.length == 1) {
			return found[0];
		} else {
			return found;
		}
	},	
	linkDefinitions: function ( def1, method1, def2, method2 ) {

		oldfunc = def1[method1];
		
		def1[method1] = function () {
			newfunc = oldfunc.bind(this);
			return def2[method2](newfunc());
		}


	}
}

Definition.start();