/** $Id: fastframe-setup.js 48 2010-04-29 02:24:38Z dlundgren $ */
// {{{ license

// +----------------------------------------------------------------------+
// | FastFrame Application Framework                                      |
// +----------------------------------------------------------------------+
// | Copyright (c) 2002-2009 The Codejanitor Group                        |
// +----------------------------------------------------------------------+
// | This source file is subject to the GNU Lesser Public License (LGPL), |
// | that is bundled with this package in the file LICENSE, and is        |
// | available at through the world-wide-web at                           |
// | http://www.fsf.org/copyleft/lesser.html                              |
// | If you did not receive a copy of the LGPL and are unable to          |
// | obtain it through the world-wide-web, you can get it by writing the  |
// | Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, |
// | MA 02111-1307, USA.                                                  |
// +----------------------------------------------------------------------+
// | Authors: David Lundgren <dlundgren@syberisle.net>                    |
// +----------------------------------------------------------------------+

// }}}
// {{{ global variables

// used to cache the calendar objects to prevent recreation
var a_cals = {};

// used to cache the field objects
var a_fields = {};

// }}}
/** FF_Calendar */
var FF_Calendar = {
    // {{{ properties

    fields: {},

    // }}}
    // {{{ _cacheField()

    /**
     * Caches the field information.
     *
     * @param {Object} in_field The name of the field
     * @param {Object
     */
    _cacheField: function(in_field, in_params) {
        // use the field cache for the elements
        if (!this.fields[in_field]) {
            this.fields[in_field] = {};
            this.fields[in_field][in_params.selectDay] = document.getElementsByName(in_field + '[' + in_params.selectDay + ']')[0];
            this.fields[in_field][in_params.selectMonth] = document.getElementsByName(in_field + '[' + in_params.selectMonth + ']')[0];
            this.fields[in_field][in_params.selectYear] = document.getElementsByName(in_field + '[' + in_params.selectYear + ']')[0];

            if (in_params.showTime) {
                if (in_params.selectHour) {
                    this.fields[in_field][in_params.selectHour] = document.getElementsByName(in_field + '[' + in_params.selectHour + ']')[0];
                }
                if (in_params.selectMinute) {
                    this.fields[in_field]['i'] = document.getElementsByName(in_field + '[i]')[0];
                }
                if (in_params.selectSecond) {
                    this.fields[in_field]['s'] = document.getElementsByName(in_field + '[s]')[0];
                }
                if (in_params.selectAmPm) {
                    this.fields[in_field][in_params.selectAmPm] = document.getElementsByName(in_field + '[' + in_params.selectAmPm + ']')[0];
                }
            }
        }
    },

    // }}}
    // {{{ getSelectedDate()

    /**
     * Gets the selected date from the given Quickform date selection
     *
     * @param  {String} in_field The name of the field
     * @return {Object} The field represented as a date object
     */
    getSelectedDate: function (in_params) {
        var field = in_params.field;
        this._cacheField(field, in_params);
        var d = this.fields[field][in_params.selectDay].value;
        var M = this.fields[field][in_params.selectMonth].value;

        if (!d || !M) {
            return null;
        }

        var date = new Date();
        date.setMonth(M - 1);
        date.setDate(d);
        date.setFullYear(this.fields[field][in_params.selectYear].value);

        // get the time
        if (in_params.showTime) {
            if (in_params.selectHour) {
                var nTime = 0;
                if (in_params.selectAmPm && 'h' == in_params.selectHour) {
                    nTime = this.fields[field][in_params.selectHour].value;
                    if ('pm' == this.fields[field][in_params.selectAmPm].value) {
                        nTime = (nTime * 1) + 12;
                    }
                }
                else if ('H' == in_params.selectHour) {
                    nTime = this.fields[field][in_params.selectHour].value;
                }
                date.setHours(nTime);
            }

            if (in_params.selectMinute) {
                date.setMinutes(this.fields[field]['i'].value);
            }

            if (in_params.selectSecond) {
                date.setSeconds(this.fields[field]['s'].value);
            }
        }

        return date;
    },

    // }}}
    // {{{ calendarSelect()

    /**
     * Changes the date in the calendars associated Quickform fields
     *
     * @param {Object} in_cal The calendar object
     */
    doSelect: function(in_cal)
    {
        var p      = in_cal.params;
        var field  = p.field;
        var date   = in_cal.date;
        var year   = date.getFullYear();
        var offset = 0;

        // offset for date and month needs to be reversed since they are never 0
        offset = p.hasEmptyOption ? 0 : 1;

        this.fields[field][p.selectDay].options[ date.getDate() - offset].selected = true;
        this.fields[field][p.selectMonth].options[ (date.getMonth() + 1) - offset].selected = true;

        var elOpts = this.fields[field][p.selectYear].options;
        for(var i = 0; i < elOpts.length; ++i) {
            if (year == elOpts[i].value) {
                elOpts[i].selected = true;
                break;
            }
        }

        // reset the offset as these can begin with 0 unlike the dates
        offset = p.hasEmptyOption ? 1 : 0;

        // set the time if it is used
        if (p.showTime) {
            if (p.selectHour) {
                var hour = date.getHours() * 1;
                if ('h' == p.selectHour) {
                    if (12 < hour) {
                        hour = hour - 12;
                    }
                    else if (0 == hour) {
                        hour = 12;
                    }
                    hour -= 1;
                }

                this.fields[field][p.selectHour].options[hour + offset].selected = true;
            }
            if (p.selectMinute) {
                this.fields[field][p.selectMinute].options[ date.getMinutes() + offset].selected = true;
            }
            if (p.selectSecond) {
                this.fields[field][p.selectSecond].options[ date.getSeconds() + offset].selected = true;
            }
            if (p.selectAmPm) {
                var hour = date.getHours() * 1;
                var nAP = 0; // am
                if (12 <= hour) {
                    nAP = 1; // pm
                }
                this.fields[field][p.selectAmPm].options[nAP + offset].selected = true;
            }
        }

        if (p.calculate) {
            // calculate the number of days (using milliseconds)
            var start_date = p.calcStartDate;

            // adding one more day ensures that we actually take into account the selected date
            var diff = parseInt(Math.abs((date.getTime() - (start_date * 1000)) / 86400000)) + 1;

            // set the days in the fields
            for(var i = 0; i < p.calcFields.length; ++i) {
                document.getElementsByName(p.calcFields[i])[0].value = diff;
            }
        }
    }
}

