// global functions, and systems to hack the various browsers.
function attachEventHandler(oObject, sMethodName) {
	return function () {
		return oObject[sMethodName].apply(oObject, arguments);
	};
}
// extend the object object to include a way of extending the prototype handler.
Object.prototype.extend = function(obj){
    var method;
    for (method in obj)
    {
        if (!Object.prototype.hasOwnProperty(method))
            this[method] = obj[method];
    }
}
// extend the array object to include some much needed functionality.
Array.prototype.sum = function(){
	for(var i=0,sum=0;i<this.length;sum+=this[i++]);
	return sum;
}
Array.prototype.max = function(){
	return Math.max.apply({},this)
}
Array.prototype.min = function(){
	return Math.min.apply({},this)
}

// freevolution code, not tied into the main class as it can live in the global area.
function checkbounds(img,event){
	// returns true if the cursor is in bounds for the current cursor image
	// We are going to return an array(dX,dY)
	dX = 0; dY = 0;
	// Figure out where the cursor is in relation to the image
	x = event.layerX; // - parseInt(img.style.left);
	y = event.layerY; // - parseInt(img.style.top);	
	//debugmessage(x+'='+y);
	// Looks like theres something in IE thats causing our x to shift
	// to the right, countered here by decreasing the perceived value of x
	//x--;	
	// Find the relative height positions from our image name
	// We are expecting something of the form 0-0-0-0 in it
	
	//arrId = img.src.match(/\d\-\d\-\d\-\d/);
	//arrH = arrId[0].match(/\d/g);
	//alert(img.src +",x="+x+",y="+y);
	
	//if(x>64 || y>img.height){
	//	return false;
	//}
	
	var arrH = img.src.match(/\d\-\d\-\d\-\d/)[0].split('-');
	
	// array index: 0=top, 1=right, 2=bottom, 3=left
	// Make them all ints, rather than strings
	
	// See if we are on the image, if not an other handler will jump in
	
	// See if we are out of bounds
	if(x<=32) {
		// Left hand side of the tile
		dyt = 8 * (2 + parseInt(arrH[0]) - parseInt(arrH[3]));
		dyb = 8 * (2 + parseInt(arrH[3]) - parseInt(arrH[2]));
		tstt = dyt-(x*dyt/32);
		tstb = dyt+(x*dyb/32);
		if(y<tstt) {
			// Top Left
			dX = -1;
		}
		if(y>tstb) {
			// Bottom Left
			dY = 1;
		}
	} else {
		// Right hand side of the tile
		dyt = 8 * (2 + parseInt(arrH[0]) - parseInt(arrH[1]));
		dyb = 8 * (2 + parseInt(arrH[1]) - parseInt(arrH[2]));
		tstt = (x*dyt/32)-dyt;
		tstb = (2*dyb)+dyt-(x*dyb/32);
		if(y<tstt) {
			// Top Right
			dY = -1;
		}
		if(y>tstb) {
			// Bottom Right
			dX = 1;
		}
	}
	if(dX==0 && dY == 0){ // Not out of bounds
		return false;
	} else { // Out of bounds - return direction to move
		return new Array(dX,dY); 
	}
}

function setopacity(obj,amount){
	// either insert integer amounts (eg 100 to 1, or 0),
	// or insert decimal amounts, <1 && >0, which will be multipled by 100 to become integer
	var amount=parseFloat(amount);
	if(!obj){
 		return false;
	}
	if(amount<1 && amount!=0){ // is this save?
		amount=amount*100;
	}
	if (obj.addEventListener) { //w3c
		obj.style.MozOpacity=amount/100;
		obj.style.opacity=amount/100;
	} else {
		obj.style.filter='alpha(opacity='+amount+')';
	}
	return true;
}
// debug handler
var debugwindow=null;
function debugmessage(message){
	if(debugwindow==null){
		debugwindow=document.getElementById('debugwindow');
	}
	debugwindow.value=message+"\n"+debugwindow.value;	
	return true;
}

// align all browsers to have an XMLHttpRequest function.
if (!window.XMLHttpRequest)
{
    window.XMLHttpRequest = function()
    {
        var types = [
            'Microsoft.XMLHTTP',
            'MSXML2.XMLHTTP.5.0',
            'MSXML2.XMLHTTP.4.0',
            'MSXML2.XMLHTTP.3.0',
            'MSXML2.XMLHTTP'
        ];

        for (var i = 0; i < types.length; i++)
        {
            try
            {
                return new ActiveXObject(types[i]);
            }
            catch(e) {}
        }

        return undefined;
    }
}
// our ajax handler class, we need to have ONE for all frevolution instances
function AjaxPool()
{
	// class too hold all Ajax threads for the antire browser.
	this.maxConcurrentRequests = 2;
	this.pool = [];
	this.queue = [];
}
AjaxPool.prototype =
{
	addRequest: function(url, type, handler, object)
	{
		if (!object) object = window;
		if (!handler) handler = function() {};
		if (!type){
			type = 'GET';
		} else {
			type = type.toUpperCase();
			if (type != 'GET' && type != 'POST'){
				type = 'GET';
			}
		}
		this.queue.push(
			{
			url: url,
			type: type,
			handler: handler,
			object: object
			}
		);
		// debugmessage('adding to stack!, stacklength:'+this.queue.length);
		this.checkQueue();
	},
	
	checkQueue: function()
	{
		var i = 0;
		do
		{
			if (!this.pool[i] || this.pool[i].busy == false)
			{
				var request;
				if ((request = this.queue.shift()))
				{
					var self = this;
					var slot = this.pool[i] =
					{
						xmlhttp: new XMLHttpRequest(),
						busy: true
					}
					slot.xmlhttp.open(request.type, request.url, true);
					slot.xmlhttp.onreadystatechange = function()
					{
						if(slot.busy != false){
							if (slot.xmlhttp.readyState == 4 &&
							(!slot.xmlhttp.status ||
								(slot.xmlhttp.status >= 200 && slot.xmlhttp.status < 400)))
							{
							slot.busy = false;
							request.handler.call(request.object, slot.xmlhttp.responseXML);
							self.checkQueue();
							} else if(slot.xmlhttp.readyState == 4 &&
								(!slot.xmlhttp.status || slot.xmlhttp.status >= 400)){
								alert('http error in ajax query., please examine.');
								slot.busy = false;
								slot.xmlhttp.abort();
								self.checkQueue();
							}
						}
					}
					slot.xmlhttp.send(null);
				}
				break;
			}
		}
		while (++i < this.maxConcurrentRequests);
	}
}