/**
 * @file
 * @author Shannon M. Rause <shannon.rause@creativeflavor.com>
 * @version $Revision: 1.19 $
 * @version $Name: CREATIVEFLAVOR_2010-07-25_71 $
 * @version $Id: Calendar.js,v 1.19 2008/02/07 20:30:59 smr Exp $
 *
 * These files are copyrighted to Creative Flavor Inc. and are
 * subject to the terms of the applicable Service Agreement.
 * If no service agreement is available you must contact us at
 * legal@creativeflavor.com or 303-379-9450.
 * 
 * These files may be watermarked to ensure traceability.
 */
/**
 * Calendar class.
 *
 * @public
 */
function Calendar()
{
} // Calendar


Calendar._allowPast = false;
Calendar._autoHideDate = true;
Calendar._cmdName = null;
Calendar._dateControl = null;
Calendar._day = null;
Calendar._firstMonth = 0;
Calendar._firstYear = 0;
Calendar._lastMonth = 0;
Calendar._lastYear = 0;
Calendar._month = null;
Calendar._year = null;


/**
 * Hides date fields (for IE bug).
 *
 * @public
 */
Calendar.hideDateFields = function()
{
   if ((!Calendar._autoHideDate) ||
       (!Calendar._dateControl))
   {
      return;
   } // if

   var temp = new Array(
      'Day',
      'Hour',
      'Meridian',
      'Minute',
      'Month',
      'Second',
      'Year'
   );

   for (var i in temp)
   {
      var elem = document.getElementById(Calendar._dateControl + temp[i]);

      if (elem)
      {
         elem.style.visibility = 'hidden';
      } // if
   } // for
} // hideDateFields 


/**
 * Loads the popup calendar's grid.
 *
 * @param year          Year.
 * @param month         Month.
 * @param day           Day.
 * @param dateControl   Date control to update (null/undefined for none).
 * @param autoHideDate  true to auto hide the date when calendar is visible
 *                         (usually needed b/c of IE bug).
 * @param cmdName       Name of command to execute to get grid info
 *                         (null/undefined for none).
 * @param allowPast     true/1 to allow days in past to be clicked,
 *                         false/0/undefined/null to not.
 * @param firstYear     First allowable year (null/undefined for none).
 * @param firstMonth    First allowable month (null/undefined for none).
 * @param lastYear      Last allowable year (null/undefined for none).
 * @param lastMonth     Last allowable month (null/undefined for none).
 *
 * @public
 */
Calendar.loadPopupCalGrid = function(year,
                                     month,
                                     day,
                                     dateControl,
                                     autoHideDate,
                                     cmdName,
                                     allowPast,
                                     firstYear,
                                     firstMonth,
                                     lastYear,
                                     lastMonth)
{
   if ((dateControl != null) && (dateControl != undefined))
   {
      Calendar._dateControl = dateControl;
   } // if
   else
   {
      dateControl = Calendar._dateControl;
   } // else

   if ((autoHideDate != null) && (autoHideDate != undefined))
   {
      Calendar._autoHideDate = autoHideDate;
   } // if
   else
   {
      autoHideDate = Calendar._autoHideDate;
   } // else


   // hide all date control fields (due to IE bug).
   Calendar.hideDateFields();


   // hide close link and show loading.
   document.getElementById('popupCalClose').style.display = 'none';
   document.getElementById('popupCalLoad').style.display = 'inline';


   // get or set current values depending on whether they were given
   // to the function.
   if ((year != null) && (year != undefined))
   {
      Calendar._year = year;
   } // if
   else if ((Calendar._year == null) && (dateControl != null))
   {
      year = document.getElementById(dateControl + 'Year').value;
      Calendar._year = year;
   } // else if
   else
   {
      year = Calendar._year;
   } // else

   if ((month != null) && (month != undefined))
   {
      Calendar._month = month;
   } // if
   else if ((Calendar._month == null) && (dateControl != null))
   {
      month = document.getElementById(dateControl + 'Month').value;
      Calendar._month = month;
   } // else if
   else
   {
      month = Calendar._month;
   } // else

   if ((day != null) && (day != undefined))
   {
      Calendar._day = day;
   } // if
   else if ((Calendar._day == null) && (dateControl != null))
   {
      day = document.getElementById(dateControl + 'Day').value;
      Calendar._day = day;
   } // else if
   else
   {
      day = Calendar._day;
   } // else


   if ((cmdName != null) && (cmdName != undefined))
   {
      Calendar._cmdName = cmdName;
   } // if
   else
   {
      cmdName = Calendar._cmdName;
   } // else


   if ((allowPast != null) && (allowPast != undefined))
   {
      Calendar._allowPast = allowPast;
   } // if


   if ((firstYear != null) && (firstYear != undefined))
   {
      Calendar._firstYear = firstYear;
   } // if

   if ((firstMonth != null) && (firstMonth != undefined))
   {
      Calendar._firstMonth = firstMonth;
   } // if


   if ((lastYear != null) && (lastYear != undefined))
   {
      Calendar._lastYear = lastYear;
   } // if

   if ((lastMonth != null) && (lastMonth != undefined))
   {
      Calendar._lastMonth = lastMonth;
   } // if


   // execute command, if necessary.
   // note that the popup will finish the calendar load.
   if (cmdName)
   {
      var data = {
         'year'         : year,
         'month'        : month,
         'day'          : day,
         'dateControl'  : dateControl
      };

      Core.ajaxSendCommand(cmdName,
                           { 'month' : month, 'year' : year },
                           Calendar._popupCalLoadCallback,
                           data);
   } // if
   else
   {
      Calendar._finishCalPopupLoad(year,
                                   month,
                                   day,
                                   dateControl)
   } // else
} // loadPopupCalGrid