// }}}
// {{{ Calendar.setup

/**
 * Sets up the calendar object for the given field. If the field needs
 * to be offset to make up for empty entries at the top of the select
 * field then it needs to be specified.
 *
 * @param {Object} The configuration for the Calendar
 */
Calendar.setup = function (in_params) {
    var in_field = in_params.field;
    var el = document.getElementById(in_field + '_calendar');
    if (!el) {
        return;
    }
    el.onclick = function(e) {
        var cal = a_cals[in_field];
        var date = FF_Calendar.getSelectedDate(in_params);
        if (!a_cals[in_field]) {
            cal = a_cals[in_field] = new Calendar(0, date || null,
                in_params.onSelect || FF_Calendar.doSelect.bind(FF_Calendar),
                in_params.onClose || function(cal) { cal.hide(); });

            cal.showsOtherMonths = in_params.showOtherMonths || true;
            cal.showsTime = in_params.showTime || false;
            cal.weekNumbers = in_params.showWeekNumbers || false;

            cal.yearStep = in_params['step'] || 2;
            cal.time24 = in_params['time24'] || false;
            if (in_params.yearRange) {
                cal.setRange(in_params.yearRange[0], in_params.yearRange[1]);
            }

            cal.params = in_params;
            cal.params.field = in_field;

            cal.create();
            cal.hide();

            if (!in_params.position) {
                cal.showAtElement(this, in_params.align || 'cc');
            }
            else {
                cal.showAt(in_params.position[0], in_params.position[1]);
            }
        }
        else if (date) {
            cal.setDate(date);
        }
        cal.refresh();
        cal.show();
        return false;
    };
}

// }}}