/*  Copyright Mihai Bazon, 2002, 2003  |  http://dynarch.com/mishoo/
* This script is distributed under the GNU Lesser General Public License.
* Read the entire license text here: http://www.gnu.org/licenses/lgpl.html
*
* This file defines helper function for setting up the calendar.
* modified by Konstantin Pelepelin, DTF.RU
* uses external addEvent()
*/

/**
*  This function "patches" an input field (or other element) to use a calendar
*  widget for date selection.
*
*  The "params" is a single object that can have the following properties:
*
*    prop. name   | description
*  -------------------------------------------------------------------------------------------------
*   form          | the ID of a form with selects
*   selectsPrefix | common part of selects' names
*   button        | ID of a button or other element that will trigger the calendar (required)
*   eventName     | event that will trigger the calendar, without the "on" prefix (default: "click")
*   ifFormat      | date format that will be stored in the input field
*   singleClick   | (true/false) wether the calendar is in single click mode or not (default: true)
*   firstDay      | numeric: 0 to 6.  "0" means display Sunday first, "1" means display Monday first, etc.
*   align         | alignment (default: 'Br'); see calendar documentation
*   weekNumbers   | (true/false) if it's true (default) the calendar will display week numbers
*   disableFunc   | function that receives a JS Date object and should return true if that date has to be disabled in the calendar
*   onSelect      | function that gets called when a date is selected.  You don't _have_ to supply this (the default is generally okay)
*   onClose       | function that gets called when the calendar is closed.  [default]
*   onUpdate      | function that gets called after the date is updated in the input field.  Receives a reference to the calendar.
*   date          | the date that the calendar will be initially displayed to
*   showsTime     | default: false; if true the calendar will include a time selector
*   timeFormat    | the time format; can be "12" or "24", default is "12"
*   electric      | if true (default false) then given fields/date areas are updated for each move; otherwise they're updated only on close
*   step          | configures the step of the years in drop-down boxes; default: 2
*   position      | configures the calendar absolute position; default: null
*   cache         | if "true" (but default: "false") it will reuse the same calendar object, where possible
*   showOthers    | if "true" (but default: "false") it will show days from other months too
*/
Calendar.setup = function (params) {
    function param_default(pname, def) { if (typeof params[pname] == "undefined") { params[pname] = def; } };

    param_default("form",           null);
    param_default("selectsPrefix",  '');
    param_default("button",         null);
    param_default("eventName",      "click");
    param_default("singleClick",    true);
    param_default("disableFunc",    null);
    param_default("dateStatusFunc", params["disableFunc"]);	// takes precedence if both are defined
    param_default("dateText",       null);
    param_default("firstDay",       null);
    param_default("align",          'Br');
    param_default("weekNumbers",    false);
    param_default("onSelect",       null);
    param_default("onClose",        null);
    param_default("onUpdate",       null);
    param_default("date",           null);
    param_default("showsTime",      false);
    param_default("timeFormat",     "24");
    param_default("electric",       false);
    param_default("step",           1);
    param_default("position",       null);
    param_default("cache",          true);
    param_default("showOthers",     true);
    param_default("multiple",       null);

    if (typeof params["form"] == "string") {
        params["form"] = document.getElementById(params["form"]);
    }
    if (typeof params["button"] == "string") {
        params["button"] = document.getElementById(params["button"]);
    }

    if(!params.form) {
        alert("Calendar.setup:\n  Nothing to setup (no form found). Please check your code");
        return false;
    }

    if (!(params.multiple || params.button)) {
        alert("Calendar.setup:\n  Nothing to setup (no fields found). Please check your code");
        return false;
    }

    function onSelect(cal) {
        var p = cal.params;
        var prefix=p.selectsPrefix;

        if(!(cal.dateClicked || p.electric))
            return;

        var yf=p.form.elements[prefix+'Year'];
        var mf=p.form.elements[prefix+'Month'];
        var df=p.form.elements[prefix+'Day'];

        var y=cal.date.getFullYear();
        var m=cal.date.getMonth()+1;
        var d=cal.date.getDate();

        if(yf && y)
            for(var i=0;i<yf.options.length;i++)
            {
                var yfo=yf.options[i];

                if(parseInt(yfo.value) == y)
                {
                    yfo.selected=true;
                    break;
                }
            }

        if(mf && m)
            for(var i=0;i<mf.options.length;i++)
            {
                var mfo=mf.options[i];

                if(parseInt(mfo.value) == m)
                {
                    mfo.selected=true;
                    break;
                }
            }

        if(df && d)
            for(var i=0;i<df.options.length;i++)
            {
                var dfo=df.options[i];

                if(parseInt(dfo.value) == d)
                {
                    dfo.selected=true;
                    break;
                }
            }

        if (typeof p.onUpdate == "function")
            p.onUpdate(cal);

        if (p.singleClick && cal.dateClicked)
            cal.callCloseHandler();
    }

    var triggerEl = params.button;
    var togglecal = function() {

        var prefix=params.selectsPrefix;
        var yf=params.form.elements[prefix+'Year'];
        var mf=params.form.elements[prefix+'Month'];
        var df=params.form.elements[prefix+'Day'];

        // set current date
        var y= +yf.options[yf.selectedIndex].value;
        var m= +mf.options[mf.selectedIndex].value;
        var d= +df.options[df.selectedIndex].value;

        if(y && m && d && y!=NaN && m!=NaN && d!=NaN)
            params.date = new Date(y,m-1,d);
        else
            params.date = new Date();

        // set valid range
        max_y=min_y=null;
        for(i=yf.options.length;i-->0;)
        {
            y= +yf.options[i].value;
            if(y && y!=NaN && max_y<y) max_y=y;
            if(y && y!=NaN && (!min_y || min_y>y)) min_y=y;
        }

        var mustCreate = false;
        var cal = window.calendar;
        if (!(cal && params.cache)) {
            window.calendar = cal = new Calendar(params.firstDay,
                                params.date,
                                params.onSelect || onSelect,
                                params.onClose || function(cal) { cal.hide(); });
            cal.showsTime = params.showsTime;
            cal.time24 = (params.timeFormat == "24");
            cal.weekNumbers = params.weekNumbers;
            mustCreate = true;
        } else {
            if (params.date)
                cal.setDate(params.date);
            cal.hide();
        }
        if (params.multiple) {
            cal.multiple = {};
            for (var i = params.multiple.length; --i >= 0;) {
                var d = params.multiple[i];
                var ds = d.print("%Y%m%d");
                cal.multiple[ds] = d;
            }
        }
        cal.showsOtherMonths = params.showOthers;
        cal.yearStep = params.step;
        cal.setRange(min_y, max_y);
        cal.params = params;
        cal.setDateStatusHandler(params.dateStatusFunc);
        cal.getDateText = params.dateText;
        if (mustCreate)
            cal.create();
        cal.refresh();
        if (!params.position)
            cal.showAtElement(params.button, params.align);
        else
            cal.showAt(params.position[0], params.position[1]);
        return false;
    };

    addEvent(triggerEl, params.eventName, togglecal);

    return true;
};
