
// GERA NUMERO ALEATORIO PARA EVITAR PROBLEMAS COM CACHE (HISTORICO)######################
function randid() {
	var ran_unrounded=Math.random()*10000;
	var ran_number=Math.floor(ran_unrounded); 
	return "randid=" + ran_number;
}

// PEGA O ELEMENTO POR ID OU PELO PROPRIO OBJETO #########################################
function get(obj) {
	if (isString(obj))
		return document.getElementById(obj);
	
	else if (isObject(obj))
		return obj;
		
	else
		return false;
}

// RETORNA FALSE SE O TIPO FOR UNDEFINED #################################################
function is(obj)
{
	obj = get(obj);
	if (!obj)
		return false;
	
	if (typeof(obj) == "undefined")
		return false;
	else
		return true;	
}

// FUNCAO STR_REPLACE ####################################################################

function str_replace(search_str, replace_str, subject) {
    return subject.split(search_str).join(replace_str);
}

// STR REPLACE RECURSIVO #################################################################
// encontra as ocorrencias de uma string e a substitui em todos os filhos do objeto dado

numero_de_recursividades = 0; // apenas para controle
function strReplaceRecursivo(search_str, replace_str, objeto)
{
	numero_de_recursividades++;
	
	// SE FOR STRING, SUBSTITUI
	if (typeof(objeto) == "string")
	{
		objeto = str_replace(search_str, replace_str, objeto);
	}
	
	// SE FOR OBJETO PASSA PELOS ITENS
	else if (typeof(objeto) == "object")
	{
		for (var n in objeto)
		{
			objeto[n] = strReplaceRecursivo(search_str, replace_str, objeto[n]);
		}	
	}

	return objeto;
	
}

// FUNCAO TRIM ###########################################################################
function trim(str)
{
	if(!str || typeof str != 'string')
		return null;
	
	return str.replace(/^[\s]+/,'').replace(/[\s]+$/,'').replace(/[\s]{2,}/,' ');
	
}
// FIND PARENT TAG #######################################################################
function findParentTag(obj,tag)
{			
	if (!obj.tagName)
		throw new Error("O objeto parametro aparenta nao ser uma tag DOM pois não possui tagName.");
	
	// LOOP POR CADA PARENT NODE
	while (obj)
	{
		// SE O TAGNAME FOR IGUAL A TAG, RETORNA
		if (obj.tagName.toUpperCase() == tag.toUpperCase())
			return obj;
		
		// SE HOUVER PAI, COLOCA NA OBJETO
		if (obj.parentNode)
			obj = obj.parentNode;
		else
			return false;	
	}
		
}

// FIND PARENT TAG #######################################################################
function erro(msg_dev,msg_user,tit_dev,tit_user)
{
	if (!tit_dev)  tit_dev = "Erro Fatal";
	if (!tit_user) tit_user = "Erro";
	if (!msg_user) msg_user = "Ocorreu um erro na aplicação, favor tentar novamente. Caso o problema persista, contate o administrador do sistema.";
		
	// SE ESTIVER EM AMBIENTE DE DESENVOLVIMENTO
	if (typeof(MODO_DE_DESENVOLVIMENTO) != "undefined" && MODO_DE_DESENVOLVIMENTO == 1)
	{
		var titulo = tit_dev;
		var mensagem = msg_dev;
	} 
	else
	// SE ESTIVER EM AMBIENTE DE PRODUÇÃO
	{
		var titulo = tit_user;
		var mensagem = msg_user;
	}
	
	alert(titulo + '\n\n' + mensagem);
}

// VERIFICADORES DE TIPO #################################################################
function isObject(o) {
  return (typeof(o)=="object");
}
function isArray(o) {
  return (isObject(o) && (o.length) &&(!isString(o)));
}
function isFunction(o) {
  return (typeof(o)=="function");
}
function isString(o) {
  return (typeof(o)=="string");
}

// SE FOR STRING, DA O EVAL, SE FOR FUNCAO, EXECUTA ######################################
function executar(action)
{
	//alert(typeof(action));
	//alert(action);
	if (typeof(action) == "string")
		eval(action);
	else if (typeof(action) == "function")	
		action();
	else
		return false;	
}

// CLONE #################################################################################
/*
 * function clone(o) {
 return eval(uneval(o));
}
*/

