/**
 * ToolBox - Caixa de ferramentas por Silas R. N. Junior 2006~2007
 * v0.0.1.30
 *
 * <TODO> Classe SELECT. (90% + ajax)
 * <TODO> Tratamento de eventos avançados. (viabilizar com objeto Win)
 * <TODO> Criar um componente para exibição de erros. (em estudo)
 * <TODO> Mecanismo de troca entre cnpj e cpf / ou validação dos dois em um mesmo campo.
 * <TODO> Componente de Exibição de icones de estado de campos Input.(80%)
 * <TODO> Suporte JSON
 */
/**
 * TOOL_PATH: Caminho até a pasta /toolbox.
 * <NOTE> É importante salientar que a existência da pasta "toolbox" no path
 * é necessária pois é o diretório raiz da aplicação. Em um domínio normal onde a
 * aplicação está na raiz esta pasta nao deverá constar.
 * 
 * 
 * DOMAIN_URL: URL completa do domínio do site.
 * <TODO> Carregar configuração via XML
 * 	novos parãmetros como a tecnologia server-side serão incorporados mais tarde.
 */
//document.getElementById('buffer').style.display = 'none'; //Tentativa de se fazer um buffer
var DOMAIN_URL = getThisDomain();
//var TOOL_PATH = 'http://' + DOMAIN_URL + '/system/';
var TOOL_PATH = '../system/';
var SERVER_EXTENSION = 'php';
//Importa as Definições padrão
imports('toolbox.core.corelib');
imports('toolbox.ajax.FactoryXMLHttpRequest');
imports('toolbox.ajax.Asynchronous');
imports('toolbox.ajax.ResponseHandler');
//imports('toolbox.ajax.Synchronous');
//imports('toolbox.ajax.XMLParser');
imports('toolbox.ajax.Cache');


/**
 * String.trim()
 * Retorna a string sem espaços antes ou depois.
 * @return = String
 */
String.prototype.trim = function(){
    return this.replace(/^\s+|\s+$/, "");
}

/**
 * Array.in_array(sStr)
 * Retorna true se a String sStr for encontrada.
 * @param = sStr (String) Palavra para Comparação
 * @return = o Índice no Array se encontrar, false caso nao.
 Array.prototype.in_array = function (sStr) {
 for (var i = 0; i < this.length; i++) {
 if (this[i] == sStr) {
 return i;
 }
 }
 return false;
 }
 */
function getThisDomain(){
    var temp = window.location.href.split("/");
    return temp[2];
}

// Array Remove - By John Resig (MIT Licensed)
Array.prototype.remove = function(from, to) {
  var rest = this.slice((to || from) + 1 || this.length);
  this.length = from < 0 ? this.length + from : from;
  return this.push.apply(this, rest);
};

in_array = function(vArray, oItem){
    for (var i = 0; i < vArray.length; i++) {
        if (vArray[i] == oItem) {
            return i;
        }
    }
    return false;
}
/**
 * Object.extend(oObjDestination, oObjSource)
 * Copia os atributos de oObjSource em oObjDestination
 * @param = oObjDestination 	(Object) Objeto de destino dos Atributos.
 * @param = oObjSource			(Object) Objeto de origem dos atributos.
 */
extend = function(destination, source){
    for (property in source) {
        destination[property] = source[property];
    }
}

///////////////////////////////////////////////////////////////
// FUNÇÕES
///////////////////////////////////////////////////////////////

/**
 * getElementByClassName()
 * retorna um array contendo elementos de uma determinada classe
 * @param = oElm			(Object) Elemento onde realizar a busca
 * @param = strTagName		(String) Tag HTML do elemento a ser buscado.
 * @param = strClassName	(String) Nome da classe.
 * @author
 *    Written by Jonathan Snook, http://www.snook.ca/jonathan
 *    Add-ons by Robert Nyman, http://www.robertnyman.com
 */
function getElementsByClassName(oElm, strTagName, strClassName){
    var arrElements = (strTagName == "*" && oElm.all) ? oElm.all : oElm.getElementsByTagName(strTagName);
    var arrReturnElements = new Array();
    strClassName = strClassName.replace(/\-/g, "\\-");
    var oRegExp = new RegExp("(^|\\s)" + strClassName + "(\\s|$)");
    var oElement;
    for (var i = 0; i < arrElements.length; i++) {
        oElement = arrElements[i];
        if (oRegExp.test(oElement.className)) {
            arrReturnElements.push(oElement);
        }
    }
    return (arrReturnElements);
}

/**
 * include(strScriptFilename)
 * @param = strScriptFilename (String) Caminho do script no servidor.
 * Inclui biliotecas JavaScript no cabeçalho da página utilizando DOM.
 */
function include(strScriptFilename, executeOnStateChange){
    var html_doc = document.getElementsByTagName('head').item(0);
    var js = document.createElement('script');
    js.setAttribute('language', 'javascript');
    js.setAttribute('type', 'text/javascript');
    if (executeOnStateChange) 
        js.setAttribute('onreadystatechange', executeOnStateChange)
    js.setAttribute('src', strScriptFilename);
    html_doc.appendChild(js);
    return false;
}

/**
 * imports(strPacote)
 * Permite a inclusão de bibliotecas com sintaxe de pacotes.
 * @param = srtPacote (String) String com o caminho do pacote
 */
function imports(strPacote, executeOnStateChange){
    strPacote = TOOL_PATH + strPacote.replace(/\./gi, '/') + '.js';
    include(strPacote, executeOnStateChange);
    return false;
}

///////////////////////////////////////////////////////////////
// OBJETOS
///////////////////////////////////////////////////////////////
/*
 Toolbox = function () {
 this.loader = new Loader();
 this.ajax = FactoryXMLHttpRequest();
 }
 Toolbox.prototype = {
 include: function () {
 
 }
 }
 */