/**
 * Loads the next month's popup calendar grid.
 *
 * @public
 */
Calendar.loadNextPopupCalGrid = function()
{
   // determine if its ok to change.
   if (Calendar._nextOk())
   {
      Calendar._month++;

      if (Calendar._month > 12)
      {
         Calendar._year++;
         Calendar._month = 1;
      } // if
   } // if


   // load the grid.
   Calendar.loadPopupCalGrid();
} // nextPopupCalGrid


/**
 * Loads the next month's popup calendar grid.
 *
 * @public
 */
Calendar.loadPrevPopupCalGrid = function()
{
   // determine if its ok to change.
   if (Calendar._prevOk())
   {
      Calendar._month--;

      if (Calendar._month < 1)
      {
         Calendar._year--;
         Calendar._month = 12;
      } // if
   } // if


   // load the grid.
   Calendar.loadPopupCalGrid();
} // prevPopupCalGrid


/**
 * sHOWS date fields (for IE bug).
 *
 * @public
 */
Calendar.showDateFields = function()
{
   if ((!Calendar._autoHideDate) ||
       (!Calendar._dateControl))
   {
      return;
   } // if

   var temp = new Array(
      'Day',
      'Hour',
      'Meridian',
      'Minute',
      'Month',
      'Second',
      'Year'
   );

   for (var i in temp)
   {
      var elem = document.getElementById(Calendar._dateControl + temp[i]);

      if (elem)
      {
         elem.style.visibility = '';
      } // if
   } // for
} // showDateFields


/**
 * Changes the date control values based on what the user has clicked.
 * 
 * @param day  Day clicked on.
 *
 * @private
 */
Calendar._changeDateControl = function(day)
{
   var elem = document.getElementById(Calendar._dateControl + 'Year');

   if (elem)
   {
      elem.value = Calendar._year;
   } // if

   elem = document.getElementById(Calendar._dateControl + 'Month');

   if (elem)
   {
      elem.value = Calendar._month;

      // in case months are setup as two-digit.
      if (parseInt(Calendar._month) < 10)
      {
         elem.value = '0' + Calendar._month;
      } // if
   } // if

   elem = document.getElementById(Calendar._dateControl + 'Day');

   if (elem)
   {
      elem.value = day;

      // in case days are setup as two-digit.
      if (parseInt(day) < 10)
      {
         elem.value = '0' + day;
      } // if
   } // if
} // _changeDateControl


/**
 * Finishes the calendar popup load.
 *
 * @param year          Year.
 * @param month         Month.
 * @param day           Day.
 * @param dateControl   Date control to update (null/undefined for none).
 * @param days          Days from command (null/undefined for none).
 *
 * @private
 */
