/**
*	prototype.ext.js
*
*	by Peter Welch, peter@beepix.com
*
*	These are extensions written on top of the prototype.js code.
*
*/
/* General function extensions and replacements */

/*
Ajax Class: Adds incrementer and multiple attempts
*/

var incrementing = 0;  //Left this is in case ajax responses need to be ordered

var Ajaxed = Class.create();

Ajaxed.prototype = {
	initialize:function(settings) {
		this.tries = 0;
		if(!settings) settings = {};
		this.setup(settings);
	},
	//Lifted en toto from prototype.
	getTransport: function() {					
    	return Try.these(
      		function() {return new XMLHttpRequest()},
      		function() {return new ActiveXObject('Msxml2.XMLHTTP')},
    		function() {return new ActiveXObject('Microsoft.XMLHTTP')}
    	) || false;
  	},
	setup:function(settings) {
		this.settings = Object.extend({
			loading_txt:"Loading...",
			success_txt:"Success",
			failure_txt:"Failure",

			loading:function(){},
			success:function(){},
			failure:function(){},
	
			maxTries:2,
			method:"GET",
			url:'',
			prm:''
		}, settings || {});
	},
	parseGet:function(variables) {
		if(!variables.toString().match(/^\?/))
		{
			query = $H(variables);
			return query.toQueryString();
		} else {
			return variables.slice(1);
		}
	},
	fire:function() {
		incrementing++;
		var cycle_out = this;
		var transport = cycle_out.getTransport();
		//transport.pointfire = incrementing;
		
		var sendUrl = cycle_out.settings.url+'?'+cycle_out.parseGet(cycle_out.settings.prm);
		transport.open("GET", sendUrl, true);
		transport.onreadystatechange = function() {
			if (transport.readyState < 4) 
			{
				result = cycle_out.settings.loading_txt;
				cycle_out.settings.loading(result);
			} 
			else 
			{
				if (transport.status == 200)
				{
					cycle_out.tries = 0;
					result = cycle_out.settings.success_txt;
					output = transport.responseText;
					cycle_out.settings.success(output,result);
				}
				else
				{
					cycle_out.tries++;
					if(cycle_out.tries > cycle_out.settings.maxTries) 
					{
						cycle_out.tries = 0;
						result = cycle_out.settings.failure_txt;
						cycle_out.settings.failure(result);
					}
					else 
					{
						cycle_out.fire();
					}
				}
			}
		}
		transport.send(null);
	}
};
/*
Creates instance of action class
*/
function $AX(vars,trg_url,settings, mods)
{
	settings.prm = vars;
	settings.url = trg_url;
	if (mods) Object.extend(settings,mods);
	var Instance = new Ajaxed(settings);
	Instance.fire();
}

/* 
Action binder function; binds a class of actions to objects based on 
a css-style selector
*/
function $ACTION(selector_path, actionset, clear)
{
	var objects = $$(selector_path);
	var ac = new actionset;
	objects.each(function(object){
		ac.actionReference.each(function(actionGrab){

			reference = ac[actionGrab];
			if(!clear) Event.observe(object, actionGrab, reference, false);
			else Event.stopObserving(object, actionGrab, reference, false);
		});
	});
}

/*
Window binder: specifically for organizing large numbers of load 
actions spread around multiple js files.
*/
var WindowSet = Class.create();

WindowSet.prototype = {
	initialize:function() { 
		this.functions = [];
	},
	//Manages passed variables and avoids reference and recursion errors
	rebuild: function(func, value) { 
		return function() { 
			func(value);
		}
	},
	//Adds a function at the beginning
	priority:function(func,value) {
		this.functions.unshift(this.rebuild(func,value));
	},
	//Adds a function on the end
	add:function(func, value) {
		this.functions.push(this.rebuild(func,value));
	},
	//Inserts function at particular location and pushes others forward
	insert:function(func,locate,value) {
		if (!this.functions[locate])
			this.functions.push(this.rebuild(func,value));
		else {	
			var swap = this.functions[locate];
			this.functions[locate] = this.rebuild(func,value);
			var it = locate + 1;
			while(this.functions[it]) {
				var hold = this.functions[it];
				this.functions[it] = swap;
				swap = hold;
				it++;
			}
			this.functions.push(swap);
		}
	},
	//Executes functions in the assigned order
	fire:function() {
		this.functions.each(function(func) { 
			Event.observe(window, "load", func, false);
		});
	}
};
var Window = new WindowSet();