function clone(obj)
{
    if(obj == null || typeof(obj) != 'object')
        return obj;

    var temp = new obj.constructor(); // changed (twice)

    for(var key in obj)
        temp[key] = clone(obj[key]);

    return temp;
}

// ADICIONA O METODO HERDAR AOS OBJETOS ##################################################
// copia para si todos os elementos do objeto pai
// se "overwrite" for setado como true, subrescreve os valores do objeto com os do novo objeto

Object.prototype.herdar = function(parent,overwrite,clonar)
{
	// SE PARENT NAO FOR OBJETO, RETORNA FALSO
	if (typeof(parent) != "object")
		return false;
  	
	// PASSA PELOS SUBOBJETOS DE PARENT E ADICIONA AO OBJETO
	for (var propriedade in parent)
	{
		if (overwrite)
		{
			if (clonar) 	this[propriedade] = clone(parent[propriedade]);	
			else			this[propriedade] = parent[propriedade];		
		}	
		else 
		{
			if (!this[propriedade]) 
			{
				if (clonar) 	this[propriedade] = clone(parent[propriedade]);	
				else			this[propriedade] = parent[propriedade];
	 		}
	 	}		
	}

};

// FUNÇÃO HERDAR =========================================================================
herdar = function(objeto, parent,overwrite,clonar)
{
	// SE PARENT NAO FOR OBJETO, RETORNA FALSO
	if (typeof(parent) != "object")
		return false;
  	
	// PASSA PELOS SUBOBJETOS DE PARENT E ADICIONA AO OBJETO
	for (var propriedade in parent)
	{		
		if (overwrite)
		{
			if (clonar) 	objeto[propriedade] = clone(parent[propriedade]);	
			else			objeto[propriedade] = parent[propriedade];	
		}	
		else 
		{
			if (!objeto[propriedade]) 
			{
				if (clonar) 	objeto[propriedade] = clone(parent[propriedade]);	
				else			objeto[propriedade] = parent[propriedade];
	 		}
	 	}		
	}
}

//OBJETO GLOBAL "FRED" ###################################################################
fred = {}


fred.onLoadFunctions = new Array();	// array com as funções que serão iniciadas ao terminar de carregar
fred.TagHeadFiles = new Array; 		// array com os arquivos carregados na tag head

// FUNÇÃO QUE ADICIONA VALORES AO ARRAY ONLOADFUNCTIONS ==================================
fred.onload = function (obj)
{
	fred.onLoadFunctions.push(obj);	
}

// INSERE AS FUNÇÕES NO ONLOAD DA WINDOW =================================================
window.onload = function ()
{
	// PASSA POR TODAS AS FUNÇÕES EXECUTANDO-AS (SE TIVER STRING DA O EVAL)
	for (n in fred.onLoadFunctions)
	{
		//alert((fred.onLoadFunctions[n]));
		if (typeof(fred.onLoadFunctions[n]) == "function")
			fred.onLoadFunctions[n]();
		else if (typeof(fred.onLoadFunctions[n]) == "string")
			eval(fred.onLoadFunctions[n]);
	}
}

// AJAX LOADJS ===========================================================================

fred.loadJS = function(caminho,absolute)
// se absolute for true, nao adiciona o ROOTURL no caminho
{
	if (!absolute)
		caminho = ROOTURL + caminho;
		
	// VERIFICA SE JÁ FOI INSERIDA ANTES
	if (!fred.TagHeadFiles[caminho])
	{
		fred.TagHeadFiles[caminho] = 1;
		tag("script",{type:"text/javascript", src: caminho + '?' + randid()},"",document.getElementsByTagName("head")[0]);
	}

}

// AJAX LOADCSS ==========================================================================
fred.loadCSS = function(caminho,absolute)
// se absolute for true, nao adiciona o ROOTURL no caminho
{
	if (!absolute)
		caminho = ROOTURL + caminho;
		
	// VERIFICA SE JÁ FOI INSERIDA ANTES
	if (!fred.TagHeadFiles[caminho])
	{
		fred.TagHeadFiles[caminho] = 1;
		tag("link",{rel:"stylesheet", type:"text/css", href: caminho + '?' + randid()},"",document.getElementsByTagName("head")[0]);
	}

}


// TRUE UNESCAPE =======================================================


function trueUnescape(txt)
{
	return unescape(txt.replace(/\+/g," "));
}