general.js

/**
 * Contiene muchas funciones usadas anteriormente en el BPMS para simplificar algunas lógicas en javascript. 
 * De lo más importante son las funciones de serialización de los datos en XML
 * @module General
 */

/** 
*Funcion utilizada en los Text Area para saber cuantos caracteres se pueden escribir
*@param {string} field Nombre del campo
*@param {integer} countfield Conteo Actual
*@param {integer} maxlimit Limite maximo de caracteres
*/
function textCounter(field, countfield, maxlimit) {
    if (field.value.length > maxlimit) // if too long...trim it!
        field.value = field.value.substring(0, maxlimit);
    // otherwise, update 'characters left' counter
    else
        countfield.value = maxlimit - field.value.length;
}

/**
*Retorna el elemento correspondiente al ID -- $: document.getElementById
*@param elemID {String} id del elemento
*@returns {Object} Elemento, si no lo encuentra devuelve null, tener cuidado
*/
function $(elemID) {
    var obj

    if (document.getElementById) {
        obj = document.getElementById(elemID);
    }
    else if (document.all) {
        obj = document.all(elemID);
    }
    else if (document.layers) {
        obj = document.layers[elemID];
    }
    else if (obj == null && document.getElementsByName) {
        obj = document.getElementsByName(elemID)[0];
    }
    return obj
}

/**
*Retorna el primer Objeto con el Name suministrado a la funcion
*@param elemID {String} Name del Objeto 
*@returns {Object}
*/

function $n(elemID) {
    var obj
    if (document.getElementsByName) {
        obj = document.getElementsByName(elemID)[0];
    }
    return obj
}
/**
*Retorna el valor del elemento correspondiente al ID
*@param elemID {String} ID del elemento
*@returns Valor del elemento, si no lo encuentra devuelve null
*/

function $v(elemId) {
    if($(elemId) == null)
        return null

    return $(elemId).value;
}
/**
*Retorna el HTML del elemento correspondiente al ID
*@param elemID id del elemento
*@returns HTML del elemento
*/
function $ih(elemId) {
    if($(elemId) == null)
        return null

    return $(elemId).innerHTML;
}

/**
*Retorna si el elemento correspondiente al ID esta chequeado o no esta chequeado
*@param elemID {String} id del elemento
*@returns {Boolean} Si el control está chequeado o no
*@tutorial first
*/
function $ck(elemId) {
    if ($(elemId) == null)
        return null

    return $(elemId).checked;
}
/**
*@description Retorna el valor del radio button chequeado  correspondiente al Name
*@param elemID {String} Name del conjunto de radios
*@returns Valor del elemento (radio)
*/
function $vr(elemId) {    
    var element = document.getElementsByName(elemId);
    for (var i = 0; i < element.length; i++)
        if (element[i].checked) return element[i].value;
    
    return '';
}

/**
*@param elemId {String} ID del Select 
*@returns {String}  Texto  seleccionado 
*@deprecated
*@description Retorna el texto de el Option seleccionado en un Select
*/

function $stext(elemId) {
    if ($(elemId) == null)
        return null
    return $(elemId).options[$(elemId).selectedIndex].text    
}
/**
*@param elemId {String} Name del conjunto de radio buttons 
*@param value {String} Valor del radio button
*@description Chequea un radio button segun el value dado en la funcion
*/
function $svr(elemId, value) {
    var element = document.getElementsByName(elemId);
    for (var i = 0; i < element.length; i++) {
        if (element[i].value == value) {
            element[i].checked = true;
            return;
        }
    }
}
/**
*Da el foco al elemento con el Id que se suministre en la funcion
*@param elemId {String} Id del elemento
*@returns {Object}
*/

function $fc(elemId) {
    if ($(elemId) == null)
        return null

    return $(elemId).focus();
}

/**
*Chequea un radio button segun el value suministrado en la funcion 
*@param elemId {String} Name del conjunto de radio buttons 
*@param value {String} valor del radio button
*@deprecated
*
*/
function $cvr(elemId, value) {
    var element = document.getElementsByName(elemId);
    for (var i = 0; i < element.length; i++)
        if (element[i].value == value)
            element[i].checked = true;

    return '';
}

/**
*Retorna el ID del elemento (radio) chequeado 
*@param elemId {String} Name del contenedor de los radios
*@returns {String} ID del radio  button
*/
function $rIdCk(elemId) {
    var element = document.getElementsByName(elemId);
    for (var i = 0; i < element.length; i++)
        if (element[i].checked) return element[i].id;

    return '';
}

//Selecciona la opción de un select que contenga el texto
/**
*Selecciona el Option de un select que contenga el texto suministrado en la funcion
*@param selectId {String} ID del elemento Select
*@param text {String} Texto del option a seleccionar
*@deprecated
*@description esta funcion es similar a la funcion :{@link $sv}
*/
function $ss(selectId, text) {
    var lst = $(selectId);
    for (var i = 0; i < lst.options.length; i++) {
        if (lst.options[i].text == text)
            lst.options[i].selected = true;
    }
}

/**
*Retorna  el texto del Option  seleccionado en el momento
*@param selectId {String} ID del elemento Select 
*@returns {String} texto seleccionado
*@description esta es igual a :{@link $stext}
*/
function $st(selectId) {
    if ($(selectId) == null)
        return '';

    var index = $(selectId).selectedIndex;
    if (index < 0)
        return '';

    return $(selectId).options[index].text;
}
/**
*Retorna el indice del Option (Segun el text suministrado a la funcion)
*@param selectId {String} ID del elemento
*@param text {String} Texto a buscar
*@returns {int} indice
*/
function $sit(selectId, text) {
    var lst = $(selectId);
    for (var i = 0; i < lst.options.length; i++) {
        if (lst.options[i].text == text)
            return i;
    }
    return -1
}

/**
*Adjunta un archivo 
*@param cual {String} ID del elemento
*@param fileType {String} Tipo Archivo
*@param maxFiles {int} Numero Maximo de archivos
*@param maxLengthKB {int} Tamaño maximo del archivo
*/
var vModal = null;
function Adjuntar2(cual, fileType, maxFiles, maxLengthKB) {
    var tipo = "";
    var cantidad = "3";
    var max = "1024";
    var cualf = cual;
    var i;
    var fileName = "";
    var fileMD5 = "";
    var mensaje = '';
    var btnf = $("btnf" + cual);

    if (fileType != "" && fileType != null && fileType != undefined)
        tipo = fileType;
    if (maxFiles != "" && maxFiles != null && maxFiles != undefined)
        cantidad = maxFiles;
    if (maxLengthKB != "" && maxLengthKB != null && maxLengthKB != undefined)
        max = maxLengthKB;

    cantidad = cantidad - $("f" + cual).childNodes.length;
    if (cantidad <= 1 && btnf != null)
        btnf.style.display = "none";

    if (window.showModalDialog) {
        var MyArgs = new Array(tipo, cantidad, max, cualf);

        var WinSettings = "center:yes;resizable:no;dialogHeight:400px;dialogWidth:800px"

        MyArgs = window.showModalDialog("../solicitudes/plantillas/upload.aspx?t=" + tipo + "&m=" + max + "&c=" + cantidad + "&f=" + cualf, MyArgs, WinSettings);

        if (MyArgs == null) {
            if (btnf != null) {
                //window.alert("Nothing returned from child. No changes made to input boxes");
                btnf.style.display = "";
            }
        }
        else {
            ponerFile(MyArgs, cantidad, cual, cualf, mensaje);
        }
    } else {
        if (vModal == null) {
            vModal = document.createElement("DIALOG");

            if (vModal.showModal) {
                vModal.addEventListener('close', function () {
                    ponerFile(this.returnValue, cantidad, cual, cualf, mensaje);
                    vModal = null;
                });
            } else {
                vModal = document.createElement("DIV");

                vModal.style.position = 'fixed';
                vModal.style.top = '50%';
                vModal.style.left = '50%';
                vModal.style.transform = 'translate(-50%, -50%)';
                vModal.style.backgroundColor = 'white';
                vModal.style.zIndex = '1000';

                vModal.close = function (rValue) {
                    ponerFile(rValue, cantidad, cual, cualf, mensaje);
                    this.style.display = 'none';
                    vModal = null;
                }
            }
        }

        vModal.innerHTML = '';

        vModal.style.border = (vModal.showModal) ? '1px solid rgba(0, 0, 0, 0.3)' : 'none';
        vModal.style.borderRadius = '6px';
        vModal.style.boxShadow = '0 3px 7px rgba(0, 0, 0, 0.3)';

        var upload = document.createElement("iframe");
        upload.src = "../solicitudes/plantillas/upload.aspx?t=" + tipo + "&m=" + max + "&c=" + cantidad + "&f=" + cualf;
        upload.style.width = '800px';
        upload.style.height = '400px';

        vModal.appendChild(upload);

        try {
            document.documentElement.appendChild(vModal);
        } catch (E) {
            document.body.appendChild(vModal);
        }

        if (vModal.showModal) {
            vModal.showModal();
        }
    }
}

// falta
function ponerFile(MyArgs, cantidad, cual, cualf, mensaje) {
    var btnf = $("btnf" + cual);
    if (typeof MyArgs == 'string') {
        MyArgs = MyArgs.split('¬');
    }
    if ((MyArgs == null || MyArgs[0] == '') && btnf != null) {
        btnf.style.display = "";
    }
    else {
        for (i = 0; i < MyArgs.length; i++) {
            fileName = MyArgs[i].toString().split("&")[0];
            fileMD5 = MyArgs[i].toString().split("&")[1];
            var cant = cantidad + $("f" + cual).childNodes.length;
            if (!existeArchivo(fileMD5)) {
                add_li("f" + cualf, fileName + "&nbsp;&nbsp;<a href=\"javascript:R($" + fileMD5 + "$,$" + "f" + cualf + "$," + cant + ")\">Quitar</a>", fileMD5, fileName);
            } else {
                mensaje += 'El Archivo ' + fileName + ' Ya Existe \n'
                if (btnf != null) 
                    btnf.style.display = "";
            }
        }
        cantidad = cantidad - $("f" + cual).childNodes.length;

        if (cantidad <= 0 && btnf != null) {
            btnf.style.display = "none";
        } else {
            if(typeof(btnf) == undefined && btnf != null)
                btnf.style.display = "";
        }
        if (typeof (postAdjuntar) != 'undefined') {
            postAdjuntar(cual);
        }
        if (mensaje != '') {
            alert(mensaje);
        }
    }
}

//falta
function existeArchivo(md5) {
    var listas = document.getElementsByTagName('ol');
    var nListas = listas.length;
    var existe = false;

    for (var i = 0; i < nListas; i++) {
        var hijas = listas[i].childNodes;
        var nHijas = hijas.length;
        for(var j = 0; j < nHijas; j++){
            if (md5 == hijas[j].id) {
                existe = true;
                j = nHijas;
                i = nListas;
            }
        }
    }
    return existe;
}


/**
*Adjunta un archivo Mercaderistas
*@param cual {String} ID del elemento
*@param fileType {String} Tipo Archivo
*@param maxFiles {int} Numero Maximo de archivos
*@param maxLengthKB {int} Tamaño maximo del archivo
*/
function AdjuntarMer(cual, fileType, maxFiles, maxLengthKB) {
    var tipo = "";
    var cantidad = "3";
    var max = "1024";
    var cualf = cual;
    var i;
    var fileName = "";
    var fileMD5 = "";
    var btnf = $("btnf" + cual);

    if (fileType != "" && fileType != null && fileType != undefined)
        tipo = fileType;
    if (maxFiles != "" && maxFiles != null && maxFiles != undefined)
        cantidad = maxFiles;
    if (maxLengthKB != "" && maxLengthKB != null && maxLengthKB != undefined)
        max = maxLengthKB;

    cantidad = cantidad - $("f" + cual).childNodes.length;
    if (cantidad <= 1 && btnf != null)
        btnf.style.display = "none";

    var MyArgs = new Array(tipo, cantidad, max, cualf);

    var WinSettings = "center:yes;resizable:no;dialogHeight:400px;dialogWidth:800px"
    MyArgs = window.showModalDialog("../../solicitudes/plantillas/upload.aspx?t=" + tipo + "&m=" + max + "&c=" + cantidad + "&f=" + cualf, MyArgs, WinSettings);
    if (MyArgs == null && btnf != null) {
        //window.alert("Nothing returned from child. No changes made to input boxes");
        btnf.style.display = "";
    }
    else {
        for (i = 0; i < MyArgs.length; i++) {
            fileName = MyArgs[i].toString().split("&")[0];
            fileMD5 = MyArgs[i].toString().split("&")[1];
            var cant = cantidad + $("f" + cual).childNodes.length;
            add_li("f" + cualf, fileName + "&nbsp;&nbsp;<a href=\"javascript:R($" + fileMD5 + "$,$" + "f" + cualf + "$," + cant + ")\">Quitar</a>", fileMD5, fileName);
        }
        cantidad = cantidad - $("f" + cual).childNodes.length;

        if (btnf != null) {
            if (cantidad <= 0) {
                btnf.style.display = "none";
            } else {
                btnf.style.display = "";
            }
        }
        
        if (typeof (postAdjuntar) != 'undefined') {
            postAdjuntar(fileName, fileMD5);
        }
    }
}
/*add_li: despues de adjuntar el archivo, se agrega a un control ol*/
/**
*Despues de adjuntar el archivo, se agrega a un control ol  
*@param list {string} id del ol que se le desea asignar el archivo 
*@param text{string} cual archivo 
*@param id {string} id  del archivo 
*@param path {string} link que dara la opcion para remover el archivo 
*@deprecated
*@description esta funcion es utilizada en :{@link Adjuntar}
*/
function add_li(list, text, id, path) {
    var cual = list;
    var list = document.getElementById(list);
    var li = document.createElement("li");
    text = text.replace(/\$/gi, "'");
    li.innerHTML = text;
    li.id = id;
    li.title = path;
    list.appendChild(li);
}

