﻿RegExp.prototype.Matches = function(str)
{
	var lastIndex = 0;
	var result = new Array();
	if(str == null)
		str = "";
	while(lastIndex < str.length)
	{
		var match = this.exec(str);
		if(match == null)
			break;
		
		result.push(match);
		str = str.substr(match.index + match[0].length);
		
	}
	return result;
}
Array.prototype.remove = function(item)
{
	var i = this.indexOf(item);
	if(i != -1)
		this.splice(i, 1);
}
Array.prototype.indexOf = function(item)
{
	for(var i = 0; i < this.length; ++i)
		if(this[i] == item)
			return i;
	return -1;
}
Array.prototype.IndexWhere = function(predicate)
{
	for(var i = 0; i < this.length; ++i)
	{
		if(predicate(this[i]))
			return i;
	}
	return -1;
}
Array.prototype.Where = function(predicate)
{
	var res = new Array();
	for(var i = 0; i < this.length; ++i)
		if(predicate(this[i]))
			res.push(this[i]);
	return res;
}
function inherit(base, child, baseName)
{
	if(baseName == null)
	{
		var sConstructor = base.toString();
		var aMatch = sConstructor.match( /\s*function (.*)\(/ );
		if(aMatch != null)
			baseName = aMatch[1];
	}
	if(baseName == null || baseName == "") return;
	child.prototype[baseName] = base; // allows for syntax like "ChildClass() { this.BaseClass(...); ... }
	child.prototype.base = base; // allows for syntax like "ChildClass() { this.base(...); ... }
	// copy static methods
	if(child.base == null)
		child.base = new Object();
	child[baseName] = new Object();
	for(var i in base)
	{
		if(i != "prototype" && i != "base" && i != baseName && i != "bind")
			child[i] = 
				child.base[i] =
				child[baseName][i] =
				 base[i];
	}
	
	for(var i in base.prototype)
	{
		child.prototype[baseName][i] = // this.BaseClass.function.call(this, ....);
			child.prototype.base[i] = // this.base.function.call(this, ....); (will break with M.I. - only latest inherited class will be available)
			base.prototype[i];
		if(i != "base")
			child.prototype[i] = base.prototype[i]; // this.function(...); these will be (possibly) overridden (virtual-like behavior)
	}
}
function Char()
{
}
Char.isWhiteSpace = function(c)
{
	return (c == ' ' || c == '\t' || c == '\r' || c == '\n');
}
String.prototype.trimStart = function()
{
	var i;
	for(i = 0; i < this.length; ++i)
	{
		if(!Char.isWhiteSpace(this.charAt(i)))
			break;
	}
	return this.substr(i);
}
String.prototype.trimEnd = String.prototype.TrimEnd = function()
{
	var i;
	for(i = this.length - 1; i > -1; --i)
	{
		if(!Char.isWhiteSpace(this.charAt(i)))
			break;
	}
	return this.substr(0, i + 1);
}
String.prototype.trim = String.prototype.Trim = function()
{
	return this.trimStart().trimEnd();
}
String.prototype.appendZeros = String.prototype.AppendZeros = function(numCharacters)
{
	var t = this;
	while(t.length < numCharacters)
		t = "0" + t;
	return t;
}
String.prototype.Replace = function(search, replace)
{
	var res = "";
	for(var i = 0; i < this.length; ++i)
	{
		if(this.substr(i, search.length) == search)
		{
			res += replace;
			i += search.length - 1;
		}
		else
			res += this.charAt(i);
	}
	return res;
}
var saveDateToString = Date.prototype.toString;
Date.prototype.toString = function(formatString)
{
	if(formatString == null)
		return saveDateToString.call(this);
	
	var hours = this.getHours() % 12 == 0 ? 12 : this.getHours() % 12;
	formatString = formatString.replace("hh", hours.toString().toString().appendZeros(2));
	formatString = formatString.replace("h", hours.toString());

	formatString = formatString.replace("mm", this.getMinutes().toString().appendZeros(2));
	formatString = formatString.replace("m", this.getMinutes());
	
	formatString = formatString.replace("ss", this.getSeconds().toString().appendZeros(2));
	formatString = formatString.replace("s", this.getSeconds());

	formatString = formatString.replace("yyyy", this.getFullYear());
	formatString = formatString.replace("yy", (this.getFullYear() % 100).toString().appendZeros(2));

	formatString = formatString.replace("MM", this.getMonth().toString().appendZeros(2));
	formatString = formatString.replace("M", this.getMonth().toString());

	formatString = formatString.replace("dd", this.getDate().toString().appendZeros(2));
	formatString = formatString.replace("d", this.getDate());

	formatString = formatString.replace("tt", this.getHours() >= 12 ? "PM" : "AM");
	formatString = formatString.replace("t", this.getHours() >= 12 ? "P" : "A");
	return formatString;							
}







Function.prototype.bind = function(object, argument_list)
{	
	var method = this;
	var args = new Array();
	for(var i=1; i < arguments.length; ++i)
	{
		args.push(arguments[i]);
	}
	return function () 
		{
			var args2 = new Array();
			for(var i=0; i < arguments.length; ++i)
			{
				args2.push(arguments[i]);
			}
			if(arguments.length == 0 && window.event != null && arguments.caller == null)
				args2.push(window.event);
			return method.apply(object, args2.concat(args));
		};
}
Function.prototype.bindSimple = Function.prototype.bind;






