/* Instrucciones:
=================
1. incluir primero mvd_form_fecha.js y despues dlcalendar.js
2. incluir el código de dlcalendar y los campos dia, mes y año. Los ids de éstos, deben ser la concatenación de input_element_id y "_day", "_month" y "_year" respectivamente.

<dlcalendar click_element_id="imgCalendario" input_element_id="fecha" urlbase="%%UrlDelSitio%%/jscripts/dlcalendar/"></dlcalendar>
<input id="fecha_day" name="fecha_day" value="13" size="2" maxlength="2" type="text"> de
<select id="fecha_month" name="fecha_month">
    <option value="1">Enero</option>
    <option value="2">Febrero</option>
    <option value="3">Marzo</option>
    <option value="4">Abril</option>
    <option value="5">Mayo</option>
    <option value="6">Junio</option>
    <option value="7">Julio</option>
    <option value="8">Agosto</option>
    <option value="9">Septiembre</option>
    <option value="10">Octubre</option>
    <option value="11">Noviembre</option>
    <option value="12">Diciembre</option>
</select> del
<input name="fecha_year" class="camposlogin" id="fecha_year" value="1975" size="4" maxlength="4" type="text">
<img align="top" src="%%UrlDelSitio%%/jscripts/dlcalendar/dlcalendar.gif" height="13" width="13" id="imgCalendario">

3. En la hoja de estilos, puede estar definida la clase 'inputError' que se usará si la fecha ingresada es erronea.
4. Validación y otros:
    // Obtener la instancia del controlador para una fecha. Usar el mismo valor que input_element_id.
    var f = MVD.Form.getFecha('fecha');
    if (!f.isValid()) {  // f.isValid() devuelve true si la fecha es correcta.
        alert("ERROR");
    }
    var v = f.getDMY();  // v es un array con, v[0] = día, v[1] = mes, v[2] = año. v = null si la fecha es incorrecta.
    var s = f.getValue();  // s es un string con la fecha en formato aaaammdd. Ej: "20080519". s = null si la fecha es incorrecta.
    f.setValue(24,12,2008); // Cambia el valor de la fecha al 24 de diciembre de 2008.
*/

if (typeof(MVD) == 'undefined') {
    MVD = { Form: {} };
} else {
    if (typeof(MVD.Form) == 'undefined') {
        MVD.Form = {};
    }
}

Array.prototype.remove = function (element) {
    var i=0;
    while(i<this.length) {
        if (this[i] == element)
            this.splice(i, 1);
        i++;
    }
};

Array.prototype.contains = function (element) {
    var l = this.length - 1;
    while (l >= 0) {
        if (this[l] == element) {
            return true;
        }
        l --;
    }
    return false;
}

MVD.extend = function (base, ext) {
	for (var i in ext) if (ext.hasOwnProperty(i)) {
        base[i] = ext[i];
	}
};

MVD.addClass = function (elem, clase) {
    var l = elem.className.split(" ");
    var nc;
    if (l.length > 0) {
        l.push(clase);
        nc = l.join(" ");
    } else {
        nc = clase;
    }
    elem.className = nc;
};

MVD.removeClass = function (elem, clase) {
    var l = elem.className.split(" ");
    if (l.length > 0) {
        l.remove(clase)
        elem.className = l.join(" ");
    }
};

// Obtiene el valor de un select (combo box)
function getSelectValue(sel) {
    return sel.options && sel.options[sel.selectedIndex].value;
}

// Cambia el valor de un select (combo box)
function setSelectValue(sel, val) {
    if (sel.options) {
        var i = sel.options.length - 1;
        while (i > 0) {
            if (sel.options[i].value === val) {
                sel.selectedIndex = i;
                return true;
            }
            i --;
        }
    }
    return false;
}

