/**
 * FormDate Object
 * 
 * Dependancies:
 *    - Date.js
 *    - Calendar.js
 *    - DatePicker.js
 * 
 * @author Michael Mifsud
 * @package javascript
 */



/**
 * A wrapper around a DatePicker object to allow the DatePicker
 *  to interact with a form that is in the below format.
 * 
 * The form element must be in the form of:
 * <code>
 *   <form name="form_1" method="POST">
 *     <select name="dateFrom_month">
 *       <option value="2006-12">Dec</option>
 *       <option value="0" class="shade">&nbsp;&nbsp;2007</option>
 *       ...
 *     </select>
 *    
 *     <select name="dateFrom_day">
 *       <option value="1" selected>1</option>
 *       ...
 *     </select>
 *     
 *     <span id="form_1_formDateIcon" />
 *     
 *     <script language="javascript">
 *       var formDate = new FormDate('formDate', document.form_1, 'dateFrom');
 *     </script>
 * </code>
 * 
 * The 'dateFrom' in the element name is the what is passed as param 2 (elementName).
 * The Icon is pre-pended
 * 
 * 
 * 
 * @param string objName     - the form object
 * @param DOMElement form    - the form object
 * @param string elementName - The prepended name of the form elements
 */
FormDate.Extends(DatePicker);
function FormDate(objName, form, elementName) 
{
    
    this.DatePicker(objName, objName+'.callback');      // parent::__construct
    this.imgIcon   = arguments[3] != null ? arguments[3] : 'images/blank.gif';
    
    this.form               = form;
    this.yearSelect         = form[elementName+'_year']
    this.monthSelect        = form[elementName+'_month'];
    this.daySelect          = form[elementName+'_day'];
    
    // __construct
    this.update();
    this.init();
    
    
    //__construct
    // Add update events to the elements
    this.yearSelect.setAttribute('onChange', this.objName+'.update();');
    this.monthSelect.setAttribute('onChange', this.objName+'.update();');
    this.daySelect.setAttribute('onChange', this.objName+'.update();');
    // Set up default icons.
    var iconId = this.form.id+'_'+elementName+'Icon';
    
    this.writeIconDOM(getElementById(iconId));
}



/**
 * Set the dateFrom and DateTo boundary based on the month select option
 * 
 */
FormDate.prototype.init = function() {
    var year, month, day;
    
    // dateFrom
    year = parseInt(this.yearSelect.options[0].value, 10);
    month = parseInt(this.monthSelect.options[0].value, 10)-1;
    day = 1;
    this.dateFrom = new Date(year, month, day, 12, 0, 0);
    
    
    // dateTo
    year = parseInt(this.yearSelect.options[this.yearSelect.options.length-1].value, 10);
    month = parseInt(this.monthSelect.options[this.monthSelect.options.length-1].value, 10)-1;
    this.dateTo = new Date(year, month, 1, 12, 0, 0);
    day = this.dateTo.getDaysInMonth(month);
    this.dateTo = new Date(year, month, day, 12, 0, 0);
    
}

/**
 * Override the show method to put in an auto update call to this object
 * 
 * 
 * @param integer month - (optional) Where 0 = jan, 11 = dec.
 * @param integer year  - (optional) Where in format of 2005.
 * @param integer day   - (optional) Month date 1-31
 */
FormDate.Override(DatePicker, 'show');
FormDate.prototype.show = function() {
    var year  = arguments[0] != null ? arguments[0] : this.selectedDate.getFullYear();
    var month = arguments[1] != null ? arguments[1] : this.selectedDate.getMonth();
    var day   = arguments[2] != null ? arguments[2] : this.selectedDate.getDate();
    
    // Update this calendars selected dates from the form
    this.update();
    this.DatePicker_show(year, month, day);
}

/**
 * Update the calendar date from the form values.
 * 
 * Note: Update takes data from the form elements and 
 *       populates the DatePicker object
 */