Calendar._finishCalPopupLoad = function(year,
                                        month,
                                        day,
                                        dateControl,
                                        days)
{
   // update prev/next links.
   if (Calendar._prevOk())
   {
      document.getElementById('popupCalPrev').style.display = 'inline';
   } // if
   else
   {
      document.getElementById('popupCalPrev').style.display = 'none';
   } // else

   if (Calendar._nextOk())
   {
      document.getElementById('popupCalNext').style.display = 'inline';
   } // if
   else
   {
      document.getElementById('popupCalNext').style.display = 'none';
   } // else


   // current date (or whatever is selected in cal).
   var dt;

   if (dateControl)
   {
      var curYear = document.getElementById(dateControl + 'Year').value;
      var curMonth = document.getElementById(dateControl + 'Month').value;
      var curDay = document.getElementById(dateControl + 'Day').value;
   } // if
   else
   {
      dt = new Date();
      var curYear = dt.getFullYear();
      var curMonth = dt.getMonth() + 1;
      var curDay = dt.getDate();
   } // else


   // title.
   dt = new Date(year,
                 month - 1,
                 1,
                 12,
                 0,
                 0,
                 0);
   var elem = document.getElementById('popupCalTitle');
   Utils.removeChildren(elem);
   elem.appendChild(document.createTextNode(Utils.getMonthString(dt.getMonth() + 1) + ' ' + dt.getFullYear()));


   // update the grid.
   var d = 1;
   var start = dt.getDay();
   var end = Utils.getDaysInMonth(year,
                                  month);
   var monthInPast = ((year < curYear) || ((month < curMonth) && (year == curYear)));
   var show5 = false;
   var show6 = false;
   
   for (var j = 0; j < 42; j++)
   {
      elem = document.getElementById('popupCalCell' + j);
      elem.className = '';
      Utils.removeChildren(elem);

      if ((j < start) ||
          (d > end))
      {
         elem.appendChild(document.createTextNode('\u00A0'));
      } // if
      else
      {
         if (j > 27)
         {
            show5 = true;
         } // if

         if (j > 34)
         {
            show6 = true;
         } // if

         var action = '';
         
         if ((!monthInPast) && (month == curMonth) && (d == curDay))
         {
            elem.className = 'cellCurrent';
         } // if

         if ((!Calendar._allowPast) &&
             ((monthInPast) || ((month == curMonth) && (year == curYear) && (d < curDay))))
         {
            elem.className = 'cellPast';
         } // if
         else if ((days) &&
                  (days[d]))
         {
            if (days[d]['action'])
            {
               action = days[d]['action'] + ';';
            } // if

            if (parseInt(days[d]['updateDate']))
            {
               action += 'Calendar._changeDateControl(' + d + ');';
            } // if

            if (parseInt(days[d]['close']))
            {
               action += "Calendar.showDateFields();Popup.hide('popupCal');";
            } // if

            if (action)
            {
               elem.className = 'cellAvail';
            } // if
            
            if (days[d]['class'])
            {
               elem.className = days[d]['class'];
            } // if
         } // if
         else if (dateControl)
         {
            action = "Calendar._changeDateControl(" + d + ");Calendar.showDateFields();Popup.hide('popupCal');";
         } // else if

         if (action)
         {
            var a = document.createElement('a');
            a.setAttribute('href',
                           'javascript:' + action + 'void(0);');
            a.setAttribute('onfocus',
                           'this.blur();');
            elem.appendChild(a);

            a.appendChild(document.createTextNode(d));
         } // if
         else
         {
            elem.appendChild(document.createTextNode(d));
         } // else

         d++;
      } // else
   } // for

   if (show5)
   {
      document.getElementById('popupCalGridRow5').style.display = '';
   } // if
   else
   {
      document.getElementById('popupCalGridRow5').style.display = 'none';
   } // else

   if (show6)
   {
      document.getElementById('popupCalGridRow6').style.display = '';
   } // if
   else
   {
      document.getElementById('popupCalGridRow6').style.display = 'none';
   } // else


   // hide load link and show close.
   document.getElementById('popupCalLoad').style.display = 'none';
   document.getElementById('popupCalClose').style.display = 'inline';
} // _finishCalPopupLoad


/**
 * Determines if its ok to go to the next month.
 *
 * @return true if ok, false if not.
 *
 * @private
 */
Calendar._nextOk = function()
{
   return ((!Calendar._lastMonth) || (!Calendar._lastYear) || (Calendar._year < Calendar._lastYear) || ((Calendar._month < Calendar._lastMonth) && (Calendar._year == Calendar._lastYear)));
} // _nextOk


/**
 * Callback for a calendar load command response.
 *
 * @param obj     Response object.
 * @param data    Callback data.
 * @param status  HTTP status of response (e.g. 200).
 * @param reason  Status text of response (e.g. OK).
 *
 * @private
 */
Calendar._popupCalLoadCallback = function(obj,
                                          data,
                                          status,
                                          reason)
{
   if ((obj) &&
       (data))
   {
      Calendar._finishCalPopupLoad(data.year,
                                   data.month,
                                   data.day,
                                   data.dateControl,
                                   obj.days)
   } // if
} // _popupCalLoadCallback


/**
 * Determines if its ok to go to the previous month.
 *
 * @return true if ok, false if not.
 *
 * @private
 */
Calendar._prevOk = function()
{
   return ((Calendar._allowPast) || (!Calendar._firstMonth) || (!Calendar._firstYear) || (Calendar._year > Calendar._firstYear) || ((Calendar._month > Calendar._firstMonth) && (Calendar._year == Calendar._firstYear)));
} // _prevOk
