/**
 * Clase: LiveTable
 * Autor: Alberto Giménez E.
 * Requiere: prototype.js,
 * 			 YUI (yahoo.js, dom.js, event.js, connection.js
 * 			 datasource-beta.js, datatable-beta.js)
 */
acadweb = new Object();
/*@overide */
YAHOO.widget.DataTable.MSG_EMPTY = "No existen registros";
YAHOO.widget.DataTable.MSG_ERROR = "Sin datos";
YAHOO.widget.DataTable.MSG_LOADING = "Cargando datos";
YAHOO.widget.DataTable.CLASS_TABLE = "table";
YAHOO.widget.DataTable.CLASS_EVEN = "odd";
YAHOO.widget.DataTable.CLASS_ODD = "even";
YAHOO.widget.DataTable.CLASS_LOADING  = "empty";
YAHOO.widget.DataTable.CLASS_ERROR  = "empty";
YAHOO.widget.DataTable.CLASS_EMPTY  = "empty";
YAHOO.widget.DataTable.CLASS_BODY  = null;
YAHOO.widget.DataTable.CLASS_SELECTED  = "selected";
YAHOO.widget.DataTable.CLASS_PAGELINKS = "pagelinks";
YAHOO.widget.DataTable.CLASS_PAGINATOR = "pagebanner"
/**
 * Esta clase representa una tabla din&aacute;mica implementada
 * con YUI.
 */
acadweb.LiveTable = Class.create();
acadweb.LiveTable.prototype = {
    /**
     * Crea una nueva instancia de LiveTable
     * @param divId El identificador del contenedor
     * @param opts Las opciones adicionales del Datatable
     */
    initialize: function (divId, opts) {
        Object.extend(this, Object);
        this.columnHeaders = [];
        this.opts = opts;
        this.myId = divId;
        this.dataSource = new YAHOO.util.DataSource([]);
        this.dataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
        this.dataSource.responseSchema = { fields: []};
        this.created = false;
    },
    /**
     * Agrega una cabecera de columna especificando el nombre y el tipo.
     * @param nombre El nombre de la columna cabecera
     * @param label La etiqueta de la columna cabecera
     * @param type El tipo de la columna cabecera
     */
    addColumnHeader: function(nombre, label, opts) {
        var cabecera = {key:nombre, text:label};
        if (opts != null) {
            Object.extend(cabecera, opts);
        }
        this.columnHeaders.push(cabecera);
        this.dataSource.responseSchema.fields.push(nombre);
    },
    /**
     * Dibuja la tabla a partir de la información proveida.
     */
    draw: function() {
        var columnSet = new YAHOO.widget.ColumnSet(this.columnHeaders);
        this.dataTable = new YAHOO.widget.DataTable(this.myId, columnSet, this.dataSource, this.opts);
        this.created = true;
        var first = false;
        var tabla = $(this.myId).getElementsBySelector("table")[0];
        var th = tabla.getElementsBySelector("th");
        for (var i = 0; i < th.length; i++) {
            if (this.dataTable.getColumnSet().keys[i].sortable) {
                th[i].addClassName("sorteable");
                var a = th[i].getElementsBySelector("a")[0];
                th[i].firstDescendant().remove();
                th[i].appendChild(a);
                Event.observe(th[i], "click", this.toggleHeader);
                if (!first) {
                    th[i].addClassName("sorted order1");
                    first = true;
                }
            }
        }
    },
    /**
     * Agrega un item a la tabla dinámica.
     * Debe recibir HASH con las claves especificadas en
     * "this.dataSource.responseSchema.fields"
     * Ej.
     * this.dataSource.responseSchema.fields = ["codigo", "descripcion"]
     * => Entonces
     * item = {codigo:"1", descripcion: "esta es una descripción"}
     * Si no ocurre esto agregará filas vacías con error de datos.
     * @param item El item a agregar
    */
    addItem: function(item) {
        this.dataTable._oRecordSet.append(item);
        this.dataTable.populateTable();
    },
    /**
     * Envia un item asíncronamente al dirección de recurso URL.
     * @param url La dirección de recurso URL
     * @param item La fila a enviar
    */
    sendItem: function(url, item) {
        var caller = this;
        var xmlhttprequest = new Ajax.Request(url, {
                                  method: 'post',
                                  parameters: Hash.toQueryString(item),
                                  onFailure: function (transport) {
                                          caller.dataTable.showErrorMessage();
                                      }
                                  });
    },
    /**
     * Cambia la vista de una columna cabecera ordenable, la
     * que anteriormente estaba elegida cambia.
     * @param event El evento disparado cuando se realiza
     * click sobre la columna a ordenar.
    */
    toggleHeader: function(event) {
        var th = event.currentTarget;
        if (!th.hasClassName("sorted")) {
            th.addClassName("sorted")
        }
        if (th.hasClassName("order2")) {
            th.removeClassName("order2");
            th.addClassName("order1");
        }
        else if (th.hasClassName("order1")) {
            th.removeClassName("order1");
            th.addClassName("order2");
        }
        else {
            th.addClassName("order1");
        }
        var ths = th.siblings();
        for (var i = 0; i < ths.length; i++) {
            ths[i].removeClassName("sorted");
            ths[i].removeClassName("order1");
            ths[i].removeClassName("order2");
        }
    },
    clean: function () {
        this.dataTable._oRecordSet.reset();
        if (this.dataTable._elBody) {
            Element.getElementsBySelector(this.dataTable._elBody, "tr").map(Element.remove);
        }
        this.dataTable.populateTable();
    }
}