/**
 * Loader: Object
 * se encarrega da importação de classes e da inicialização dos componentes da tela.
 */
Loader = function(){
    this.packages = Array();
    this.classes = Array();
    this.functions = Array();
    this.postponed = Array();
}

Loader.prototype = {

    /**
     * addOnLoad(function)
     * Adiciona Funcoes para serem carregadas ao fim do carregamento do documento.
     * @param = function (Object function) objeto Função a ser executado
     */
    addOnLoad: function(func){
        this.functions.push(func);
    },
    
    /**
     * execOnLoad()
     * Executa os mÃ©todos adicionados com a funcao addOnLoad
     * Deve ser anexada ao evento OnLoad documento.
     */
    execOnLoad: function(){
    
        var loaded = false;
        /*
         while (!loaded) {
	         for (var i = 0; i < this.classes.length; i++) {
		         if (this.classes[i])
		        	 loaded = true;
		         else
		         	loaded = false;
		         }
		     }
         }
         */
        for (var i = 0; i < this.functions.length; i++) {
            if (this.functions[i]) 
                this.functions[i]();
            //else
            //this.execPostponed(this.functions[i]);
        }
    },
    
    /**
     * execOnLoad()
     * Executa os mÃ©todos adicionados com a funcao addOnLoad
     * Deve ser anexada ao evento OnLoad documento.
     */
    execPostponed: function(func){
    
        //var loaded = false;
        /*
         while (!loaded) {
         for (var i = 0; i < this.classes.length; i++) {
         if (this.classes[i])
         loaded = true;
         else
         loaded = false;
         }
         }
         
         for (var i = 0; i < this.postponed.length; i++) {
         if (this.postponed[i]) {
         this.postponed[i]();
         this.splice(i,1);
         }
         
         }
         */
        //setTimeout(func,2000);
    },
    
    /**
     * addClass(strPackage)
     * Adiciona Classes para serem carregadas na inicializacao.
     * Importa o arquivo de script da classe.
     * @param = strPackage (String) string com o caminho para o pacote
     */
    addClass: function(strPackage, executeOnStateChange){
        if (!in_array(this.packages, strPackage)) {
            this.packages.push(strPackage);
            imports(strPackage, executeOnStateChange);
        }
    },
    
    /**
     * registerInstance(strPackage, oObj)
     * @param = strPackage 	(String) string com o caminho para o pacote
     * @param = oObj		(Object) objeto de tipo para registro na sessao
     */
    registerInstance: function(strPackage, oObj){
        var index = in_array(this.packages, strPackage);
        this.classes[index] = oObj;
    },
    
    /**
     * initObjects()
     * Método de inicialização dos objetos no formulário
     */
    initObjects: function(){
        for (var i = 0; i < this.classes.length; i++) {
            if (this.classes[i]) {
                switch (this.classes[i].htmlType) {
                    case 'class':
                        var vElements = getElementsByClassName(document, this.classes[i].htmlElement, this.classes[i].htmlClass);
                        break;
                    case 'tag':
                        var vElements = document.getElementsByTagName(this.classes[i].htmlElement);
                        break;
                }
                for (var j = 0; j < vElements.length; j++) {
                    //this.classes[i].extend(vElements[j],this.classes[i]);
                    this.classes[i].create(vElements[j]);
                    
                    if (vElements[j].registerFormElement) { //Registra o elemento com seu formulário
                        vElements[j].registerFormElement();
                    }
                }
            }
        }
    }
}

///////////////////////////////////////////////////////////////
// CONFIGURAÇÕES ESPECÍFICAS
///////////////////////////////////////////////////////////////

/*
 * toolBoxInit()
 * rotinas de inicialização do documento
 * deve ser incluído no onload do documento
 */

function toolBoxInit(){
    
    loader.initObjects();
    
    window.win = new Win();
    window.onunload = function(){
        win.closeChildren();
		if (!win.isReloading()) {
			if (window.opener) {
				window.opener.win.closePopup(win.name);
				//window.opener.win.unblockInput();
				//window.opener.location.reload(true);
				//alert(window.opener.document.forms[2].commit);
				//window.opener.document.forms[2].commit();
			}
		}
    }
    if (window.document.getElementById('buffer')) 
        //document.getElementById('buffer').style.display = 'block';
        window.document.getElementById('buffer').style.visibility = 'visible';
}

window.loader = new Loader();
window.onload = function(){
    loader.execOnLoad();
}

//Registro de Classes para inclusão;

//WINDOW
loader.addClass('toolbox.window.Win');

//FORMS
loader.addClass('toolbox.html.Form');
loader.addClass('toolbox.html.form.Input');
loader.addClass('toolbox.html.form.Textarea');
loader.addClass('toolbox.html.form.input.Cnpj');
loader.addClass('toolbox.html.form.input.CpfCnpj');
loader.addClass('toolbox.html.form.input.Tempo');
loader.addClass('toolbox.html.form.input.Moeda');
loader.addClass('toolbox.html.form.input.Data');
loader.addClass('toolbox.html.form.input.Cpf');
loader.addClass('toolbox.html.form.input.IE');
loader.addClass('toolbox.html.form.input.CartaoCredito');
loader.addClass('toolbox.html.form.input.Email');
loader.addClass('toolbox.html.form.input.Cep');
loader.addClass('toolbox.html.form.Select');
loader.addClass('toolbox.html.Label');
loader.addClass('toolbox.html.Div');


///////////////////////////////////////////////////////////////
// INICIALIZAÇÂO
///////////////////////////////////////////////////////////////
loader.addOnLoad(toolBoxInit);
