/*
TimothyHumphrey.WebControls
Copyright (c) 2003 - 2004 Timothy Humphrey

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

//-------------------- Enumerations --------------------\\
Axis = {
	X : 0
	,Y : 1
}

//-------------------- Delegate Class --------------------\\
Delegate = function(previousHandler) {
	this.Handlers = [];
	this.PreviousHandler = previousHandler;

	this.Handlers.Remove = Delegate.RemoveArrayItem;
}

Delegate.Proxies = [];

Delegate.Add = function(element, eventName, thisObj, func) {
	var proxy, delegate;

	proxy = Delegate.GetProxy(element);
	if(!proxy) {
		if(element.id)
			proxy = Delegate.Proxies[element.id] = new Object();
		else {
			Delegate.Proxies[Delegate.Proxies.length] = [];
			Delegate.Proxies[Delegate.Proxies.length - 1][0] = element;
			proxy = Delegate.Proxies[Delegate.Proxies.length - 1][1] = new Object();
		}
	}

	if(!proxy[eventName])
		proxy[eventName] = new Delegate(element["on" + eventName]);
	delegate = proxy[eventName];

	delegate.Handlers[delegate.Handlers.length] = new DelegateHandler(thisObj ? thisObj : element, func);
	element["on" + eventName] = Delegate.Handler;
}

Delegate.GetProxy = function(element) {
	var i;

	if(element.id)
		return Delegate.Proxies[element.id];
	else {
		for(i = 0; i < Delegate.Proxies.length; i++) {
			if(Delegate.Proxies[i][0] == element)
				return Delegate.Proxies[i][1];
		}
	}
}

Delegate.Handler = function(e) {
	var delegate, delegateHandler;
	var returnValue;
	var i;

	if(!e) {
		e = event;
		if(!e)
			return;
	}

	delegate = Delegate.GetProxy(this)[e.type];
	for(i = 0; i < delegate.Handlers.length; i++) {
		delegateHandler = delegate.Handlers[i];
		delegateHandler.ThisObj.__ = delegateHandler.Handler;
		returnValue = delegateHandler.ThisObj.__(e);
		delete delegateHandler.ThisObj.__;
	}

	if(delegate.PreviousHandler) {
		this.__ = delegate.PreviousHandler;
		returnValue = this.__(e);
		delete this.__;
	}

	return returnValue;
}

Delegate.Remove = function(element, eventName, thisObj, func) {
	var proxy, delegate, delegateHandler;
	var i;

	proxy = Delegate.GetProxy(element);
	if(proxy && proxy[eventName]) {
		delegate = proxy[eventName];
		if(!thisObj)
			thisObj = element;

		for(i = 0; i < delegate.Handlers.length; i++) {
			delegateHandler = delegate.Handlers[i];
			if(delegateHandler.ThisObj == thisObj && delegateHandler.Handler == func) {
				delegate.Handlers.Remove(i);
				break;
			}
		}

		if(delegate.Handlers.length == 0) {
			element["on" + eventName] = delegate.PreviousHandler;
			delete proxy[eventName];
		}
	}
}

Delegate.RemoveArrayItem = function(index) {
	var i;

	for(i = index; i < this.length - 1; i++)
		this[i] = this[i + 1];
	this.length--;
}

//-------------------- DelegateHandler Class --------------------\\
DelegateHandler = function(thisObj, handler) {
	this.ThisObj = thisObj;
	this.Handler = handler;
}

//-------------------- List Class --------------------\\
function List() {
	this.Count = 0;
	this._list = [];
}

List.prototype.Add = function(obj) {
	this._list[this._list.length] = obj;
	this.Count++;
	return obj;
}

List.prototype.Item = function(index) {
	return this._list[index];
}

List.prototype.Remove = function(obj) {
	var i;

	for(i = 0; i < this._list.length; i++) {
		if(this._list[i] == obj) {
			this.RemoveAt(i);
			return;
		}
	}
}

List.prototype.RemoveAt = function(index) {
	var i;

	for(i = index; i < this._list.length - 1; i++)
		this._list[i] = this._list[i + 1];
	this._list.length--;
	this.Count--;
}

//-------------------- Point Class --------------------\\
function Point(x, y) {
	this.X = x;
	this.Y = y;
}

Point.prototype.toString = function() {
	return this.X + ", " + this.Y;
}

//-------------------- Rect Class --------------------\\
function Rect(left, top, width, height) {
	this.Left = left;
	this.Top = top;
	this.Width = width;
	this.Height = height;
}

Rect.prototype.Contains = function(rect, axis) {
	var okay = true;

	if(axis == null || axis == Axis.X)
		okay &= rect.Left >= this.Left
			&& rect.Left + rect.Width <= this.Left + this.Width;
	if(axis == null || axis == Axis.Y)
		okay &= rect.Top >= this.Top
			&& rect.Top + rect.Height <= this.Top + this.Height;
	return okay;
}

Rect.prototype.Intersects = function(rect, axis) {
	var okay = true;

	if(axis == null || axis == Axis.X)
		okay &= rect.Left < this.Left + this.Width
			&& rect.Left + rect.Width > this.Left;
	if(axis == null || axis == Axis.Y)
		okay &= rect.Top < this.Top + this.Height
			&& rect.Top + rect.Height > this.Top;
	return okay;
}

Rect.prototype.toString = function() {
	return this.Left + ", " + this.Top + ", " + this.Width + ", " + this.Height;
}