/**
 * Esta clase representa un tabla din&aacute;mica de b&uacute;squeda implementada
 * con YUI.
 */
acadweb.SearchTable = Class.create();
acadweb.SearchTable.prototype = {
    initialize: function (divId, opts) {
        Object.extend(this, acadweb.LiveTable);
        acadweb.LiveTable.prototype.initialize.apply(this, arguments);
        this.myForm = "<div><form method='post' action='searchTable.html' id='" + divId + "_frm'>";
        this.myForm += "<h2>B&uacute;squeda</h2>";
        this.myForm += "<table><tr>";
        this.target = null;
    },
    addColumnHeader: function(nombre, label, opts) {
        acadweb.LiveTable.prototype.addColumnHeader.apply(this, arguments);
        this.myForm += "<td><label class='desc'>" + label + "</label>" +
                     "<input type='text' size='20' maxlength='100' name='" + nombre + "'></td>"
    },
    draw: function() {
        acadweb.LiveTable.prototype.draw.apply(this);
        this.myForm += "</tr><tr><td colspan=" + this.columnHeaders.length + " align='center'><input type='hidden' name='sourceEntity' value='" + this.sourceEntity + "'>";
        this.myForm += "<input type='button' class='button' value='Buscar' onclick='" + this.myId + ".getItems(this);' ></td></tr></table></form></div>"
        this.myForm = new Insertion.Top($(this.myId), this.myForm);
        if (this.target != null) {
            new Insertion.Bottom($(this.myId), "<input type='button' class='button' value='Agregar' onclick='" + this.myId + ".agregar();' />");
        }
        this.dataTable.subscribe("cellClickEvent", this.dataTable.onEventSelectRow);
    },
    agregar: function() {
        if (this.target) {
            var id = this.dataTable.getSelectedRecordIds()[0];
            if (id != null) {
                var item = Object.clone(this.dataTable._oRecordSet.getRecord(id))
                this.target.addItem(item);
            }
        }
    },
    addItem: function(item) { acadweb.LiveTable.prototype.draw.apply(this); },
    getItems: function (form) {
        var caller = this;
        this.clean();
        this.dataTable.showLoadingMessage();
        $(this.myId + "_frm").request({
                        method:'post',
                        onSuccess: function (transport) {
                                caller.dataTable._oRecordSet.append(transport.responseText.gsub("\n|\r","").evalJSON());
                                caller.dataTable.populateTable();
                            },
                        onFailure: function (transport) {
                                caller.dataTable.showErrorMessage();
                            },
                        on302: function (transport) {
                                location.href = '/';
                            }
                        });
        return false;
    },
    sendItem: function(url, item) { return; },
    toggleHeader: function(event) { acadweb.LiveTable.prototype.toggleHeader.apply(this, arguments); },
    clean: function () { acadweb.LiveTable.prototype.clean.apply(this, arguments); }
}

/**
 * Esta clase representa una utilidad para un formulario.
 * Utiliza el framework Prototype.jss
 */
acadweb.FormUtil = Class.create();
acadweb.FormUtil.prototype = {
    initialize: function(formId) {
        if ($(formId)) {
            this.item = {};
            var fields = Form.getElements($(formId));
            for (var i = 0; i < fields.length; i++) {
                var tipo = fields[i].readAttribute("type");
                var nombre = fields[i].readAttribute("name");
                if (tipo == null || (tipo != "button" && tipo != "file" &&
                    tipo != "reset" && tipo != "submit")) {
                    this.item[nombre] = $F(fields[i]);
                }
            }
        }
    }
}

acadweb.Formatter = new Object();
acadweb.Formatter.fBoolean = function(elCell, oRecord, oColumn, oData) {
        if(oData == "S") {
            elCell.innerHTML = "SI";
        }
        else {
            elCell.innerHTML = "NO";
        }
    };

acadweb.Formatter.fRound = function(valor) {
        var retorno = parseFloat(valor);
        var resto = valor % 1000;
        if (resto > 0) {
            retorno += (1000 - resto)
        }
        return retorno;
    };