/*
	Código para correção do bug do IE de flicker em background-image css styles.
*/

try
{
  document.execCommand("BackgroundImageCache", false, true);
}
catch(e) {}

/*
	Extensão das funcionalidades dos elementos HTML.
	No navegador mozilla, os elementos não possuem o método contains. 
	Neste caso, o método abaixo é utilizado para criar o método contains.
*/

if (typeof(HTMLElement) != "undefined")
{
	HTMLElement.prototype.contains = function(child)
	{
		var element = child;

		while (element != null)
		{
			if(element == this)
			{
				return true;
			}
			
			element = element.parentNode;
		}

		return false;
	}
}

/*
	Extensão das funcionalidades do array
*/




Array.prototype.add = Array.prototype.queue = function(item)
{
    this.push(item);
}

Array.prototype.addRange = function(items)
{
	if (items == null || items.length == 0) return;
    
	for (var i = 0; i < items.length; i++)
	{
		this.push(items[i]);
	}
}

Array.prototype.clear = function()
{
	if (this.length > 0)
	{
		this.splice(0, this.length);
	}
}

Array.prototype.clone = function()
{
	var clonedArray = [];

	for (var i = 0; i < this.length; i++)
	{
		clonedArray[i] = this[i];
	}

	return clonedArray;
}

Array.prototype.contains = Array.prototype.exists = function(item)
{
	return (this.indexOf(item) >= 0);
}

Array.prototype.dequeue = function()
{
	return this.shift();
}

if (!Array.prototype.indexOf)
{
	Array.prototype.indexOf = function(item, startIndex)
	{
		if (this.length == 0) return -1;
		
		startIndex = (startIndex || 0);

		if (startIndex < 0)
		{
			startIndex = Math.max(0, this.length + startIndex);
		}
	
		for (var i = startIndex; i < this.length; i++)
		{
			if (this[i] == item)
			{
				return i;
			}
		}

		return -1;
	}
}

if (!Array.prototype.forEach)
{
    Array.prototype.forEach = function(fnCb, context)
    {
		for (var i = 0; i < this.length; i++)
		{
			fnCb.call(context, this[i], i, this);
		}
    }
}

Array.prototype.insert = function(index, item)
{
	this.splice(index, 0, item);
}

Array.prototype.remove = function(item)
{
	var index = this.indexOf(item);

	if (index >= 0)
	{
		this.splice(index, 1);
	}

	return (index >= 0);
}

Array.prototype.removeAt = function(index)
{
	this.splice(index, 1);
}

Array.parse = function(value)
{
	return eval('(' + value + ')');
}


/*
	Extensão das funcionalidades da string.
	Adição de um método estático para formatar strings.
	Uso similar ao método Format da classe String no C#.
	
	Ex:
	
		String.format("{0}px", 95);
		Result: "95px"
*/

String.format = function()
{
	if (arguments.length == 0)
	{
		return null;
	}
	else if (arguments.length == 1)
	{
		return arguments[0];
	}
	else
	{
		var str = arguments[0];

		for (var i = 1; i < arguments.length; i++)
		{
			var regex = new RegExp("\\{" + (i - 1) + "\\}", "g");
			var value = arguments[i];
			if (value != null) value = arguments[i].toString();

			str = str.replace(regex, value);
		}

		return str;
	}
}

String.isNullOrEmpty = function(value)
{
	return (value == null || value == String.empty);
}

String.empty = "";


/*
	Extensão das funcionalidades da string.
	Adição de um método de instância para substituir todas as ocorrências de um determinando valor por outro.
*/

String.prototype.replaceAll = function(oldValue, newValue)
{
	var value = this;
	var index = value.indexOf(oldValue);

	while (index > -1)
	{
		value = value.replace(oldValue, newValue); 
		index = value.indexOf(oldValue);
	}

	return value;
}

String.prototype.endsWith = function(suffix)
{
	return (this.substr(this.length - suffix.length) == suffix);
}

String.prototype.startsWith = function(prefix)
{
	return (this.substr(0, prefix.length) == prefix);
}

String.prototype.lTrim = String.prototype.trimLeft = function()
{
	return this.replace(/^\s*/, String.empty);
}

String.prototype.rTrim = String.prototype.trimRight = function()
{
	return this.replace(/\s*$/, String.empty);
}

String.prototype.trim = function()
{
	return this.trimRight().trimLeft();
}


/*
	Extensão das funcionalidades dos objetos javascript.
	Verifica se um objeto é de um determinado tipo.
*/

Object.isType = function(instance, type)
{
	return (instance != null && instance.constructor == type);
}


/*
	Extensão das funcionalidades da biblioteca Math.
	Altera a quantidade de casas decimais de um número.
*/

Math.roundDecimal = function(number, decimalPlaces)
{
	return Math.round(number * Math.pow(10, decimalPlaces)) / Math.pow(10, decimalPlaces);
}

/*

*/

Error.Create = function(message, details, innerError)
{
    var e = new Error(message);

    if (details && details.length)
    {
        e.details = details;
    }

    if (innerError)
    {
        e.innerError = innerError;
    }

    return e;
}
