function Toolkit()
{
}

Toolkit.EMPTY_STRING = "";

Toolkit.UNKNOWN		= 0x00;
Toolkit.PNG 		= 0x01;
Toolkit.JPG 		= 0x02;
Toolkit.GIF 		= 0x03;

Toolkit.INTERNET_EXPLORER 	= 0x10;
Toolkit.NETSCAPE			= 0x20;

// public static int getImageType(String url);
Toolkit.getImageType = function(path)
{
	var n = -1;
	
	if(path == null)
	{
		throw new Error("Parameter 'path' cannot be null");
	}
	
	n = path.lastIndexOf('.');
	
	if(n == -1)
	{
		return Toolkit.UNKNOWN;
	} else
	{
		var imageType = Toolkit[path.substring(n + 1).toUpperCase()];
		
		if(!imageType)
		{
			imageType = Toolkit.UNKNOWN;
		}
		
		return imageType;
	}
};

// public static void getImage = function(String path, void(String path, Element<img> image) callback);
Toolkit.getImage = function(path, callback, context)
{
	var image = new Image();
	var wrap = (Toolkit.getImageType(path) == Toolkit.PNG && !Toolkit.isPNGNativelySupported());
	
	image.src = path;
	
	if(image.complete)
	{
		callback(path, Toolkit.initializeImage(image, wrap), false, context);
	} else
	{
		image.onload = function()
		{
			callback(path, Toolkit.initializeImage(image, wrap), true, context);
		};
	}
	
	return image.complete;
};

// public static Element<?> Toolkit.initializeImage(Element<img> image, boolean isPng);
Toolkit.initializeImage = function(image, isPng)
{
	var element = null;
	
	if(isPng)
	{
		element = document.createElement("div");
		
		with(element.style)
		{
			filter	= "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='" + image.src + "', sizingMethod='scale')";
		}
	} else
	{
		element = document.createElement("img");
		element.src = image.src;
		element.ondrag = function() { return false; }
		element.dragDrop = function() { return false; }
		element.galleryImg = false;
	}
	
	with(element.style)
	{
		position	= "absolute";
		left		= 0;
		top 		= 0;
		width		= image.width;
		height		= image.height;
	}
	
	element.onselectstart = function() { return false; };
	
	return element;
};

// public static boolean isPNGNativelySupported();
Toolkit.isPNGNativelySupported = function()
{
	return !(Toolkit.getBrowser() == Toolkit.INTERNET_EXPLORER && Toolkit.getBrowserVersion() < 7);
};

// public static int getBrowser();
Toolkit.getBrowser = function()
{
	switch(window.navigator.appName)
	{
		case 'Microsoft Internet Explorer':
			return Toolkit.INTERNET_EXPLORER;
		case 'Netscape':
			return Toolkit.NETSCAPE;
		default:
			return Toolkit.UNKNOWN;
	}
};

// public static int getBrowserVersion();
Toolkit.getBrowserVersion = function()
{
	var appVersion = window.navigator.appVersion;
	
	switch(Toolkit.getBrowser())
	{
		case Toolkit.INTERNET_EXPLORER:
			var n = appVersion.indexOf("MSIE ");
			var m = appVersion.indexOf(";", n + 5);
			
			return parseFloat(appVersion.substring(n + 5, m));
	}
};

Toolkit.composeDirectoryListing = function(dirUrl, resourceUrls)
{
	var array = new Array(resourceUrls.length);
	for(var i = 0; i < resourceUrls.length; i++)
	{
		var resourceUrl = resourceUrls[i];
		
		if(resourceUrl)
		{
			array[i] = dirUrl + "/" + resourceUrl;
		}
	}
	
	return array;
};

// public Function getMethodPointer(Object thiz, Function func);
function getMethodPointer(thiz, func)
{   
	var args = new Array(arguments.length - 2);
	
	for(var i = 2; i < arguments.length; i++)
	{
	    args[i - 2] = arguments[i];     
	}
    
	return function()
	{
		var funcArgs = new Array(args.length + arguments.length);
				
		for(var i = 0; i < args.length; i++)
		{
			funcArgs[i] = args[i];
		}
		
		for(var i = 0; i < arguments.length; i++)
		{
			funcArgs[args.length + i] = arguments[i];
		}
		
		return func.apply(thiz, funcArgs);
	};
}