/*R: elimina un archivo file en una etiqueta ol, se usa en el control de adjuntar*/
/**
*Remueve un archivo y restablese el boton de adjuntar   
*@param cual {string} id  archivo a retirar 
*@param lista {string} id del ol que se le desea implementar el cambio 
*@param cuantos {int} cantida de archivos máximos soportados por el file 
*@deprecated
*/
function R(cual, lista,cuantos) {
    var list = $(lista);
    var filename = $(cual).title;
    list.removeChild($(cual));
    var c = cuantos - list.childNodes.length;
    if (c > 0)
        try {
            $("btnf" + lista.replace('f', '')).style.display = "";
        } catch (e) {
            console.log(e);
        }
        
    if (typeof (afterRemove) != 'undefined')
        afterRemove(cual, filename, lista, cuantos);
}

/**
*Cambia el formato predeterminado de un String , por el que se le desee asignar
*@param cadena {String} Recibe los valores que se deseen  ubicar en  la cadena  
*@example  
* var formatCadena = '{0}.{1}:[{3}/{2}] [{4}-{5}]'; 
* var cadenaText = formatCadena.format('A','B','C','D','E','F');
*@returns {String} 
*/
String.prototype.format = function() {
    var txt = this;
    for (var i = 0; i < arguments.length; i++) {
        var exp = new RegExp('\\{' + (i) + '\\}', 'gm');
        txt = txt.replace(exp, arguments[i]);
    }
    return txt;
}
/**
*Cambia el formato predeterminado de un String , por el que se le desee asignar
*@param  arr {Array}Arreglo en el cual vienen los valores a asignar en la cadena segun su formato  
*@returns String  
*@link  @String#format
*/

