
/*
possible init values:
    * container - html element id to add the selects/input to
    * prefix - the prefix for all field names (except input) for referencing them later, suffixes are day/month/year
    * initdate - epoch date used to initialise the calendar, todays date used if not specified
    * fieldname - the name of the hidden input, this will be the value used server side, if not given value will be 'calendar<n>'  where n is the number of the calendar on the page
    * classname - this will be the specified classname on the select elements, defaults to 'calendar' if not given
    * startyear - if you wish to restrict the year column, only years equal to or above this value will be available
    */

AWC.widget.Calendar = Class.create();

AWC.widget.Calendar.MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
AWC.widget.Calendar.DAYSINMONTH = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
AWC.widget.Calendar.DEFAULTSTARTYEAR = 1930;
AWC.widget.Calendar.DEFAULTENDYEAR = new Date().getFullYear();
AWC.widget.Calendar.COUNT = 0;

AWC.widget.Calendar.prototype = {
    initialize: function( params ) {

        this.fieldname = (params.fieldname) ? params.fieldname : 'calendar'+(++AWC.widget.Calendar.COUNT);
        this.container = params.container;
        this.prefix = params.prefix;
        this.startyear = (params.startyear) ? params.startyear : AWC.widget.Calendar.DEFAULTSTARTYEAR;
        this.endyear = (params.endyear) ? params.endyear : AWC.widget.Calendar.DEFAULTENDYEAR;
        this.classname = (params.classname) ? params.classname : 'calendar';
        this.initdate = new Date();
        if(params.initdate)
            this.initdate.setTime(params.initdate);

        if(params.onload == true)
            Event.observe(window, 'load', AWC.util.Delegate.create(this, 'render'));
        else
            this.render();
              
    },
    
    render: function() {
        var container = $(this.container);
        if(container && document.createElement && document.appendChild)
        {
            var prefix = this.prefix;
            
            /* create hidden input for storing the epoch value of the selected date */
            var input = document.createElement('input');
            input.setAttribute('type', 'hidden');
            input.setAttribute('name', this.fieldname);
            input.setAttribute('id', this.fieldname);
            container.appendChild(input);
            $(this.fieldname).value = this.initdate.getTime();
            
            var dayselect = document.createElement('select');
            dayselect['id'] = prefix+'day';
            dayselect.className = this.classname + ' ' + this.classname + 'Day';
            container.appendChild(dayselect);
            this.createDayOptions(prefix+'day', AWC.widget.Calendar.DAYSINMONTH[0]);
            
            var monthselect = document.createElement('select');
            monthselect['id'] = prefix+'month';
            monthselect.className = this.classname + ' ' + this.classname + 'Month';
            for(var i = 0; i < AWC.widget.Calendar.MONTHS.length; i++)
            {
                monthselect.options[monthselect.options.length] = new Option(AWC.widget.Calendar.MONTHS[i], i);
            }
            container.appendChild(monthselect);
            
            /* when the month is changed, we need to change the possible day options */
            Event.observe(prefix+'month', 'change', AWC.util.Delegate.create(this, 'updateDays'));
            
            var yearselect = document.createElement('select');
            yearselect['id'] = prefix+'year';
            yearselect.className = this.classname + ' ' + this.classname + 'Year';
            
            for(var i = this.endyear; i >= this.startyear; i--)
            {
                yearselect.options[yearselect.options.length] = new Option(i, i);
            }
            container.appendChild(yearselect);
            
            Event.observe(prefix+'year', 'change', AWC.util.Delegate.create(this, 'updateDays'));
            
            /* add handlers to update hidden input when any select changes */
            var obj = this;
            [prefix+'day', prefix+'month', prefix+'year'].each( function( $element ) {
                Event.observe( $($element), 'change', AWC.util.Delegate.create(obj, 'updateValue'));
            });
        }
        /* set the initial value of the calendar */
        this.setValue(this.initdate);
    },

    createDayOptions: function( dayselect, month) {
        var select = $(dayselect);
        
        var daysinmonth = AWC.widget.Calendar.DAYSINMONTH[month];
        if(month == 1) { // check if february 
        	daysinmonth = (this.isLeapYear($F(this.prefix+'year'))) ? 29 : 28;
        }
        
        /* store the current value so we can keep this value selected */
        var val = $F(dayselect);
        if(select != null)
        {
            select.options.length = 0;
            for(var i = 1; i <= daysinmonth; i++)
            {
                select.options[select.options.length] = new Option(i, i);
            }
            this.setSelectValue(select, val);
        }
    },
    
    updateDays: function() {
        var prefix = this.prefix;
        var month = $F(this.prefix+'month');
        this.createDayOptions(prefix+'day', month);
    },
    
    updateValue: function() {
        var prefix = this.prefix;
        var date = new Date();
        date.setFullYear($F(prefix+'year'), $F(prefix+'month'), $F(prefix+'day'));
        date.setHours(1 - date.getTimezoneOffset()/60); date.setMinutes(0); date.setSeconds(0); date.setMilliseconds(0);
        $(this.fieldname).value = date.getTime();
    },
    
    /* if no date is received, set to todays date */
    setValue: function( date ) {
        var initdate = (date != null) ? date : new Date();
        initdate.setHours(1 - initdate.getTimezoneOffset() / 60);

        this.setSelectValue($(this.prefix+'month'), initdate.getMonth());
        this.setSelectValue($(this.prefix+'year'), initdate.getFullYear());
        
        this.updateDays();
        
        this.setSelectValue($(this.prefix+'day'), initdate.getDate());
    },
    
    setSelectValue: function(element, value) {
        var options = $A(element.getElementsByTagName('option'));
        options.each( function( option ) {
            if(option.value == value) {
                option.selected = true;
            }
        });
    },
    
    isLeapYear: function(year) {
		return ( ((year % 400) == 0) || ( (year % 4) == 0 && (year % 100) > 0 ) );
    }
};