function getInvokationContext(func)
{
    var args = subArray(arguments, 1);
    return function()
    {
        var argsUnion = new Array(args.length + arguments.length);
        
        for(var i = 0; i < args.length; i++)
        {
            argsUnion[i] = args[i];
        }
        
        for(var i = 0; i < arguments.length; i++)
        {
            argsUnion[args.length + i] = arguments[i];
        }
        
        return func.apply(null, argsUnion);
    };
};

// public Function extend(Object thiz, Function zuper);
function extend(thiz, zuper)
{
	zuper.apply(thiz, subArray(arguments, 1));
}

// public void arrayCopy(Array dst, int dstIndex, Array src, int srcIndex, int count);
function arrayCopy(dst, dstIndex, src, srcIndex, count)
{
	if(dstIndex < 0 || dstIndex + count > dst.length)
	{
		throw new Error("Index out of bounds (dst)");
	} else if(srcIndex < 0 || srcIndex + count > src.length)
	{
		throw new Error("Index out of bounds (src)");
	}
	
	for(var i = 0; i < count; i++)
	{
		dst[dstIndex + i] = src[srcIndex + i];
	}
}

// public boolean isUndefined(var reference);
function isUndefined(reference)
{
	return (typeof reference == "undefined");
}

// public Array subArray(Array array, int index, int count);
function subArray(array, index, count)
{
	if(isUndefined(count))
	{
		count = array.length - index;
	}
	
	if(index < 0 || index + count > array.length)
	{
		throw new Error("Index out of bounds");
	} else
	{
		var newArray = new Array(count);
		for(var i = 0; i < count; i++)
		{
			newArray[i] = array[index + i];
		}
		
		return newArray;
	}
}

// Element<script> include(String url);
function include(url, callback)
{
	var script = null;
	
	if(!url)
	{
		throw new Error("include() - Parameter 'url' cannot be null");
	} else
	{		
		var proxy = Proxy.create();
		
		/*if(!this.proxy)
		{
			this.proxy = new Proxy.create();
		}*/
		
		proxy.load(url, function(success, content) {
			if(success)
			{
				var script = document.createElement("SCRIPT");
				
				script.type = "text/javascript";
				script.text = content;
				
				document.body.appendChild(script);
			}
			
			if(callback)
			{
				callback(success);
			}
		});
	}

	return script;
}

// boolean isFunction(var object);
function isFunction(object)
{
	return typeof object == "function";
};

function getStackTrace(offset)
{
	var stackTrace = [];
	var frame = getStackTrace;
	
	offset = (offset ? offset : 0);
	
	for(var i = 0; frame = frame.caller; i++)
	{
		if(i < offset)
		{
			continue;
		} else
		{
			var string = frame.toString();
			var m = string.indexOf(' '), n = string.indexOf('('), o = string.indexOf(')');
			
			if(m == -1 || n == -1 || m >= n || m >= o)
			{
				break;
			} else
			{
				var args = frame.arguments;
				
				string = string.substring(m + 1, n) + "(";
				for(var j = 0; j < args.length; j++)
				{
					var arg = args[j];
					
					if(typeof arg == "string")
					{
						string += "\"" + arg + "\"";
					} else
					{
						string += arg;
					}
					
					if(j != args.length - 1)
					{
						string += ', ';
					}
				}
				
				stackTrace.push(string + ')');
			}
		}
	}
	
	return stackTrace;
};

function raise(message)
{
	throw new Error(message + "\n" + getStackTrace(1));
}

// public boolean isNumber(Object object);
function isNumber(number)
{
    return typeof number == "number";
}

function isNaN(number)
{
	return number == Number.NaN;
}

function toHexString(number)
{
	if(!isNumber(number))
	{
		throw new Error("toHexString - Invalid argument '" + number + "'");
	} else
	{
		var string = "";
		
		do
		{
			var rem = number % 16;
			
			number = Math.floor(number / 16);
			string = Toolkit.HEX_LITERAL[rem] + string;
		} while(number > 0);
		
		return string;
	}
}

Toolkit.HEX_LITERAL = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'];