String.prototype.formatArray = function (arr) {
    var txt = this;
    for (var i = 0; i < arr.length; i++) {
        var exp = new RegExp('\\{' + (i) + '\\}', 'gm');
        txt = txt.replace(exp, arr[i]);
    }
    return txt;
}
/**
*Remueve las tildes en una cadena y cambia a mayusculas los caracteres del String  
*@returns {String} texto en mayusculas y sin tildes 
*/
String.prototype.removeAccentsUpper = function () {
    var txt = this;
    txt = txt.toUpperCase();

    /*txt = txt.replace(new RegExp(/Á/g), 'A');
    txt = txt.replace(new RegExp(/É/g), 'E');
    txt = txt.replace(new RegExp(/Í/g), 'I');
    txt = txt.replace(new RegExp(/Ó/g), 'O');
    txt = txt.replace(new RegExp(/Ú/g), 'U');*/
    txt = txt.replace(new RegExp(/'/g), '');

    return txt;
}
/**
*Remueve las tildes en una cadena ,reemplaza Ñ por N dependiendo del parametro que se le proveea a la funcion
*@param  incEgne {boolean} variable con la cual se define si deja las Ñ o las cambia por N 
*@returns {String}  
*/
String.prototype.removeAccents = function (incEgne) {
    var txt = this;
    txt = txt.replace(/á/g, 'a').replace(/é/g, 'e').replace(/í/g, 'i').replace(/ó/g, 'o').replace(/ú/g, 'u');
    txt = txt.replace(/Á/g, 'A').replace(/É/g, 'E').replace(/Í/g, 'I').replace(/Ó/g, 'O').replace(/Ú/g, 'U');
    if (!(typeof (incEgne) == 'undefined') && incEgne)
        txt = txt.replace(/ñ/g, 'n').replace(/Ñ/g, 'N');
    return txt;
}
/**
*Remueve caracteres no validos en XML 
*@param element {string} a modificar 
*@returns {String} texto 
*/
String.prototype.removeNonXML = function () {
    var txt = this;
    txt = txt.replace(/&/g, 'Y');
    return txt;
}


/**
*Coloca en rojo los caracteres invalidos en una cadena 
*@param text{String} cadena a validar 
*@param reInvalidChars{String} nombre de la expresion regular 
*@param formatInvalid {String} etiqueta html la cual señalara el error
*@example   
*'<font color=red>{0}</font>'
*@returns String 
*/
// /^[a-zA-Zá-úÑñ,\s\-\@\/\=\(\)\$\_\:\+\0x0d\d\t\n\r\f\v ]*$/
function getCharInvalid(text, reInvalidChars, formatInvalid) {
    var result = '';
    for (var i = 0; i < text.length; i++) {
        tChar = text.charAt(i);
        if (reInvalidChars.test(tChar)) {
            tChar = formatInvalid.format(tChar);
        }
        result += tChar;
    }

    return result;
}

/**
*Reemplaza caracteres invalidos por '_'
*@param element {string} id del objeto a validar.
*@param elementMsg {string} mensaje a mostrar.
*@param reTextInvalid {string} nombre de expresion regular
*@deprecated
*@description esta funcion es utlizada en la funcion {@link  prepareAndValidateText}
*/
function replaceTextCharInvalid(element, elementMsg, reTextInvalid) {
    $(element).value = replaceCharInvalid($v(element), reTextInvalid, '_');
    $(elementMsg).innerHTML = '';
}
/**
*Valida cadena para evitar caracteres invalidos(Esta Funcion se simplifica en el metodo validarTextos().  )
*@param element {String} id del objeto a validar.
*@param elementMsg {String} caracteres a cambiar.
*@param reTextInvalid {String} expresion regular
*@param nameReTextInvalid {String} expresion regular
*@link  validarTextos
*@returns {Boolean} 
*@deprecated
*@description esta funcion es utlizada en la funcion {@link  validarTextos}
*/
var valCaracteres = /[^[a-zA-ZñÑ\.\äëïöüÄËÏÖÜ\-áÁéÉíÍóÓúÚ\.\"\¡\!\-\@\*\;\#\%\/\=\(\)\$\?\¿\~\_\:\,\+\{\}\[\]\\\0x0d\d\t\n\r\f\v\s]/g
function prepareAndValidateText(element, elementMsg, reTextInvalid, nameReTextInvalid) {
    //Para que los textareas permitan todos estos caracteres
    if (reTextInvalid.toLocaleString().length < valCaracteres.toLocaleString().length) {
        reTextInvalid = valCaracteres;
        nameReTextInvalid = 'valCaracteres';
    }
    
    $(element).value = $v(element).removeAccentsUpper();

    if ($v(element).match(reTextInvalid)) {
        $(elementMsg).innerHTML = '<br><b>Texto con caracteres invalidos</b><br> '
                            + '[<a href="javascript:replaceTextCharInvalid(\'' + element + '\', \'' + elementMsg + '\',' + nameReTextInvalid + ');void(0);">Remover caracteres erróneos</a>]<br />'
                            + getCharInvalid($v(element), reTextInvalid, '<font color=red>{0}</font>');
        return false;
    }
    return true;
}
/**
*Ubica en un numero el caracter  de  pesos , miles 
*@param num {int} numero a utilizar 
*@link formatMoney ---- formatCurrency3 --- formatCurrency4
*@returns {String} Numero con sus respectivos caracteres 
*@link pendiente
*/

function formatCurrency2(num) {
    num = num.toString().replace(/\$|\./g, '');
    if (isNaN(num))
        num = "0";
    sign = (num == (num = Math.abs(num)));
    num = Math.floor(num * 100 + 0.50000000001);
    cents = num % 100;
    num = Math.floor(num / 100).toString();
    if (cents < 10)
        cents = "0" + cents;
    for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++)
        num = num.substring(0, num.length - (4 * i + 3)) + '.' +
    num.substring(num.length - (4 * i + 3));
    return (((sign) ? '$' : '-') + num);
}
/**
*Ubica en  un  numero el caracter   miles 
*@param num {int} numero a utilizar 
*@link  @formatMoney
*@returns {String} Numero con sus respectivos signos 
*/
function formatCurrency3(num) {
    num = num.toString().replace(/\$|\./g, '');
    if (isNaN(num))
        num = "0";
    sign = (num == (num = Math.abs(num)));
    num = Math.floor(num * 100 + 0.50000000001);
    cents = num % 100;
    num = Math.floor(num / 100).toString();
    if (cents < 10)
        cents = "0" + cents;
    for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++)
        num = num.substring(0, num.length - (4 * i + 3)) + num.substring(num.length - (4 * i + 3));
    return (((sign) ? '' : '-') + num);
}
/**
*Ubica en eun numero el caracter  miles y decimales 
*@param num {int} numero a utilizar 
*@link  @formatMoney
*@returns {String} Numero con sus respectivos signos 
*/
function formatCurrency4(num) {
    setCharDecimalSystem();
    num = num.toString().replace(/\$|\charDecimalSystem/g, '');
    if (isNaN(num)) num = '0';
    sign = (num == (num = Math.abs(num)));
    num = Math.floor(num * 100 + 0.50000000001);
    cents = num % 100;
    num = Math.floor(num / 100).toString();
    if (cents < 10) cents = '0' + cents;
    for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++)
        num = num.substring(0, num.length - (4 * i + 3)) + charMilesSystem + num.substring(num.length - (4 * i + 3));
    return (((sign) ? '' : '-') + '' + num + charDecimalSystem + cents);
}

/**
*General -Da Validacion a un campo  segun la expresion regular (keyRE) que se le suministre a la funcion 
*@param event {event} Evento que se ejecuto
*@param keyRE {String}Expresion regular 
*@returns {Boolean} 
*/
function validVal(event, keyRE) {
    if (String.fromCharCode(((navigator.appVersion.indexOf('MSIE') != (-1)) ? event.keyCode : event.charCode)).search(keyRE) != (-1)
		|| (navigator.appVersion.indexOf('MSIE') == (-1)
			&& (event.keyCode.toString().search(/^(8|9|13|45|46|35|36|37|39)$/) != (-1)
				|| event.ctrlKey || event.metaKey))) {
        return true;
    } else {
        return false;
    }
}
/**
*Esta funcion es utilizada en formatMoney 
*@link  formatMoney   
*/
function isThousands(position) {
    if (Math.floor(position / 3) * 3 == position) return true;
    return false;
};

/**
*Ubica los signos de miles  en el numero que se le suministre 
*@param  theNumber {int} numero  a utilizar 
*@param  theCurrency {string}tipo de moneda 
*@param  theThousands {string}separador de miles 
*@param  theDecimal {string}separador de decimales
*@returns numero con respectivos  signos   
*/
//http://bytes.com/topic/javascript/answers/145113-formatting-number-thousands-separator
function formatMoney(theNumber, theCurrency, theThousands, theDecimal, numberDecimal) {
    var numDecimal = 2;
    if (numberDecimal != undefined && numberDecimal != null) {
        numDecimal = numberDecimal;
    }
    
    var theDecimalDigits = '';
    if (theDecimal != undefined) {
        theDecimalDigits = Math.round((theNumber * Math.pow(10, numDecimal)) - (Math.floor(theNumber) * Math.pow(10, numDecimal)));
    }

    if (theDecimalDigits == 0) {
        theDecimalDigits = Array(numDecimal + 1).join('0');
    }
    /*
    if (theDecimalDigits <= 9)
        theDecimalDigits = '0' + theDecimalDigits;

    theDecimalDigits = '' + (theDecimalDigits + '0').substring(0, numDecimal);
    */
    theNumber = '' + Math.floor(theNumber);

    var theOutput = theCurrency;

    for (x = 0; x < theNumber.length; x++) {
        theOutput += theNumber.substring(x, x + 1);
        if (isThousands(theNumber.length - x - 1) && (theNumber.length - x - 1 != 0)) {
            theOutput += theThousands;
        };
    };

    if (theDecimal != undefined) {
        theOutput += theDecimal + theDecimalDigits;
    }

    return theOutput;
}


/*getFormData: convierte el formulario en un array*/
/**
*Convirte el formulario en un array( deshuso se recomienda ver el metodo getFormDataXML())
el evento no se produsca.
*@param  arrData{} 
*@param  excElemUser{} 
*@param  excludeEmpty{} 
*@param  selectsText{string} cadena de ID de los elementos u objetos que no deben ser guardados. 
*@link getFormDataXML.
*@returns {Array} datos del formulario
*/
function getFormData(arrData, excElemUser, excludeEmpty, selectsText, saveNameUpper) {
    var excElem = ',CBHELPFOCUS,SOL_ID,SUBMIT,SUBMIT1,';

    if (saveNameUpper == undefined || saveNameUpper == null)
        saveNameUpper = true;

    if (excElemUser != undefined && excElemUser != null && excElemUser != '')
        excElem += excElemUser + ',';

    if (excludeEmpty == undefined || excludeEmpty == null)
        excludeEmpty = false;

    if (selectsText != undefined && selectsText != null && selectsText != '')
        selectsText = ',' + selectsText + ',';
    else
        selectsText = ',,';

    var texts = '';
    var checkboxs = '';
    var radios = '';
    var selects = '';
    var files = '';

    var items = document.getElementsByTagName('input');
    for (var i = 0; i < items.length; i++) {
        var id = items[i].getAttribute('id');
        var name = items[i].getAttribute('name').toUpperCase();

        if (id == null)
            continue;

        var idU = id.toUpperCase();


        if (excElem.indexOf(',' + idU + ',') >= 0)
            continue;
        
        if (idU.substring(0, 3) == 'SCW')
            continue;

        var value = items[i].value;
        value = getValueValid(value);

        if (excludeEmpty && value == '')
            continue;


        var preffix = idU.substring(0, 1);

        if (preffix == 'T') {
            //if(value!='')
            texts += ((saveNameUpper)? idU : id) + ':' + value + '¬';
        }
        else if (preffix == 'S') {
            //if(value!='')
            selects += ((saveNameUpper) ? idU : id) + ':' + value + '¬';
        }
        else if (preffix == 'C') {
            if ($(id).checked)
                checkboxs += ((saveNameUpper) ? idU : id) + ':' + value + '¬';

        }
        else if (preffix == 'R') {
            if ($(id).checked) {
                var iunsc = idU.indexOf('_');
                /*
                if (iunsc >= 0)
                    radios += ((saveNameUpper) ? idU : id).substring(0, iunsc) + ':' + value + '¬';
                else
                    radios += ((saveNameUpper) ? idU : id).substring(0, 2) + ':' + value + '¬';
                */
                radios += name + ':' + value + '¬';
            }
        }
    }

    var items = document.getElementsByTagName('select');
    for (var i = 0; i < items.length; i++) {
        var id = items[i].getAttribute('id');

        if (id == null)
            continue;

        var idU = id.toUpperCase();

        if (excElem.indexOf(',' + idU + ',') >= 0)
            continue;

        if (idU.substring(0, 3) == 'SCW')
            continue;

        var preffix = idU.substring(0, 1);
        if (preffix == 'S') {
            value = $(id).value;
            value = getValueValid(value);

            if (excludeEmpty && value == '')
                continue;

            if (selectsText.indexOf(',' + idU + ',') >= 0) {
                value = $(id).options[$(id).selectedIndex].text;
                value = getValueValid(value);

                selects += ((saveNameUpper) ? idU : id) + ':' + value + '¬';
            }
            else
                selects += ((saveNameUpper) ? idU : id) + ':' + value + '¬';

        } else if (preffix == 'T') {
            value = $(id).value;
            value = getValueValid(value);

            texts += ((saveNameUpper) ? idU : id) + ':' + value + '¬';
        }
    }

    var items = document.getElementsByTagName('textarea');
    for (var i = 0; i < items.length; i++) {
        var id = items[i].getAttribute('id');

        if (id == null)
            continue;

        var idU = id.toUpperCase();

        if (excElem.indexOf(',' + idU + ',') >= 0)
            continue;

        if (idU.substring(0, 3) == 'SCW')
            continue;

        var value = items[i].value;
        value = getValueValid(value);

        if (excludeEmpty && value == '')
            continue;

        var preffix = idU.substring(0, 1);

        if (preffix == 'T') {
            texts += ((saveNameUpper) ? idU : id) + ':' + value + '¬';
        }
    }

    var items = document.getElementsByTagName('ol');
    var cantFs = items.length;
    for (var i = 0; i < cantFs; i++) {
        var id = items[i].getAttribute('id');
        if (id === 'f100') {
            continue;            
        }
        if (id == null)
            continue;

        var idU = id.toUpperCase();

        if (excElem.indexOf(',' + idU + ',') >= 0)
            continue;

        var preffix = idU.substring(0, 1);

        if (preffix == 'F') {
            for (var iOption = 0; iOption < $(id).childNodes.length; iOption++) {
                if ($(id).childNodes[iOption].title == null || $(id).childNodes[iOption].title == undefined)
                    continue;

                files += $(id).childNodes[iOption].title + ':' + $(id).childNodes[iOption].id + ';';
            }
            if (files.length >= 1 && files.substring(files.length - 1, files.length) == ';') {
                files = files.substring(0, files.length - 1);
            }
            files += '¬';
        }
    }

    var agente = ($('q') == null) ? 'Agente que atiende' : $('q').value;
    texts += 'TA:' + agente + '¬';

    texts = texts.substring(0, texts.length - 1);
    checkboxs = checkboxs.substring(0, checkboxs.length - 1);
    radios = radios.substring(0, radios.length - 1);
    selects = selects.substring(0, selects.length - 1);
    files = files.substring(0, files.length - 1);

    //alert(texts+'\n'+checkboxs+'\n'+radios+'\n'+selects+'\n'+files+'\n');

    arrData[0] = texts;
    arrData[1] = radios;
    arrData[2] = checkboxs;
    arrData[3] = selects;
    arrData[4] = files;
    arrData[5] = ''; //TODO: Tomar la info de las grids
}

//==========================================

/**
*Reemplaza caracteres invalidos  en una cadena por '.'
*@param  text {String} elemento texto  
*@returns {String} texto modificado
*@link replaceCharInvalid.
*/
function getValueValid(text) {
    if (text.indexOf('<![CDATA[') > -1)
        return text;

    var reValueCharInvalid = /[~<>]/g
    var value = replaceCharInvalid(text, reValueCharInvalid, '.');
    //value = value.replace(/[&]/g,'y');

    //reValueCharInvalid = /[:]/g
    //value = replaceCharInvalid(value, reValueCharInvalid, '~');

    return value;
}

/**
*Imprime el resultado de la funcion getFormData
*@param  arrData {Array} 
*@link getFormData 
*/

function printFormData(arrData) {
    if(arrData == undefined)
        arrData = new Array(6);

    getFormData(arrData);

    alert(arrData[0]+'\n'+arrData[1]+'\n'+arrData[2]+'\n'+arrData[3]+'\n'+arrData[4]+'\n');
}
/**
*Muestra/Oculta un objeto. (este  metodo se encuentra en desUso)
*@param elementName {string} id del objeto.
*@param view {bool} tipo de visibilidad(False : Ocultar, True:Mostrar).
*@link  @displayElement 
*/
function visibleElement(element, visible) {
    if (visible)
        element.style.display = 'block';

    else
        element.style.display = 'none';
}
/**
*Muestra/Oculta un objeto.
*@param elementName {string} id del objeto.
*@param view {bool} tipo de visibilidad(False : Ocultar, True:Mostrar).
*/
function displayElement(elementName, view) {
    if (elementName != null && $(elementName) != null)
        $(elementName).style.display = (view ? '' : 'none');
}

/**
*Muesta un elemento determinado tiempo.
*@param element {Object} elemento a mostrar
*@param ms {String} tiempo que se desea mostrar 
*/
function viewElementTime(element, ms) {
    displayElement(element, true);
    var clear = setTimeout('displayElement("' + element + '", false);', ms);
}

//Funcion usada para llenar un DropDownList
/**
*Llena un DropDownList apartir de una DataTable
*@param control {Object} elemento DropDownList
*@param table {Object} DataTable
*@param selected {}
*@Link aclarar .
*/
function setDropDownList(control, table, selected) {
    var row;
    var option = null;
    var optGroup = null;
    var i;
    for (i = 0; i < table.Rows.length; i++) {
        row = table.Rows[i];
        if (row.type == "header") {
            if (optGroup != null)
                control.appendChild(optGroup);
            optGroup = document.createElement("c");
            optGroup.label = row.nombre;
        }
        else {
            option = document.createElement("option");
            option.value = row.id;
            option.innerHTML = row.nombre;
            if (optGroup == null)
                control.appendChild(option);
            else
                optGroup.appendChild(option);
        }
    }
    if (optGroup != null)
        control.appendChild(optGroup);
    if (selected != null && selected != undefined && selected != "")
        control.value = selected;
}

/**
*Función usada para llenar un DropDownList a partir de un archivo xml
*@param control {Object} elemento DropDownList
*@param xmlFile {Object} archivo XML
*@param selected {}
*@Link aclarar .
*/
function setDropDownListXML(control, xmlFile, selected) {
    ajax_plantillas.getDropDownList(xmlFile, function (data) { CBsetDropDownListXML(data, control, selected) });
}
/**
*@Link aclarar .
*/
function CBsetDropDownListXML(data, control, selected) {
    if (data.error == null)
        setDropDownList(control, data.value, selected);

}

/**
*Agrega Option a un Select apartir de un DataTable
*@param lst {Object} elemento Select
*@param data {Object} DataTable
*@param fieldId {String} Id 
*@param fields {String} Id y nombre del Option separados por comas
*@param formatOption {String} formato de como se ban a ubicar los datos dentro del Option
*@example 
* bindSelect($('selectId'), dt.Rows, 'codigo', 'codigo,texto', '{0} - {1}');
*@Link bindSelectArray
*/
function bindSelect(lst, data, fieldId, fields, formatOption) {
    var arrFields = fields.split(',');
    for (var iOption = 0; iOption < data.length; iOption++) {
        var arrFieldValue = [];
        for (var iField = 0; iField < arrFields.length; iField++) {
            arrFieldValue.push(data[iOption][arrFields[iField]]);
        }
        var txtOption = formatOption.formatArray(arrFieldValue);
        if (txtOption.split(' - ').length > 1) {
            if (txtOption.split(' - ')[0].toUpperCase() == txtOption.split(' - ')[1].toUpperCase()) {
                txtOption = txtOption.split(' - ')[0];
            }
        }
        
        lst.options[lst.length] = new Option(txtOption, data[iOption][fieldId]);
    }
}
/**
*Agrega una cantidad especifica de Option a un Select
*@param lst  {String}  elemento Select .
*@param options  {Array}  conjunto de Option que se ban a agregar 
*@Link bindSelect
*/
function bindSelectArray(lst, options) {
    for (var i = 0; i < options.length; i += 2)
        lst.options[lst.length] = new Option(options[i + 1], options[i]);
}
/**
*Mostrar  y ocultar un determinado Elemento 
*@param forml      		{String}  elemento a mostrar .
*@param img     		{string}  debe ser el elemento img al cual se le cambia la imagen a mostrar 
*/
function formularioDesplegable(forml, img) {
    if (forml.style.display == "none") {
        forml.style.display = "block";
        img.src = "../images/up.png";
        img.alt = "Ocultar";
    } else {
        forml.style.display = "none";
        img.src = "../images/down.png";
        img.alt = "Mostrar";
    }

}
/**
*Cambia la visibilidad de un Objeto.
*@param element {Object} Elemento al cual se le cambiara la visibilidad.
*/
function changeDisplay(element) {
    if (element == null) {
        return;
    }

    element.style.display = (element.style.display == '') ? 'none' : '';
}

/**
*Cambia la visibilidad de varios objetos .
*@param elements {Object} Objetos a los cuales se les cambiara la visibilidad. 
*@deprecated
*@description es similar a :  {@link changeDisplay}

*/
function changeDisplayElements(elements) {
    var arrElement = elements.split(',');
    for (var i = 0; i < arrElement.length; i++) {
        changeDisplay($(arrElement[i]));
    }
}
/**
*Muestra/Oculta multiples Objetos
*@param visible {bool} Tipo de Visibilidad a generar(False : Ocultar, True:Mostrar).
*@param elements {string} Cadena de id de los Objetos. deben estar separados por ','
*/
function setDisplayElements(visible, elements) {
    var arrElement = elements.split(',');
    for (var i = 0; i < arrElement.length; i++) {
        displayElement(arrElement[i], visible);
    }
}
/**
*Retorna una lista  que contiene varios elementos a los cuales seles
   concatena  un indice y un separador  
*@param preffix {String} prefijo a utilizar
*@param separator {String} el separador sobre los prefijos
*@param start {int} desde que indice se desea empezar
*@param finish {int} hasta donde se desea aumentar el indice 
*@return {String} Cadena con sufijos separados por comas
*@example : 
* preffix = 'tr'
* separator = ','
* start = 1 ;
* finish = 3
* resultado = 'tr1,tr2,tr3'
*/
function getList(preffix, separator, start, finish) {
    var list = '';
    for (var i = start; i <= finish; i++) {
        list += preffix + i;
        if (i < finish) list += separator;
    }
    return list;
}


/**
*Redondea un decimal a un numero entero.
*@param num {int} numero a redondear.
*@param dec {} exponente
*/
function roundNumber(num, dec) {
    var result = Math.round(num * Math.pow(10, dec)) / Math.pow(10, dec);
    return result;
}
//---                   Fin Funciones Generales                 ---//

/**
*Indica Si el formulario cargado es un formulario de respuesta, verifica el Tag con id frmRes, el valor debe ser S
*@returns {Boolean} true = existe , false = no existe 
*/ 

function isFormResponse() {
    if ($('frmRes') != null && $('frmRes').value == 'S') {
        return true;
    }
    return false;
}

/**
*setea la configuracion de visibilidad de las columnas de una grid.
*@param grid {Object} Grid a configurar.
*@param cols {string} indices de las columnas a configurar. deben estar separados por ','
*@param hidden {bool} tipo de visibilidad a generar. False o True.
*/
function setColumnsHidden(grid, cols, hidden) {
    var arrCol = cols.split(',');
    for (var i = 0; i < arrCol.length; i++) {
        grid.setColumnHidden(arrCol[i], hidden);
    }
}
/**
*Saber si el contenido  es numerico.
*@param input {String} valor que se desea verificar.
*@returns {Boolean} 
*/
function isNumeric(input) {
    return (input - 0) == input && input.length > 0;
}
/**
*@Link aclarar .
*/
function setDropDownList2(element, rows, fieldValue, fieldText, valueSelected) {
    var selLength = element.options.length;
    for (var i = 0; i < rows.length; i++) {
        var selected = ((rows[i][fieldValue])+'' == valueSelected);
        element.options[selLength + i] = new Option(rows[i][fieldText], rows[i][fieldValue], false, selected);
    }
}
/**
*Limpia los valores de multiples elementos .
*@param elements {string} cadena con los id de los elementos a limpiar , separados por ','
*/
function clearValue(elements) {
    var arrElement = elements.split(',');
    for (var i = 0; i < arrElement.length; i++) {
        $(arrElement[i]).value = '';
    }
}

/**
*Deschequea todos los radios y los checkbox
*@param elements {}
*/
function uncheckedElements(elements) {
    var items = document.getElementsByTagName('input');
    for (var i = 0; i < items.length; i++) {
        var type = items[i].getAttribute('type');
        if (type == 'checkbox' || type == 'radio') {
            items[i].checked = false;
        }
    }
}

/**
*Deja seleccionado el primer valor del Select
*@param elements {}
*/
function unselectedElements(elements) {
    var items = document.getElementsByTagName('select');
    for (var i = 0; i < items.length; i++) {
        items[i].selectedIndex = 0;
    }
}
/**
*@Link aclarar .
*/
function loadTemplateValues(values) {
    for (var iType = 0; iType < 4; iType++) {
        if (values[iType] == null)
            continue;

        var items = values[iType].split('¬');
        for (var i = 0; i < items.length; i++) {
            var item = items[i].split(':');

            if (iType == 0 || iType == 2 || iType == 3)
                if ($(item[0]) == null)
                    continue;

            if (iType == 1)
                if ($n(item[0]) == null)
                    continue;

            var value = item[1];
            value = replaceCharInvalid(value, /[~]/g, ':');

            switch (iType) {
                case 0:
                    $(item[0]).value = value;
                    break;
                case 3:
                    $(item[0]).value = value;
                    break;
                case 1:
                    $svr(item[0], value);
                    break;
                case 2:
                    if ($v(item[0]) == value)
                        $(item[0]).checked = true;
                    break;
            }
        }
    }
}
/**
*Devuelve el valor dentro de una serializacion  segun el key suministrado en la funcion
*@param values {String} Serializacion a evaluar 
*@param key {String} llave con la cual se accede al valor de la serializacion
*@returns {} valor 
*@example : 
* values = 't1:123¬t2:456¬t3:789';
* key = t1 ;
* retorna = 123
*/
function getFormDataValue(values, key) {
    var idx = values.indexOf(key);
    if (idx < 0)
        return '';

    idx = values.indexOf(':', idx);
    var idx2 = values.indexOf('¬', idx);

    if (idx2 < 0)
        return values.substring(idx + 1);

    return values.substring(idx + 1, idx2);
}
/**
*Reemplaza  caracteres invalidos por el caracter que se suministre en la funcion.
*@param text {Object} elemento texto
*@param reInvalidChars {String} expresion regular
*@param charNew {String} caracter por el cual se reemplazaran los caracteres invalidos
*@returns {String} texto modificado
*/
// /[^a-zA-Zá-úÑñ,\s\.\-\@\/\=\(\)\$\_\+\0x0d\d\t\n\r\f\v ]/g
function replaceCharInvalid(text, reInvalidChars, charNew) {
    return text.replace(reInvalidChars, charNew);
}
/**
*Clona en una columna  de un agrid.
*@param grid {Object} objeto dhtmlXGridFromTable 
*@param col {Int} indice de la columna 
*@param row {Int} indice de la fila 
*@param isText {Boolean} *true = toma el innerHTML  *false = toma el getValue
*/
function clonarColumna(grid, col, row, isText) {
    var clonValue = '';
    if (isText) {
        clonValue = grid.cells2(row, col).cell.innerHTML;
    }
    else {
        clonValue = grid.cells2(row, col).getValue();
    }

    grid.forEachRow(function (id) {
        var value = '';
        if (isText) {
            value = grid.cells(id, col).cell.innerHTML;
        }
        else {
            value = grid.cells(id, col).getValue();
        }
        if (value.trim() == '' || value == '&nbsp;') {
            if (isText) {
                grid.cells(id, col).cell.innerHTML = clonValue;
            }
            else {
                grid.cells(id, col).setValue(clonValue);
            }
        }
    });
}

//------Inicio Manejo de fuentes -----------------------------------

/**
*Cambia de forma dinamica el estilo de una clase 
*@param theClass {String} nombre del atributo Class
*@param element {String} elemento css 
*@param value {String} valor 
*/
function changecss(theClass, element, value) {
    //Last Updated on June 23, 2009
    //documentation for this script at
    //http://www.shawnolson.net/a/503/altering-css-class-attributes-with-javascript.html
    var cssRules;

    var added = false;
    for (var S = 0; S < document.styleSheets.length; S++) {

        if (document.styleSheets[S]['rules']) {
            cssRules = 'rules';
        } else if (document.styleSheets[S]['cssRules']) {
            cssRules = 'cssRules';
        } else {
            //no rules found... browser unknown
        }

        for (var R = 0; R < document.styleSheets[S][cssRules].length; R++) {
            if (document.styleSheets[S][cssRules][R].selectorText == theClass) {
                if (document.styleSheets[S][cssRules][R].style[element]) {
                    document.styleSheets[S][cssRules][R].style[element] = value;
                    added = true;
                    break;
                }
            }
        }
        if (!added) {
            if (document.styleSheets[S].insertRule) {
                document.styleSheets[S].insertRule(theClass + ' { ' + element + ': ' + value + '; }', document.styleSheets[S][cssRules].length);
            } else if (document.styleSheets[S].addRule) {
                document.styleSheets[S].addRule(theClass, element + ': ' + value + ';');
            }
        }
    }
}
/**
*Encuentra un Class css que se en cuentra dentro de un archivo  exterior de estilo  y le asigna un estilo  
*@param theClass {String} nombre del atributo Class que se deseea buscar 
*@param element {String} estilo que se desea agregar 
*@param  {String} valor del estilo 
*@deprecated
*@description esta funcion se utiliza en :{@link Aumentar_Fuente}
*/

function valorcss(theClass, element) {
    var cssRules;

    var added = false;
    for (var S = 0; S < document.styleSheets.length; S++) {

        if (document.styleSheets[S]['rules']) {
            cssRules = 'rules';
        } else if (document.styleSheets[S]['cssRules']) {
            cssRules = 'cssRules';
        } else {
            //no rules found... browser unknown
        }

        for (var R = 0; R < document.styleSheets[S][cssRules].length; R++) {
            if (document.styleSheets[S][cssRules][R].selectorText == theClass) {
                if (document.styleSheets[S][cssRules][R].style[element]) {
                    return document.styleSheets[S][cssRules][R].style[element]; //= value;
                    added = true;
                    break;
                }
            }
        }
    }
}
/**
*Asigna el ancho a las columnas dentro de un a grid
*@param grid {Object} objeto dhtmlXGridFromTable grid a la cual pertenecen las columnas  
*@param colWidth {String } conjunto de anchos de las columnas  separados por comas  
*/
function setGridColWidth(grid, colWidth) {
    var arrColWidth = colWidth.split(',');
    for (var i = 0; i < arrColWidth.length; i++) {
        grid.setColWidth(i, parseInt(arrColWidth[i]));
    }
}

/**
* General -Alinea el texto dentro de una fila en una tabla  
*@param tabla {String} Id de la tabla  
*@param col_no {String } indice de la celda 
*@param align {String} como se desea alinear ('left','center','right')
*/
function setTableColAlign(tabla, col_no, align) {
    var tbl = $(tabla);
    var rows = tbl.getElementsByTagName('tr');

    for (var row = 1; row < rows.length; row++) {
        var cels = rows[row].getElementsByTagName('td')
        cels[col_no].style.textAlign = align;

    }
}
/**
*Muestra una ventana emergente con el Buscador de usuarios Activos
*@param donde {} 
*/
function Ver_Libreta(donde) {
    var MyArgs = new Array('', '');
    var WinSettings = "center:yes;resizable:no;dialogHeight:500px;dialogWidth:550px"
    MyArgs = window.showModalDialog("libreta.aspx", MyArgs, WinSettings);
    if (MyArgs !== null) {
        for (var i = 0; i < MyArgs.length; i++) {
            $(donde).options[$(donde).options.length] = new Option(MyArgs[i], MyArgs[i]);
        }
    }
}
/**
*Elimina los correos dentro de una lista 
*@param element {String} Id de la lista  
*/
function Eliminar_Correo(element) {
    for (var i = 0; i < $(element).length; i++) {
        if ($(element).item(i).selected) {
            $(element).remove(i);
        }
    }
}
/**
*Devuelde un dato  que viene en el URL  
*@param ji {String} Url 
*@Retuns {String} 
*@link getQueryStringArray
*/
function querySt(ji) {
    hu = window.location.search.substring(1);
    gy = hu.split("&");
    for (i = 0; i < gy.length; i++) {
        ft = gy[i].split("=");
        if (ft[0] == ji) {
            return ft[1];
        }
    }
}
/**
*Devuelde los datos que viene en el URL  
*@Retuns {Array} Conjunto de datos 
*/
function getQueryStringArray() {
    var qs = new Array()
    var hu = window.location.search.substring(1);
    hu = decodeURI(hu);
    gy = hu.split('&');
    for (i = 0; i < gy.length; i++) {
        ft = gy[i].split('=');
        qs[ft[0]] = ft[1];
    }
    return qs;
}
/**
*Combierte una cadena que viene en formato(año/mes/dia) en Date   
*@param sdate {String} String con fecha 
*@returns {Date} fecha 
*/

function getJSDate(sdate) {
    var arrdate = sdate.split('/');

    if (arrdate[0].substr(0, 1) == '0') arrdate[0] = arrdate[0].substr(1, 1);
    if (arrdate[1].substr(0, 1) == '0') arrdate[1] = arrdate[1].substr(1, 1);
    
    //var date = Date(parseInt(arrdate[2]), parseInt(arrdate[1]) - 1, parseInt(arrdate[0]));
    var date = new Date();
    date.setFullYear(parseInt(arrdate[2]), parseInt(arrdate[1]) - 1, parseInt(arrdate[0]));

    return date;
}
/**
*Retorna los dias que hay de diferencia entre dos fechas
*@Returns {Date}
*/
//http://www.coderanch.com/t/116818/HTML-JavaScript/Calculate-Number-Days-Between-Two
Date.prototype.DaysBetween = function(){  
    var intMilDay = 24 * 60 * 60 * 1000;  
    var intMilDif = arguments[0] - this;  
    var intDays = Math.floor(intMilDif/intMilDay);  
    return intDays;
}
/**
*Retorna los meses que hay de diferencia entre dos fechas
*@Returns {Date}
*/
Date.prototype.MonthsBetween = function () {
    var date1, date2, negPos;
    if (arguments[0] > this) {
        date1 = this;
        date2 = arguments[0];
        negPos = 1;
    }
    else {
        date2 = this;
        date1 = arguments[0];
        negPos = -1;
    }

    if (date1.getFullYear() == date2.getFullYear()) {
        return negPos * (date2.getMonth() - date1.getMonth());
    }
    else {
        var mT = 11 - date1.getMonth();
        mT += date2.getMonth() + 1;
        mT += (date2.getFullYear() - date1.getFullYear() - 1) * 12;
        return negPos * mT;
    }
}
/**
*Agrega  y selecciona un Option en un Select 
*@param sel {object} elemento Select
*@param value {String} value del Option
*@param text {String}  texto del Option 
*@param seleccionar {Boleano} Indica si se desea que se seleccione
*/
function addOptionSelect(sel, value, text, seleccionar) {
    sel.options[sel.options.length] = new Option(text, value);

    if(seleccionar != undefined && seleccionar != null)
        sel.options[sel.options.length - 1].selected = seleccionar;
    else
        sel.options[sel.options.length - 1].selected = true;
}
/**
*Agrega options a Select clasificandolos por Option Grup	(se recomienda mirar bindSelectGroup())
*@param lst      		{Object} Select a  poblar.
*@param data     		{DataTable} datos con los cuales de llenara el Select. deben estar ordenados por Option Grups
*@param fieldId  		{string}  valor que se guardar en el atributo ID de los options
*@param fields   		{string}  Valores que se visulizaran en el option, debe estar separados por ","
*@param formatOption	{string}  Orden en el cual se ejecutara la funcion format
*@param opt	{string}  Nombre de Grupo por el cual seran clasificados.
*@deprecated
*@description esta es Similar a :{@link bindSelectGroup}
*/
function bindSelectOpt(lst, data, fieldId, fields, formatOption, opt) {
    var arrFields = fields.split(',');

    optGroup = document.createElement("optgroup");
    optGroup.label = opt;

    for (var iOption = 0; iOption < data.length; iOption++) {
        var arrFieldValue = [];
        for (var iField = 0; iField < arrFields.length; iField++) {
            arrFieldValue.push(data[iOption][arrFields[iField]]);
        }
        var txtOption = formatOption.formatArray(arrFieldValue);

        option = document.createElement("option");
        option.value = data[iOption][fieldId];
        option.innerHTML = txtOption;

        optGroup.appendChild(option);

        lst.appendChild(optGroup);
    }
}
/**
*Reemplaza un fragmento de la cadena  
*@param stringToFind {String} fragmento a reemplazar
*@param stringToReplace {String} fragmento que reemplazara a el fragmento anterior
*@param text {String}  texto modificado 
*/
//http://codes.codedigest.com/CodeDigest/75-String-ReplaceAll-function-in-JavaScript.aspx
String.prototype.ReplaceAll = function (stringToFind, stringToReplace) {
    var temp = this;
    var index = temp.indexOf(stringToFind);
    while (index != -1) {
        temp = temp.replace(stringToFind, stringToReplace);
        index = temp.indexOf(stringToFind);
    }
    return temp;
}

/**
* Extrae los valores de los controles del formulario y los devuelve en un arreglo con estructura XML, 
separando los textos, radios, selects, chechbox y files, los campos deben tener un id específico por tipo
para que sean tenídos en cuenta a la hora de generar el XML.
* @param arrData 	   {string}
* @param excElemUser   {string} ID de la solicitud.
* @param excElemUser   {string}
* @param excludeEmpty  {string}
* @param selectsText   {string} id de los objetros que no se deben guardar. deben estar separados por ','
* @param saveNameUpper {string} 
*@returns {Array} arreglo con los datos, en la posición 0 los textos, 1 los radios, 2 los checkbox, 3 los selects, 4 los files
*/
function getFormDataXML(arrData, excElemUser, excludeEmpty, selectsText, saveNameUpper, textCDATA) {
    var excElem = ',CBHELPFOCUS,SOL_ID,SUBMIT,SUBMIT1,';

    if (saveNameUpper == undefined || saveNameUpper == null)
        saveNameUpper = true;

    if (excElemUser != undefined && excElemUser != null && excElemUser != '')
        excElem += excElemUser + ',';

    if (excludeEmpty == undefined || excludeEmpty == null)
        excludeEmpty = false;

    if (selectsText != undefined && selectsText != null && selectsText != '')
        selectsText = ',' + selectsText + ',';
    else
        selectsText = ',,';

    if (textCDATA != undefined && textCDATA != null && textCDATA != '')
        textCDATA = ',' + textCDATA + ',';
    else
        textCDATA = ',,';

    var texts = '<T>';
    var checkboxs = '<C>';
    var radios = '<R>';
    var selects = '<S>';
    var files = '';

    var items = document.getElementsByTagName('input');
    for (var i = 0, len = items.length; i < len; i++) {
        var id = items[i].getAttribute('id');
        var name = items[i].getAttribute('name');
        if (name != null) {
            name = name.toUpperCase();
        }

        if (id == null)
            continue;

        var idU = id.toUpperCase();

        if (excElem.indexOf(',' + idU + ',') >= 0)
            continue;

        if (idU.substring(0, 3) == 'SCW')
            continue;

        var value = items[i].value;
        value = getValueValid(value);

        if (excludeEmpty && value == '')
            continue;


        var preffix = idU.substring(0, 1);

        if (preffix == 'T') {
            if (textCDATA.indexOf(',' + idU + ',') >= 0) {
                value = '<![CDATA[' + value + ']]>';
                texts += '<' + ((saveNameUpper) ? idU : id) + '>' + value + '</' + ((saveNameUpper) ? idU : id) + '>';
            }
            else {
                texts += '<' + ((saveNameUpper) ? idU : id) + '>' + value + '</' + ((saveNameUpper) ? idU : id) + '>';
            }
        }
        else if (preffix == 'S') {
            //if(value!='')
            selects += '<' + ((saveNameUpper) ? idU : id) + '>' + value + '</' + ((saveNameUpper) ? idU : id) + '>';
        }
        else if (preffix == 'C') {
            if (items[i].checked || items[i].hasAttribute('data-switch'))
                checkboxs += '<' + ((saveNameUpper) ? idU : id) + '>' + value + '</' + ((saveNameUpper) ? idU : id) + '>';

        }
        else if (preffix == 'R') {
            if (items[i].checked) {
                radios += '<' + name + '>' + value + '</' + name + '>';
                /*
                var iunsc = idU.indexOf('_');
                if (iunsc >= 0)
                    radios += '<' + ((saveNameUpper) ? idU : id).substring(0, iunsc) + '>' + value + '</' + ((saveNameUpper) ? idU : id).substring(0, iunsc) + '>';
                else
                    radios += '<' + ((saveNameUpper) ? idU : id).substring(0, 2) + '>' + value + '</' + ((saveNameUpper) ? idU : id).substring(0, 2) + '>';
                */
            }
        }
    }

    var items = document.getElementsByTagName('select');
    for (var i = 0, len = items.length; i < len; i++) {
        var id = items[i].getAttribute('id');

        if (id == null)
            continue;

        var idU = id.toUpperCase();

        if (excElem.indexOf(',' + idU + ',') >= 0)
            continue;

        if (idU.substring(0, 3) == 'SCW')
            continue;

        var preffix = idU.substring(0, 1);
        if (preffix == 'S') {
            value = getSelectValue.call(items[i]);

            if (value == '')
                value = getSelectValue2(items[i]);

            value = getValueValid(value);

            if (excludeEmpty && value == '')
                continue;

            if (selectsText.indexOf(',' + idU + ',') >= 0) {
                try{
                    value = items[i].options[items[i].selectedIndex].text;
                    value = getValueValid(value);
                } catch (E) {
                    value = '';
                }

                selects += '<' + ((saveNameUpper) ? idU : id) + '>' + value + '</' + ((saveNameUpper) ? idU : id) + '>';
            }
            else
                selects += '<' + ((saveNameUpper) ? idU : id) + '>' + value + '</' + ((saveNameUpper) ? idU : id) + '>';

        } else if (preffix == 'T') {
            value = items[i].value;
            value = getValueValid(value);

            texts += '<' + ((saveNameUpper) ? idU : id) + '>' + value + '</' + ((saveNameUpper) ? idU : id) + '>';
        }
    }

    var items = document.getElementsByTagName('textarea');
    for (var i = 0, len = items.length; i < len; i++) {
        var id = items[i].getAttribute('id');

        if (id == null)
            continue;

        var idU = id.toUpperCase();

        if (excElem.indexOf(',' + idU + ',') >= 0)
            continue;

        if (idU.substring(0, 3) == 'SCW')
            continue;

        var value = items[i].value;
        value = getValueValid(value);

        if (excludeEmpty && value == '')
            continue;

        var preffix = idU.substring(0, 1);

        if (preffix == 'T') {
            texts += '<' + ((saveNameUpper) ? idU : id) + '>' + value + '</' + ((saveNameUpper) ? idU : id) + '>';
        }
    }

    var items = document.getElementsByTagName('ol');
    var cantFs = items.length;
    var cantEnc = 0 ; 



    for (var i = 1; i <= 50 && cantEnc < cantFs; i++)
    {
        var id = ""; 
        if ($('f' + i) != null)
        {
            id = 'f' + i;
        }
        else if ($('F' + i) != null)
        {
            id = 'F' + i;
        }
        else
       {
           files += '¬';
           continue;
       }

        for (var iOption = 0; iOption < $(id).childNodes.length; iOption++)
        {
            if ($(id).childNodes[iOption].title == null || $(id).childNodes[iOption].title == undefined)
                continue;

            files += $(id).childNodes[iOption].title + ':' + $(id).childNodes[iOption].id + ';';
        }
        if (files.length >= 1 && files.substring(files.length - 1, files.length) == ';') {
            files = files.substring(0, files.length - 1);
        }
        files += '¬';
        cantEnc++;
    }

    var agente = ($('q') == null) ? 'Agente que atiende' : $('q').value;
    texts += '<TA>' + agente + '</TA>';

    texts = texts + '</T>';
    checkboxs =  checkboxs + '</C>';
    radios =  radios + '</R>';
    selects = selects + '</S>';
    files = files.substring(0, files.length - 1);

    //alert(texts+'\n'+checkboxs+'\n'+radios+'\n'+selects+'\n'+files+'\n');

    arrData[0] = texts;
    arrData[1] = radios;
    arrData[2] = checkboxs;
    arrData[3] = selects;
    arrData[4] = files;
    arrData[5] = ''; //TODO: Tomar la info de las grids
}

/////****** limpia todos los radios indicados, deparados por ","*****\\\\\\\\\\*******DFA********
/**
*Limpia todos los radios indicados, separados por ","
*@param radios  {String} conjunto de radios a deschequear
*/
function limpiarRadios(radios) {

    var s = radios.split(",");
    var i = 0;
    while (i < s.length) {
        $("" + s[i]).checked = false;
        i++;
    }
}

/////********  Retorna un arreglo con el navegador utilizado y la version  *****\\\\\\\\\\*******DFA********
/**
*Retorna un arreglo con el navegador utilizado y la version del navegador
*@returns {Array} arreglo con el navegador utilizado
*/
function getNavegadorVersion() {

    var navegador = navigator.appName;
    var version = navigator.appVersion;
    version = version.substring(0, 3);

    return datos = [navegador, version];
}

/* Valida grids, recibe un Array de grids, por cada grid enviada debe haber una caja de texto
con id "_Grrid" + numero empezando en 0 ejm.    id="_Grid0",id="_Grid1"....                             *****\\\\\\\\\\*******DFA********
*/
/**
*Valida las grids que llegan dentro de un parametro a la funcion 
*@param grids {Array}  Array de grids, por cada grid enviada debe haber una caja de texto 
*@returns {String} arreglo con el navegador utilizado
*@example
* con id "_Grrid" + numero empezando en 0 ejm.    id="_Grid0",id="_Grid1"....  
*/ 
function validarGrids(grids) {
    var i = 0;
    while (i < grids.length) {
        var rows =grids[i].getRowsNum();

        if (validateGrid(grids[i]) == 0 && rows > 0) {
            $("_Grid" + i).value = "ok";
        } else {
            $("_Grid" + i).value = "";
        }
        i++;
    }
}



/////********  Recibe un String y lo convierte a Date para su retorno  *****\\\\\\\\\\*******DFA********

/**
*Convierte un string  en formato 'Dia/Mes/Año' en Date 
*@param fecha {String} fecha en formato 'Dia/Mes/Año'
*@returns {Date}   
*/ 
function converStringToDate(fecha) {

    if (fecha == "")
        return '';

    date = new Date();
    fecha = fecha.split('/');
    
    if (fecha[1].length == 2 && fecha[1].substr(0, 1) == '0') {
        fecha[1] = fecha[1].substr(1, 1);
    }

    date.setDate(parseInt(fecha[0]));
    date.setMonth(parseInt(fecha[1]) - 1);
    date.setYear(fecha[2]);

    return date;

}


/**
*Deschequea todos los radios  de un elemento
*@param elemId {String} Name del elemento que contiene los radios
*/ 
function unchecked(elemId) {
    var element = document.getElementsByName(elemId);
    for (var i = 0; i < element.length; i++)
        element[i].checked = false;

    return '';
}
/**
* General- Retorna el formato de fecha necesario para habilitar o deshabilitar fechas en calendario
* @param fechabase	{string} fecha de la cual partira. De enviarse vacio el sistema partira de la fecha actual.
* @param periodo 	{string} tipo de periodo a implemetar 'D': dia, 'M':mes, 'Y': año
* @param offset 	{int}    cantidad de periodos a evaluar
* @param operador	{string} tipo de operacion a realizar '+': la operacion de bloqueo se hara a partir de la fecha base
hacia el futuro acorde al offset enviado. '-': la operacion de bloqueo se hara se hara 
hasta la fechaBase - el valor enviado en el offset.
* @returns {string} Formato Fecha.							 
*/
function FechaDisabled(fechabase, periodo, offset, operador) {
    var fecha;
    if (fechabase == '') {
        var scwDateNow = new Date();
        fechabase = scwDateNow.getDate() + '/' + (scwDateNow.getMonth()+1) + '/' + scwDateNow.getFullYear();
    }
    if (fechabase == 'today') {
        return 'today';
    } else if (periodo == 'D') {
        fecha = fechabase.split('/');
        ann = fecha[2];
        if (operador == '-')
        { fecha[2] = eval(fecha[0]) - offset; }
        else { fecha[2] = eval(fecha[0]) + offset; }
        fecha[0] = ann;
        fecha[1] = eval(fecha[1]) - 1;
        return fecha;
    } else if (periodo == 'M') {
        fecha = fechabase.split('/');
        ann = fecha[2];
        if (operador == '-')
        { fecha[1] = eval(fecha[1]) - 1 - offset; }
        else { fecha[1] = eval(fecha[1]) - 1 + offset; }
        fecha[2] = fecha[0];
        fecha[0] = ann;
        return fecha;
    } else if (periodo == 'Y') {
        fecha = fechabase.split('/');
        if (operador == '-')
        { ann = eval(fecha[2]) - offset; }
        else { ann = eval(fecha[2]) + offset; }
        fecha[2] = fecha[0];
        fecha[0] = ann;
        fecha[1] = eval(fecha[1]) - 1;
        return fecha;
    }
}
/**
* General- Agrega un caracter a la izquierda  n numero de veces veces 
* @param str {string} elemento al cual se le desea agregar el caracter
* @param car {string} caracter a concatenar en el elemento
* @param len {int} cantidad de veces a agregar    
* @returns {string} cadena Modificada							 
*/
function padleft(str, car, len) {
    if (str.length <= len) {
        for (var i = str.length; i <= len; i++) {
            str = car.toString() + str.toString();
        }
    }
    return str;
}


var reTextInvChk = /[^a-zA-ZÑñ,\s\%\.\-\@\/\=\(\)\$\_\+\0x0d\d\t\n\r\f\v]/;
var reTextInvRpl =/[^a-zA-ZÑñ,\s\.\%\-\@\/\=\(\)\$\_\+\0x0d\d\t\n\r\f\v]/g;
var reTextValid = /[a-zA-ZÑñ,\s\.\-\@\/\=\(\)\$\_\+\0x0d\d\t\n\r\f\v]*/g;

/**
*Valida textos de caracteres indeseados  
*@param obj {Array} conjunto de elementos de texto a validar 
*@returns {Boolean}   
*/ 

function validarTextos(obj) {

    var estado = true;
    var s = 0;
    while (s < obj.length) {
        var i = prepareAndValidateText('' + obj[s].id, 'lbl' + obj[s].id + 'inv', reTextInvChk, 'reTextInvRpl');
        if (!i) {
            estado = false;
        }
        s++;
    }
    return estado;
}

/**
*Agrega Options  a un Select  clasificadolos por Option Grup		 
*@param {Object} lst Select a  poblar.
*@param {DataTable} data datos con los cuales se llenara el Select.
deben estar ordenados por Option Grups
*@param {string} fieldId valor que se guardar en el atributo ID de los Options
*@param {string} fields  Valores que se visulizaran en el Option, debe estar separados por ","
*@param {string} formatOption Orden en el cual se ejecutara la funcion format
*@param {string} fieldGroup	 Nombre de Grupo por el cual seran clasificados.
*@deprecated
*@description esta es similar a :{@link bindSelectOpt}
*/
function bindSelectGroup(lst, data, fieldId, fields, formatOption, fieldGroup) {
    var arrFields = fields.split(',');
    var curGroup = '';

    for (var iOption = 0; iOption < data.length; iOption++) {
        if (curGroup != data[iOption][fieldGroup]) {
            curGroup = data[iOption][fieldGroup];
            optGroup = document.createElement("optgroup");
            optGroup.label = curGroup;
        }

        var arrFieldValue = [];
        for (var iField = 0; iField < arrFields.length; iField++) {
            arrFieldValue.push(data[iOption][arrFields[iField]]);
        }

        var txtOption = formatOption.formatArray(arrFieldValue);
        var option = document.createElement("option");
        option.value = data[iOption][fieldId];
        option.innerHTML = txtOption;
        optGroup.appendChild(option);
        lst.appendChild(optGroup); 
    }
}
/**
*Remueve  el numero de nodos de un Select  especificados(options,grupt)
*@param lst {Object} Select a  limpiar.
*@param start {int} indica apartir de que Nodo elimina.p
*/
function clearSelectGroup(lst, start) {
    for (var i = lst.childNodes.length - 1; i > start; i--) {
        lst.removeChild(lst.childNodes[i]);
    }
}

/**
*Cambia el color de un elemento a un color Rojo
*@requires className 'tfvHighlight' 
*@param elemColor {String} Id del elemento 
*@deprecated
*@description esta funcion es usada en  :{@link validarRango}
*/
function colorRojo(elemColor) {
    $(elemColor).className = 'tfvHighlight';
}

/**
*Normaliza el color de un elemento 
*@requires className 'tfvNormal' 
*@param elemColor {String} Id del elemento 
*@deprecated
*@description esta funcion es usada en  :{@link validarRango}
*/
function color(elemColor) {
    $(elemColor).className = 'tfvNormal';
}

/**
*Determina si un valor se encuentra dentro de un rango predeteminado
*@param valor {Int}
*@param min {Int} Rango minimo
*@param max {Int} Rango maximo 
*@param elemColor {String} Id del elemento
*/

function validarRango(valor, min, max, elemColor) {
    var reFloat = /^[\-]?[0-9]+\.?[0-9]*$/;
    if (!reFloat.test(valor)) {
        colorRojo(elemColor);
        return;
    }

    var v = 0;
    v = parseFloat(valor);
    if (v >= min && v <= max) {
        color(elemColor);
    }
    else {
        colorRojo(elemColor);
    }
}
/**
*Cambia el type de un input de text a hidden o viceversa Solo para Firefox
*@param check {Boolean} True = text   False = hidden  
*@param elem {String} Id del elemento Input 
*/
function fromCk(check, elem) {
    if ($ck(check) == true) {
        $(elem).type = 'text';
    }
    else
        if ($ck(check) == false) {
            $(elem).type = 'hidden';
        }
    }
    /**
    *Selecciona el Option de un select que contenga el Value suministrado en la funcion
    *@param selectId {String} ID del elemento Select
    *@param value {String} Value del option a seleccionar
    *@deprecated
    *@description esta funcion es similar a la funcion :{@link $ss}
    */
    function $sv(selectId, value) {
        var lst = $(selectId);
        for (var i = 0; i < lst.options.length; i++) {
            if (lst.options[i].value.toLowerCase() == value.toLowerCase())
                lst.options[i].selected = true;
        }
    }
    /**
    *Limpia los campos ingresados en la funcion
    *@param elements {String} Id de los campos separados por ','
    */
    function setCleanElements(elements) {
        if (elements != null) {                 // && $(elementName) != null)
            var arrElement = elements.split(',');

            for (var i = 0; i < arrElement.length; i++) {
                if ($(arrElement[i]) != null) {
                    $(arrElement[i]).value = "";
                }
            }


        }
    }
    var charDecimalSystem = '.';
    var charMilesSystem = ',';

    /**
    *Designa el separador desimal a utilizar en el proceso ya sea ',' o '.'.
    */
    function setCharDecimalSystem() {
        charDecimalSystem = (eval('0,1') == 0.1) ? ',' : '.';
        charMilesSystem = (charDecimalSystem == '.') ? ',' : '.';

        return charDecimalSystem + ',' + charMilesSystem;
    }
    /**
    *Toma un elemento y le reemplaza el separador de miles por el de decimales
    *@param text {Object} Elemento 
    */

    function adjustDecimalChar(text) {
        return text.replace(charMilesSystem, charDecimalSystem);
    }

    /**
    *Retira los separadores de miles de un valor 
    *@param text {Object} Elemento 
    */
    function removeNonDecimalChar(text) {
        return text.replace(new RegExp((charDecimalSystem == '.') ? ',' : '\.', 'g'), '');
    }


    /**
    *Verifica que un decimal sea valido 
    *@param value {Object} valor del elemento  
    *@returns  null = si no lo es  
    */
    function isDecimalValid(value) {
        var re = new RegExp("^[0-9]*\.?[0-9]*$");
        return value.match(re);
    }

    /**
    *Se verifica si existe un prototype.filter el cual nos permite filtrar un arreglo 
                      si no existe se crea el prototype.filter
    *@param value {Object} valor del elemento 
    *@example 
    *
    *    function sedeseaFiltrar(element, index, array) 
    *    {
    *               return (element >= 10);
    *    }
    *    var filtered  = [12, 5, 8, 130, 44].filter(sedeseaFiltrar);
    *    resultado : 12,130,44 
    *   http://www.tutorialspoint.com/javascript/array_filter.htm
    */
    if (!Array.prototype.filter) {
        Array.prototype.filter = function (fun /*, thisp*/) {
            var len = this.length >>> 0;
            if (typeof fun != "function")
                throw new TypeError();

            var res = [];
            var thisp = arguments[1];
            for (var i = 0; i < len; i++) {
                if (i in this) {
                    var val = this[i]; // in case fun mutates this
                    if (fun.call(thisp, val, i, this))
                        res.push(val);
                }
            }

            return res;
        };
    }


  /**
    *Agrega a la derecha n cantidad de veces un caracter a una cadena 
    *@param padString {String} caracter a Agregar 
    *@param length {int} cantidad de veces a repetirlo
    *@deprecated
    *@description Vease tambien :{@link String#rpad}
    *@returns {String} 
  */
    String.prototype.lpad = function (padString, length) {
        var str = this;
        while (str.length < length)
            str = padString + str;
        return str;
    }

    /**
    *Agrega a la izquierda n cantidad de veces un caracter a una cadena 
    *@param padString {String} caracter a Agregar 
    *@param length {int} cantidad de veces a repetirlo
    *@deprecated
    *@description Vease tambien :{@link String#lpad}
    *@returns {String} 
    */
    String.prototype.rpad = function (padString, length) {
        var str = this;
        while (str.length < length)
            str = str + padString;
        return str;
    }

    /**
    *Remueve los espacios al comienzo y al final de una cadena
    *@example :
    * var cadena =  ' prueba '
    * var cadena2 = cadena.trim();
    * resultado = 'prueba';
    *@deprecated
    *@description Vease tambien las funciones :{@link String#trim}---{@link String#ltrim}----{@link String#rtrim}    
    */
    String.prototype.trim = function ()
           {
       
               return this.replace(/^\s+|\s+$/g, "");
           }

   /**
    *Remueve los espacios al comienzo  de una cadena
    *@example :
    * var cadena =  ' prueba '
    * var cadena2 = cadena.ltrim();
    * resultado = 'prueba ';
    *@deprecated
    *@description Vease tambien las funciones :{@link String#trim}---{@link String#ltrim}----{@link String#rtrim}    
   */
    String.prototype.ltrim = function ()
           {
               return this.replace(/^\s+/, "");
           }
    /**
     *Remueve los espacios al final  de una cadena
     *@example :
     * var cadena =  ' prueba '
     * var cadena2 = cadena.ltrim();
     * resultado = ' prueba';
     *@deprecated
     *@description Vease tambien las funciones :{@link String#trim}---{@link String#ltrim}----{@link String#rtrim}    
    */
    String.prototype.rtrim = function () 
           {
               return this.replace(/\s+$/, "");
           }
   /**
      *Verifica si la cadena comienza por un String especifico especifico
      *@param str {String} String especifico a buscar
      *@returns {Boolean} *true =  si existe  *false = no existe 
      *@deprecated
      *@description Vease tambien las funciones :{@link String#endsWith}
   */
   String.prototype.startsWith = function (str) 
           {
               return (this.match("^" + str) == str);
           }
    /**
       *Verifica si la cadena finaliza por un String especifico especifico
       *@param str {String} String especifico a buscar
       *@returns {Boolean} *true =  si existe  *false = no existe 
       *@deprecated
       *@description Vease tambien las funciones :{@link String#endsWith}
    */
   String.prototype.endsWith = function (str) 
          {
            return (this.match(str + "$") == str);
          }
        /**
        *Oculta una columna de una tabla por su indice 
        *@param tableId {String} Id de la tabla
        *@param col_no {String} Indice de la columna 
        *@param do_show {Boolean} *true = Oculta *false= Muestra 
        */
        function show_hide_column(tableId, col_no, do_show) {

            var stl;
            if (do_show) stl = ''
            else stl = 'none';

            var tbl = document.getElementById(tableId);
            var rows = tbl.getElementsByTagName('tr');

            for (var row = 0; row < rows.length; row++) {
                var cels = rows[row].getElementsByTagName('td');
                if (cels[col_no] != undefined && cels[col_no] != null)
                    cels[col_no].style.display = stl;
            }
        }

        /**
        *Oculta un conjunto de columnas de la grid 
        *@param grid {String} objeto dhtmlXGridFromTable grid 
        *@param colWidth {String} conjunto de indice de columnas separado por ',' 
        */
        function setColWidth(grid, colWidth) {
            var arrColWidth = colWidth.split(',');
            for (var i = 0; i < arrColWidth.length; i++) {
                grid.setColWidth(i, parseInt(arrColWidth[i]));
            }
        }
        
        /**
        *Metodo utilizado en el modificador  FILELIST 
        */
        function showFileDelete(e, controlHTML, PhysicalPath, vPath, list, maxFiles, del) {
            var solId = $v('sol');

            var posx;
            var posy;
            var divInner = "";
            if (navigator.appName == "Netscape") {
                posx = e.pageX;
                posy = e.pageY;
            } else {
                posx = window.event.x + document.body.scrollLeft;
                posy = window.event.y + document.body.scrollTop;
            }
            posx += 'px';
            posy += 'px';
            var divId = 'div' + PhysicalPath;
            if ($(divId) == undefined) {
                var newDiv = document.createElement("div");
                newDiv.id = divId;
                newDiv.name = "del0";
                if (navigator.appName == "Netscape") {
                    newDiv.addEventListener("mouseout", function () { noShowFileDelete(divId, controlHTML) }, false);
                    newDiv.addEventListener("mouseover", function () { onShowFileDelete(divId) }, false);
                }
                else {
                    newDiv.attachEvent('onmouseout', function () { noShowFileDelete(divId, controlHTML) });
                    newDiv.attachEvent('onmouseover', function () { onShowFileDelete(divId) });
                }

                var table = document.createElement("table");
                var tbody = document.createElement("tbody");
                var row = document.createElement("tr");

                if (del) {
                    cell = document.createElement("td");
                    var img = document.createElement('img');
                    img.alt = 'Borrar archivo';
                    img.title = 'Borrar archivo';
                    img.src = '../images/delFile.png';
                    img.style.cursor = 'pointer';
                    if (navigator.appName == "Netscape")
                        img.addEventListener("click", function () { deleteFileFromList(divId, PhysicalPath, list, maxFiles, solId) }, false);
                    else
                        img.attachEvent('onclick', function () { deleteFileFromList(divId, PhysicalPath, list, maxFiles, solId) });
                    cell.appendChild(img);
                    row.appendChild(cell);
                }

                cell = document.createElement("td");
                var img = document.createElement('img');
                img.alt = 'Descargar archivo';
                img.title = 'Descargar archivo';
                img.src = '../images/viewFile.png';
                img.style.cursor = 'pointer';
                if (navigator.appName == "Netscape")
                    img.addEventListener("click", function () { window.open(vPath, '_blank') }, false);
                else
                    img.attachEvent('onclick', function () { window.open(vPath, '_blank') });
                cell.appendChild(img);
                row.appendChild(cell);

                cell = document.createElement("td");
                cell.align = 'right';
                cell.vAlign = 'top';
                var img = document.createElement('img');
                img.alt = 'Cerrar';
                img.title = 'Cerrar';
                img.src = '../images/cancelar.png';
                img.style.cursor = 'pointer';
                if (navigator.appName == "Netscape")
                    img.addEventListener("click", function () { delShowFileDelete(divId, controlHTML, true) }, false);
                else
                    img.attachEvent('onclick', function () { delShowFileDelete(divId, controlHTML, true) });
                cell.appendChild(img);
                row.appendChild(cell);
                tbody.appendChild(row);
                table.appendChild(tbody);
                newDiv.appendChild(table);
                controlHTML.appendChild(newDiv);
            }
        }
        /**
        *Metodo utilizado en el modificador  FILELIST 
        */
        function noShowFileDelete(divId, container) {
            var div = $(divId);
            div.name = "del0";
            setTimeout(function () { delShowFileDelete(divId, container) }, 2000);
        }
        /**
        *Metodo utilizado en el modificador  FILELIST 
        */
        function onShowFileDelete(divId) {
            var div = $(divId);
            div.name = "del1";
        }
        /**
        *Metodo utilizado en el modificador  FILELIST 
        */
        function delShowFileDelete(divId, container, close) {
            var div = $(divId);
            if (div != null) {
                if (div.name == "del0")
                    container.removeChild(div);
                if (close)
                    container.removeChild(div);
            }
        }
        /**
        *Metodo utilizado en el modificador  FILELIST 
        */
        function deleteFileFromList(divId, PhysicalPath, list, maxFiles, solId) {
            if (typeof (preDeleteFileFromList) != 'undefined') {
                var result = preDeleteFileFromList(divId, PhysicalPath, list, maxFiles, solId);
                if (result == false) {
                    return;
                }
            }

            if(solId == null)
                var del = ajax_plantillas.eliminarArchivo(PhysicalPath);
            else
                var del = ajax_plantillas.eliminarArchivo2(PhysicalPath,solId);

            if (del.value == 'OK') {
                var lista = $(list);
                if (navigator.appName == "Netscape")
                    lista.removeChild(document.getElementsByName(PhysicalPath)[0]);
                else {
                    for (var i = 0; i < lista.childNodes.length; i++) {
                        if (lista.childNodes[i].title == PhysicalPath) {
                            lista.removeChild(lista.childNodes[i]);
                            break;
                        }
                    }
                }
                delShowFileDelete(divId, true);
                var c = maxFiles - lista.childNodes.length;
                if (c > 0)
                    $("btn" + list).style.display = "";
            }
            else
                $('ver_error').innerHTML = del.value;

            if (typeof (postDeleteFileFromList) != 'undefined') {
                var result = postDeleteFileFromList(divId, PhysicalPath, list, maxFiles, solId);
            }
        }
        /**
        *Metodo utilizado en el modificador  FILELIST 
        */
        function convNBSPToEmpty(text) {
            if (text == '&nbsp;' || text == null)
                return '';

            return text;
        }

        /**
        *Devuelve los diferentes valores de un arreglo en una columna 
        *@param arr {Array} arreglo a utilizar
        *@param col {int} indice de la columna
        *@returns {Array}
        */
      
        function extractArrColValuesDistinct(arr, col) {
            var hashDistinct = new Array();
            var arrDistinct = new Array();

            for (var iRow = 0; iRow < arr.length; iRow++) {
                var distinct = arr[iRow][col].trim();
                if ((distinct != '') && (hashDistinct[distinct] == null)) {
                    hashDistinct[distinct] = 'X';
                    arrDistinct.push(distinct);
                }
            }
            return arrDistinct;
        }
        /**
        *Devuelve los diferentes valores de un arreglo en una columna 
        *@param arr {Array} arreglo a utilizar
        *@param col {int} indice de la columna
        */


        function FormatTdCurrency(col_no, tabla) {
            var stl;
            var tbl = document.getElementById(tabla);
            var rows = tbl.getElementsByTagName('tr');
            for (var row = 1; row < rows.length; row++) {
                var cels = rows[row].getElementsByTagName('td')
                cels[col_no].innerHTML = (isNumeric(cels[col_no].innerHTML)) ? formatMoney(cels[col_no].innerHTML, '', '.', ',') : cels[col_no].innerHTML;
                cels[col_no].style.textAlign = 'right';
            }
        }
        /**
        * General -Actualiza Archivos
        *@param solId {String} Id de la solicitud
        *@param fOriginal {String} Id del archivo antiguo
        *@param fTemporal {String} Id del del archivo a guardar 
        *@param reemplazar{Boolean}
        
        */
        function actualizarArchivos(solId, fOriginal, fTemporal, reemplazar) {
            var item = document.getElementById(fTemporal);
            var file, files;
            if (item != null || item != undefined) {
                if (item.childNodes.length == 0) {
                    alert("No hay archivos que guaradar");
                } else {
                    var idU = fTemporal.toUpperCase();
                    var preffix = idU.substring(0, 1);
                    if (preffix == 'F') {
                        for (var iOption = 0; iOption < item.childNodes.length; iOption++) {
                            if (item.childNodes[iOption].title == null || item.childNodes[iOption].title == undefined)
                                continue;

                            files += item.childNodes[iOption].title + ':' + item.childNodes[iOption].id + ';';
                        }
                        files = files.substring(0, files.length - 1);
                        files += '¬';
                    }
                    files = files.substring(0, files.length - 1);
                    var data = ajax_mesaayuda_.gestionar.actualizarArchivosSolicitud(solId, fOriginal, files, reemplazar);
                    switch (data.value) {
                        case -1:
                            alert("Error al guardar el arcivo");
                            break;
                        case 0:
                            alert("No se guardo ningun archivo");
                            break;
                        default:
                            while (item.firstChild) {
                                item.removeChild(item.firstChild);
                            }
                            alert("Archivos guardados con exito " + data.value.toString());
                            break;
                    }
                }
            }
        }

        /**
        *Devulve los valores o el html de uno o todos Options de un select
        *@param sel {Object} elemento Select
        *@param isValue {String} Valor que se desea colocar en el select
        *@param all {Boolean} true= para afectar todos los Option
        *@param separador {String} el separador que se ba a usar para la identificacion de los distintos valores
        *@returns {String} con los valores o el html de uno o todos los Option de un Select
         */


        function getSelectValues(sel, isValue, all, separador) {
            var values = '';
            for (var i = 0; i < sel.length; i++) {
                if (all || sel.options[i].selected) {
                    if (isValue)
                        values += sel.options[i].value + separador;
                    else
                        values += sel.options[i].innerHTML + separador;
                }
            }
            return values;
        }

        /**
        *Remueve todos los Options de un select
        *@param sel {Object} elemento Select
        */
        function removeOptionSelected(sel) {
            for (var i = 0; i < sel.length; i++) {
                if (sel.options[i].selected) {
                    sel.removeChild(sel.options[i]);
                }
            }
        }

        /**
        *Cambia los tabs a divs y viceversa, necesita una imagen HTML para ser invocado y dependiendo del estado
        *@param divContainer {Object} elemento Div
        *@param maxWidth {int} ancho maximo
        *@param maxHeight {int} altura maxima 
        *@param divs {Array} arreglo de elementos  div
        *@param tab {Object}
        *@deprecated
        *@description 
        *inicial de los tabs colocar un mensaje en el alt de dicha imagen
        *tabs activos: alt="Vista sencilla"
        *tabs inactivos: alt="Vista mejorada"
        */

        
        function changeTabsView(divContainer, maxWidth, maxHeight, divs, tab) {
            op = $('imgVista').alt;
            //Vista con tabs    
            if (op == 'Vista mejorada') {
                divContainer.style.width = maxWidth;
                divContainer.style.height = maxHeight;
                $('imgVista').src = '../images/vistaActiva.png';
                $('imgVista').alt = 'Vista sencilla';
                tab.setSkin('dhx_skyblue');
                tab.setImagePath("../DHTML/dhtmlxTabbar/codebase/imgs/");
                tab.enableTabCloseButton(false);
                for (x in divs) {
                    tab.addTab(divs[x].id, divs[x].t, divs[x].px);
                    tab.setContent(divs[x].id, x.toString());
                    if (divs[x].a != undefined)
                        if (divs[x].a)
                            tab.setTabActive(divs[x].id);
                }
                tab.showInnerScroll();
                tab.normalize();
            }
            //Vista Divs
            else if (op == 'Vista sencilla') {
                $('imgVista').src = '../images/vistaSencilla.png';
                $('imgVista').alt = 'Vista mejorada';
                divContainer.style.width = '';
                divContainer.style.height = '';
                for (x in divs) {
                    var newDiv = $(x.toString());
                    divContainer.appendChild(newDiv);
                }
                tabbar.clearAll();
                tabbar.normalize();
            }
        }
        /**
        *Aumenta la fuente de los elementos en los cuales  el valor del atributo Class sea igual a 'DIV.gridbox_light TABLE.obj TD'
        */
        function Aumentar_Fuente() {
            //alert(valorcss("DIV.gridbox_light TABLE.obj TD","fontSize"));
            var actual = valorcss("DIV.gridbox_light TABLE.obj TD", "fontSize").replace("px", "");
            var actual2 = valorcss("TD", "fontSize").replace("px", "");
            actual = eval(actual) + 1;
            actual2 = eval(actual2) + 1;
            //alert(actual);
            changecss("DIV.gridbox_light TABLE.obj TD", "fontSize", actual + "px");
            changecss("TD", "fontSize", actual2 + "px");
        }

        /**
        *Disminuye la fuente de los elementos en los cuales  el valor del atributo Class sea igual a 'DIV.gridbox_light TABLE.obj TD'
        */
        function Disminuir_Fuente() {
            var actual = valorcss("DIV.gridbox_light TABLE.obj TD", "fontSize").replace("px", "");
            actual = eval(actual) - 1;
            changecss("DIV.gridbox_light TABLE.obj TD", "fontSize", actual + "px");
        }

        /**
        *Verifica si existe la propiedad indexof en los array de no existir la crea
        */

        if (!Array.prototype.indexOf) {
            Array.prototype.indexOf = function (obj, fromIndex) {
                if (fromIndex == null) {
                    fromIndex = 0;
                } else if (fromIndex < 0) {
                    fromIndex = Math.max(0, this.length + fromIndex);
                }
                for (var i = fromIndex, j = this.length; i < j; i++) {
                    if (this[i] === obj)
                        return i;
                }
                return -1;
            };
        }

        function finFrame(href) {
            var cual = -1;
            for (var i = 0; i < window.frames.length; i++) {
                if (window.frames[i].location.href.indexOf(href) > 0) {
                    return i
                }
            }
            return cual;
        }

		
//falta
        function removeNonDecimalCharCS(text) {
            text = removeNonDecimalChar(text);
            return text.replace(/\./gi, ',');
        }
		
//falta
        function removeNoNumber(strSource) {
            var m_strOut = new String(strSource);
            m_strOut = m_strOut.replace(/[^0-9]/g, '');
            return m_strOut;
        }

        /**
        *Verifica si un file tiene o no archivos asignados
        *@param idFile {String} id del file a verificar
        *@return true si tiene archivos, false si no los tiene {Boolean}
        */
        function valFiles(idFile) {
            return $(idFile).childNodes.length > 0;
        }

        /**
        *Guarda el valor de los combos indicados en un tag oculto automáticamente
        *@param ids {String} ids de los combos separados por coma
        */
        function grabarValorCombos(ids) {
            if (ids == '')
                return;
            var arrCombos = ids.split(',');
            var n = arrCombos.length;

            for (var i = 0; i < n; i++) {
                var combo = $(arrCombos[i]);
                if (combo == null)
                    continue;

                try{
                    if ($('t' + arrCombos[i]) == null) {
                        var ts = document.createElement('input');
                        ts.setAttribute('type', 'hidden');
                        ts.setAttribute('id', 't' + arrCombos[i]);
                        ts.value = combo.value;
                        combo.parentNode.appendChild(ts);
                    } else {
                        $('t' + arrCombos[i]).value = combo.value;
                    }
                } catch (E) {
                    console.log('Error: ' + E.message);
                }
            }
        }

//falta
        function getFormDataFile(excElemUser, excludeEmpty, saveNameUpper) {
            var files = '';
            var excElem = ',CBHELPFOCUS,SOL_ID,SUBMIT,SUBMIT1,';

            if (saveNameUpper == undefined || saveNameUpper == null)
                saveNameUpper = true;

            if (excElemUser != undefined && excElemUser != null && excElemUser != '')
                excElem += excElemUser + ',';


            //var items = document.getElementsByTagName('ol');
            for (var i = 1; i <= 20; i++) {
                var id = 'f' + i;
                if ($(id) == null) {
                    files += '¬';
                    continue;
                }

                var idU = id.toUpperCase();

                if (excElem.indexOf(',' + idU + ',') >= 0)
                    continue;

                var preffix = idU.substring(0, 1);

                if (preffix == 'F') {
                    for (var iOption = 0; iOption < $(id).childNodes.length; iOption++) {
                        if ($(id).childNodes[iOption].title == null || $(id).childNodes[iOption].title == undefined)
                            continue;

                        files += $(id).childNodes[iOption].title + ':' + $(id).childNodes[iOption].id + ';';
                    }
                    if (files.length >= 1 && files.substring(files.length - 1, files.length) == ';') {
                        files = files.substring(0, files.length - 1);
                    }
                    files += '¬';
                }
            }

            files = files.substring(0, files.length - 1);
            return files;
        }

//falta
//http://stackoverflow.com/questions/728360/most-elegant-way-to-clone-a-javascript-object
function clone(obj) {
    // Handle the 3 simple types, and null or undefined
    if (null == obj || "object" != typeof obj) return obj;

    // Handle Date
    if (obj instanceof Date) {
        var copy = new Date();
        copy.setTime(obj.getTime());
        return copy;
    }

    // Handle Array
    if (obj instanceof Array) {
        var copy = [];
        for (var i = 0, len = obj.length; i < len; i++) {
            copy[i] = clone(obj[i]);
        }
        return copy;
    }

    // Handle Object
    if (obj instanceof Object) {
        var copy = {};
        for (var attr in obj) {
            if (obj.hasOwnProperty(attr)) copy[attr] = clone(obj[attr]);
        }
        return copy;
    }

    throw new Error("Unable to copy obj! Its type isn't supported.");
}

//falta
var winModal, winModalArgs, winModalResponse;
function showModalDialogM(url, args, winSettings, callback, botonCerrar) {
    if (window.showModalDialog) {
        var response = window.showModalDialog(url, args, winSettings);
        if (typeof (callback) != 'undefined') {
            callback(response);
        }
        return response;
    }
    else {
        winModalArgs = args;

        var height = getRegExpMatches(winSettings, /dialogHeight:([^;]+)/ig, 1);
        var width = getRegExpMatches(winSettings, /dialogWidth:([^;]+)/ig, 1);

        winModal = document.createElement("DIALOG");

        if (!winModal.showModal) {
            winModal = document.createElement("DIV");
        }

        if (botonCerrar == undefined)
            winModal.innerHTML = '<input type="button" value="X" onclick="winModal.close();" /><br/>';

        winModal.style.border = '1px solid rgba(0, 0, 0, 0.3)';
        winModal.style.borderRadius = '6px';
        winModal.style.boxShadow = '0 3px 7px rgba(0, 0, 0, 0.3)';

        var content = document.createElement("iframe");
        content.src = url;
        content.style.width = width;
        content.style.height = height;

        winModal.appendChild(content);

        if (winModal.showModal) {
            winModal.addEventListener('close', function () {
                if (typeof (callback) != 'undefined') 
                    callback(winModalResponse);
                
                winModal = null;
                winModalArgs = null;
                winModalResponse = null;
            });
        } else {
            winModal.style.position = 'fixed';
            winModal.style.top = '50%';
            winModal.style.left = '50%';
            winModal.style.transform = 'translate(-50%, -50%)';
            winModal.style.backgroundColor = 'white';
            winModal.style.border = 'none';

            winModal.close = function () {
                if (typeof (callback) != 'undefined') 
                    callback(winModalResponse);
                
                this.style.display = 'none';

                winModal = null;
                winModalArgs = null;
                winModalResponse = null;
            }
        }

        try {
            document.documentElement.appendChild(winModal);
        } catch (E) {
            document.body.appendChild(winModal);
        }

        if (winModal.showModal)
            winModal.showModal();

        return null;
    }
}

//falta
//http://stackoverflow.com/questions/432493/how-do-you-access-the-matched-groups-in-a-javascript-regular-expression/14210948#14210948
function getRegExpMatches(str, regex, index) {
    index || (index = 1); // default to the first capturing group
    var matches = [];
    var match;
    while (match = regex.exec(str)) {
        matches.push(match[index]);
    }
    return matches;
}

//falta
function clearCR(elements) {

    var i = 0;
    ArrayElements = elements.split(",");
    while (i < ArrayElements.length) {
        $(ArrayElements[i]).checked = false;
        i++;
    }
}

/**
*Muestra u oculta el campo par editar, utilizado en los tags del modificador EDT
*@param tag {String} id del tag a editar
*@param ver {Boolean} true para ver, false para ocultar
*/
function verEditarTag(tag, ver) {
    var elemVer = 'v_{0},opc_{0}';
    var elemOcultar = '{0},edt_{0},hst_{0}';

    elemVer = elemVer.format(tag);
    elemOcultar = elemOcultar.format(tag);

    setDisplayElements(ver, elemVer);
    setDisplayElements(!ver, elemOcultar);

    if (!ver) {
        $('v_' + tag).childNodes[0].value = $ih(tag);
    }
}

/**
*Aplicar validación para algun tag con el modificador EDT
*@param input {HTMLTag} Control que dispara la validación
*/
function validarTag(input) {
    if (existeFValidar()) {
        validarTagEdit(input, input.parentNode.id);
    }
}

function existeFValidar() {
    try {
        validarTagEdit;
        return true;
    } catch (E) { return false;}
}

/**
*Guarda el valor del Tag en base de datos, realiza la actualización, usado con el modificador EDT
*@param tipo {String} tipo de campo según codificación de base de datos 10,20,20,40
*@param tag {String} id del tag a modificar
*@param tagAsociado {String} id del tag asociado, se usa para los combos, guardar el texto y el valor
*/
function guardarTag(tipo, tag, tagAsociado) {
    var tNValor = $('_e_' + tag);

    if (tNValor.value != $ih(tag)) {
        if (existeFValidar()) {
            if (validarTagEdit(tNValor, tag)) {
                if (tipo == '40') {
                    guardarTagBd(tipo, tag, $stext(tNValor.id));
                    guardarTagBd('10', tagAsociado, tNValor.value);
                } else {
                    guardarTagBd(tipo, tag, tNValor.value);
                }
            }
        } else {
            if (tipo == '40') {
                guardarTagBd(tipo, tag, $stext(tNValor.id));
                if (tagAsociado != "") {
                    guardarTagBd('10', tagAsociado, tNValor.value);
                }
            } else {
                guardarTagBd(tipo, tag, tNValor.value);
            }
        }
    }
}

/**
*Envia la actualización de un tag a la base de datos, usado con el modificador EDT
*@param tipo {String} tipo de campo según codificación de base de datos 10,20,20,40
*@param tag {String} id del tag a modificar
*@param nuevoValor {String} valor que se desea actualizar
*/
function guardarTagBd(tipo, tag, nuevoValor) {
    displayElement('_carg' + tag, true);

    var proId = $v('_pro');
    var frmId = '';
    var tagFrm = '';
    var tTipo = 'T';
    var valorAnt = ($ih(tag) != null) ? $ih(tag) : '';
    var nombreTag = '';

    try{
        nombreTag = $(tag).parentNode.parentNode.previousSibling.previousSibling.innerHTML.trim().replace(':', '');
    } catch (E) {
        console.log('Error an obtener el nombre del tag ' + E.message);
    }

    if (tipo == '40')
        tTipo = 'S';

    if (tipo == '40' && tag.replace(/[0-9]/g, '') == 'R') {
        tipo = '20';
        tTipo = 'R';
    }

    frmId = tag.substring(0, tag.indexOf(tTipo));
    tagFrm = tag.substring(tag.indexOf(tTipo), tag.length);

    if (valorAnt == '')
        valorAnt = ajax_generales.getValorTag(proId, frmId, tipo, tagFrm).value;

    if (frmId != '' && tagFrm != '' && proId != '') {
        ajax_generales.actualizarDatosXML(tagFrm, proId, frmId, tipo, nuevoValor, valorAnt, (valorAnt != ''), false, '', nombreTag, function (data) {
            displayElement('_carg' + tag, false);

            if (parseInt(data.value) > 0) {
                if ($(tag) != null) {
                    $(tag).innerHTML = nuevoValor;
                    verEditarTag(tag, false);
                }
            } else {
                alert('No se pudo Actualizar el Valor');
            }
        });
    } else {
        displayElement('_carg' + tag, false);
    }
}

/**
*Carga el historial de cambios de un tag, usado con el modificador EDT
*@param tag {String} id del tag a modificar
*@param tipo {String} tipo de campo según codificación de base de datos 10,20,20,40
*/
function verHistorialTag(tag, tipo) {
    if ($('_hist_Tags_') == null) {
        crearDvHistorialTag(tag);
        verDvHistorial(true);
    } else {
        verDvHistorial(true);
    }

    displayElement('_hist_Tags_carg', true);

    var tTipo = 'T';
    var proId = $v('_pro');
    var frmId = '';
    var tagFrm = '';

    if (tipo == '40')
        tTipo = 'S';

    if (tipo == '40' && tag.replace(/[0-9]/g, '') == 'R') {
        tipo = '20';
        tTipo = 'R';
    }

    frmId = tag.substring(0, tag.indexOf(tTipo));
    tagFrm = tag.substring(tag.indexOf(tTipo), tag.length);

    ajax_generales.getHistorialTag(proId, frmId, tipo, tagFrm, function (data) {
        displayElement('_hist_Tags_carg', false);

        if (data == null || data.value == null || data.value.Rows.length == 0)
        {
            $('_hist_Tags_info').innerHTML = 'No se encontró Historial de Cambios de este campo';
            return;
        }

        $('_hist_Tags_info').appendChild(crearTablaDesdeDT(data));
    });
}


//falta
function crearDvHistorialTag(tag) {
    var htmlHistorial = '<div id="_hist_Tags_bloq" style="display:none;height: 100%;left: 0;position: absolute; top: 0;width: 100%;z-index: 9;background-color: #DBEAF5;opacity: 0.2;filter: alpha(opacity=10);"></div>';
    htmlHistorial += '<div id="_hist_Tags_" style="display:none;top: 50%; left: 30%;margin-top: -200px;margin-left: -50px; width:600px; height:300px; border: 2px solid #A4BFD6; z-index: 20; background-color:white;position:fixed; padding: 8px; border-radius: 8px;"><input type="button" value="X" onclick="verDvHistorial(false);" style="float:right;cursor:pointer;" /><div><span id="_hist_Tags_carg" style="display:none;"><img src="../images/loading.gif" /> Cargando Información...</span></div><div id="_hist_Tags_info" style="width:100%;height:285px;padding:2px;overflow:auto;" class="frto"></div></div>';

    var dvContenedor = document.createElement('div');
    dvContenedor.innerHTML = htmlHistorial;

    $(tag).parentNode.parentNode.appendChild(dvContenedor);
}

//falta
function verDvHistorial(ver) {
    var alto = document.body.scrollHeight;
    $('_hist_Tags_bloq').style.height = alto + 'px';
    setDisplayElements(ver, '_hist_Tags_bloq,_hist_Tags_');
    $('_hist_Tags_info').innerHTML = '';
}

//falta
function crearTablaDesdeDT(dt) {
    var tabla = document.createElement('table');
    var trEnc = document.createElement('tr');

    var f = dt.value.Rows.length;
    var c = dt.value.Columns.length;

    //Crear Encabezados
    for (var i = 0; i < c; i++) {
        var th = document.createElement('th');
        th.innerHTML = dt.value.Columns[i].Name;

        trEnc.appendChild(th);
    }

    tabla.appendChild(trEnc);

    //Crear Filas
    for (var j = 0; j < f; j++) {
        var tr = document.createElement('tr');

        for (var x = 0; x < c; x++) {
            var td = document.createElement('td');
            td.innerHTML = dt.value.Rows[j][dt.value.Columns[x].Name];

            tr.appendChild(td);
        }

        tabla.appendChild(tr);
    }

    return tabla;
}

/**
 * Recibe implícitamente (como contexto) un select (select-one ó select-multiple)
 * @return {String} valores seleccionados separados por coma
 */
function getSelectValue() {
    try {
        return Array.prototype.slice.call(this.selectedOptions).filter(function (opt) { return opt.value }).map(function (opt) { return opt.value }).join();
    } catch (E) {
        console.error(E);
        return '';
    }
}

/** 
*Obtener los valores seleccionados de un combo, separado por comas
*@param {HTMLSelectElement} select Select que se requiere obtener los valores selccionados
* @return {String} Valores seleccionados, separados por coma
*/
function getSelectValue2(select) {
    if (select != null) {
        var arrOpt = [];
        var opts = select.options;
        var n = opts.length;

        for (var i = 0; i < n; i++) {
            var opt = opts[i];

            if (opt.selected)
                arrOpt.push(opt.value);
        }

        return arrOpt.join();
    }

    return '';
}

//falata
var vModal = null;
function Adjuntar(cual, fileType, maxFiles, maxLengthKB) {
    var tipo = "";
    var cantidad = "3";
    var max = "1024";
    var cualf = cual;
    var i;
    var fileName = "";
    var fileMD5 = "";
    var mensaje = '';
    var btnf = $("btnf" + cual);

    if (fileType != "" && fileType != null && fileType != undefined)
        tipo = fileType;
    if (maxFiles != "" && maxFiles != null && maxFiles != undefined)
        cantidad = maxFiles;
    if (maxLengthKB != "" && maxLengthKB != null && maxLengthKB != undefined)
        max = maxLengthKB;

    //Validar la cantidad de Files con ol válidos
    var arrFiles = $("f" + cual).querySelectorAll("li");

    cantidad = cantidad - arrFiles.length;
    if (cantidad <= 1 && btnf != null)
        btnf.style.display = "none";

    if (vModal == null) {
        getVModal();

        vModal.close = function (rFiles) {
            try {
                ponerFile(rFiles, maxFiles, cual, cualf, mensaje);
            } catch (E) { }
            
            bloqVModal(false);
            this.style.display = 'none';
            vModal.parentNode.removeChild(vModal);
            vModal = null;
        }

        vModal.innerHTML = '';
    }

    var upload = getUpload(tipo, max, cantidad, cualf);
    vModal.appendChild(upload);

    try {
        bloqVModal(true);
        document.documentElement.appendChild(vModal);
    } catch (E) {
        bloqVModal(true);
        document.body.appendChild(vModal);
    }

    if (vModal.showModal) {
        vModal.showModal();
    }
}

//falta
function getVModal() {
    vModal = document.createElement("DIV");
    vModal.style.position = 'fixed';
    vModal.style.zIndex = '15000';
    vModal.style.top = '50%';
    vModal.style.left = '50%';

    wdVModal();
}

//falta
function getUpload(tipo, max, cantidad, cualf) {
    var upload = document.createElement("iframe");
    upload.id = '_upload_';
    upload.style.border = 'none';
    upload.src = "../solicitudes/plantillas/upload.aspx?t=" + tipo + "&m=" + max + "&c=" + cantidad + "&f=" + cualf;

    if (screen.width > 500) {
        upload.style.width = '800px';
        upload.style.height = '520px';
    } else {
        upload.style.width = screen.width + 'px';
        upload.style.height = screen.height + 'px';
    }

    return upload;
}

//falta
function wdVModal() {
    if (screen.width > 500) {
        vModal.style.transform = 'translate(-50%, -50%)';
    } else {
        vModal.style.width = '100%';
        vModal.style.height = '100%';
        vModal.style.top = '0';
        vModal.style.left = '0';
    }
}

//falta
function bloqVModal(ver) {
    if (!$('_dvbloq_')) {
        var dvBloq = document.createElement("DIV");
        dvBloq.id = '_dvbloq_';
        dvBloq.style.position = 'absolute';
        dvBloq.style.zIndex = '14900';
        dvBloq.style.width = document.body.scrollWidth + 'px';
        dvBloq.style.height = document.body.scrollHeight + 'px';
        dvBloq.style.top = '0';
        dvBloq.style.left = '0';
        dvBloq.style.backgroundColor = '#7A7E89';
        dvBloq.style.opacity = '0.5';

        if (ver) {
            try {
                document.documentElement.appendChild(dvBloq);
            } catch (E) {
                document.body.appendChild(dvBloq);
            }
        }
    } else {
        setDisplayElements(ver, '_dvbloq_');
    }
}

//falta
String.prototype.limit = function () {
    if (this.length > arguments[0]) {
        return this.substring(0, arguments[0]) + arguments[1];
    }
    return this;
};