FormDate.prototype.update = function() {
    // Set this calendar's date from the form
    year = parseInt(this.yearSelect.options[this.yearSelect.selectedIndex].value, 10);
    month = parseInt(this.monthSelect.options[this.monthSelect.selectedIndex].value, 10)-1;
    day = parseInt(this.daySelect.options[this.daySelect.selectedIndex].value, 10);
    
    this.setSelectedDate(new Date(year, month, day, 12, 0, 0));
    this.initDaySelect();
}

/**
 * This is the callback method called by the DatePicker
 * 
 * Note: The callback function take data from the DatePicker
 *       object and populates the form elements.
 * @param integer year  - 
 * @param integer month - 
 * @param integer day   - 
 */
FormDate.prototype.callback = function(year, month, day) {
    this.setSelectedDate(new Date(year, month, day, 12, 0, 0));
    this.initDaySelect();
    
    // Set the forms selected values
    var yearIdx = this.getSelectedIndex(this.yearSelect, year);
    this.yearSelect.options[yearIdx].selected = true;
    this.monthSelect.options[month].selected = true;
    this.daySelect.options[day-1].selected = true;
}

/**
 * Init the day select to contain the correct day values and
 *  include the day name in the dropdown options. (eg "Tue 3")
 *   
 */
FormDate.prototype.initDaySelect = function () {
    var date = this.selectedDate;
    var selectedIdx = this.daySelect.selectedIndex;
    
    var options = Array();
    var newDate = date.clone();
    for(var i = 1; i <= date.getDaysInMonth(); i++) {
        newDate.setDate(i);
        //options[i-1] = new Option(newDate.getDayAbbreviation() + " " + i, i);
        stri = this.getIntegerStr(i);
        options[i-1] = new Option(stri, stri);
    }
    FormDate.setSelectOptions(this.daySelect, options);
    this.daySelect.options[selectedIdx].selected = true;
}

/**
 * Find the selected index of a value in  the select element
 * 
 * @param DOMElement monthSelect - The select element to search
 * @param string str - The value to search for
 * @return integer - defaults to 0 if not found.
 */
FormDate.prototype.getSelectedIndex = function(select, str) {
    var i = 0;
    while( (i < select.options.length) && (select.options[i].value != str) ) {
        i++;
    }
    // check if option found!
    if (!select.options[i] || select.options[i].value != str) {
        return 0;
    }
    return i;
}

/**
 * Convert an integer into a 2 digit string with leading 0's
 * 
 * @param integer value - 
 */
FormDate.prototype.getIntegerStr = function(value) {
    if (value < 10) {
        return "0" + value;
    }
    return value + "";
}

/**
 * Set the text color of the form elements
 * 
 * @param string color - Hex color (eg: 'FFFFFF', '0CC', etc)
 */
FormDate.prototype.setColor = function(color) {
    this.yearSelect.style.color = color;
    this.monthSelect.style.color = color;
    this.daySelect.style.color = color;
}




//////////////////////  STATIC  //////////////////////


/**
 * Fill a select element with an array of supplied option objects.
 * 
 * Notes: 
 *  o If selected is not defined the first element is selected
 * 
 * @param DOMElement select - The select form element
 * @param array options - The array of new options
 * @param integer selected - (optional) The selected element
 */
FormDate.setSelectOptions = function(select, options) {
    // The optional argument selected?
    var selected = arguments[2] ? arguments[2] : 0; //options.length-1;
    
    FormDate.clearSelectOptions(select);
    i = 0;
    for (i = 0; i < options.length; i++) {
        select.options[i] = options[i];
    }
    select.options[selected].selected = true;
    
    return select;
}

/**
 * Clear a select element.
 * 
 * @param DOMElement select - The form select element
 */
FormDate.clearSelectOptions = function(select) {
	  for (i = select.options.length-1; i >= 0; i--) {
        select.options[i] = null;
    }
}