/* Definición de clase MVD.Form.Fecha */
(function () {
    /* Funciones privadas de MVD.Form.Fecha */

    function isNumber(str) {
        return (/^[0-9]+$/).test(str);
    }

    function num2str(val, len) {
        var s = '' + val;
        while(s.length < len) {
            s = '0' + s;
        }
        return s;
    }

    // Recibe un día, mes y año y devuelve el string "aaaammdd"
    function dma2str(d, m, a) {
        return num2str(a,4) + num2str(m,2) + num2str(d, 2);
    }

    // Indica si un año es bisiesto.
    function esBisiesto(y) {
        return ((y % 4 == 0) && (( y % 100 != 0) || (y % 400 == 0)));
    }

    // Devuelve la cantidad de días de un mes, dado el mes y el año.
    function daysMonth(m, y) {
        var d = [0, 31, 0, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
        if (m == 2) {
            return esBisiesto(y) ? 29 : 28;
        } else {
            return d[m];
        };
    }

    // Indica si un número de día es válido para un mes y año.
    function dayValid(d,m,y) {
        return (d > 0) && (d <= daysMonth(m, y));
    }

    // Constructor. Recibe el id base de la fecha.
    MVD.Form.Fecha = function (base_id) {
        //this.base_id = base_id;
        this.dayInput = document.getElementById(base_id + '_day');
        this.monthSelect = document.getElementById(base_id + '_month');
        this.yearInput = document.getElementById(base_id + '_year');

        var that = this;
        var validation = function () {
            that.validate();
        }
        this.dayInput.onchange = validation;
        // this.monthSelect.onclick = validation;
        this.monthSelect.onblur = validation;
        this.yearInput.onchange = validation;
        this.isOk = true;
        MVD.Form.Fecha.prototype.all[base_id] = this;
    };

    /* Funciones públicas de MVD.Form.Fecha */
    MVD.extend(MVD.Form.Fecha.prototype, {
        // Lista de instancias de MVD.Form.Fecha.
        all : {},
        // Obtiene la instancia con esa id base.
        getInstance : function (id) {
            var i = this.all[id];
            if (!i) {
                i = new MVD.Form.Fecha(id);
            }
            return i;
        },

        // Devuelve día, mes y año. Si la fecha no es válida devuelve null
        getDMY : function () {
            var d = this.dayInput.value, m = getSelectValue(this.monthSelect), y = this.yearInput.value;
            if (isNumber(d) && isNumber(y)) {
                var D = parseInt(d, 10), M = parseInt(m, 10), Y = parseInt(y, 10);
                if (dayValid(D, M, Y) && Y >= 1920) {
                    return [D,M,Y];
                }
            }
            return null;
        },

        // Devuelve true si la fecha es correcta, false si es incorrecta.
        isValid : function () {
            return this.getDMY() ? true : false;
        },

        // Devuelve el valor de la fecha en el formato "aaaammff". Si la fecha no es valida devuelve null.
        getValue : function () {
            var v = this.getDMY();
            return v && dma2str(v[0], v[1], v[2]); // Idem a v ? dma2str(v[0], v[1], v[2]) : null
        },

        validate : function () {
            var errorClass = 'inputError';
            var v = this.getDMY();
            if (!v) {
                if (this.isOk) {
                    MVD.addClass(this.dayInput, errorClass);
                    MVD.addClass(this.monthSelect, errorClass);
                    MVD.addClass(this.yearInput, errorClass);
                    this.isOk = false;
                    alert("La fecha no es válida.");
                }
            } else {
                this.isOk = true;
                MVD.removeClass(this.dayInput, errorClass);
                MVD.removeClass(this.monthSelect, errorClass);
                MVD.removeClass(this.yearInput, errorClass);
            }
        },

        // Establece el valor de la fecha.
        setValue : function(d,m,y) {
            this.dayInput.value = '' + d;
            setSelectValue(this.monthSelect, '' + m);
            this.yearInput.value = '' + y;
            this.validate();
        }
    });

    MVD.Form.getFecha = function (id) {
        return MVD.Form.Fecha.prototype.getInstance(id);
    }

}) ();

