///////////////////
// Constructor
///////////////////
function calendar(name,month,year){
    //////////////
    // Methods
    /////////////  
    this.init = init_calendar;
    this.show_prev_month    = show_prev_month;
    this.show_current_month = show_current_month;
    this.show_next_month    = show_next_month;
    this.prev = prev;
    this.next = next;
    this.switchCal = switchCal; 
    this.set_day_box_dimensions = set_day_box_dimensions;
    this.add_event = add_event;
    this.show_events = show_events;
    this.show_event  = show_event;
    this.goTo  = goTo;

    this.is_valid_date = is_valid_date;
    //this.init_droppable_days = init_droppable_days;
    this.debug_show_events = debug_show_events;
    this.debug_show_map = debug_show_map;
    this.daysHeader = daysHeader; 
    this.month_txt_header_display = month_txt_header_display ; 


     ////////////////
     // Properties
     ////////////////
    this.name = name;                  // name of the div to populate the calendar
    this.month = month;                // month to display
    this.year  = year;                 // year to display
    this.master_day_count=0;           // master day count (each box)  
    this.current_month=new Date();     // current month date object
    this.prev_month = new Date();      // previous month date object
    this.prev_month_days;              // number of days displayed from the previous month
    this.next_month = new Date();      // next month_date_object
    this.day_box_width = "100px";
    this.day_box_height = "100px";
    this.map = new Array();
    this.events = new Array();
    this.event_count =0;
    this.first_date;                    // first viewable date on the calendar
    this.last_date;                     // last viewable date on the calendar
    this.onclickDay;             // last viewable date on the calendar
    this.onMouseOverDay;             // last viewable date on the calendar

    this.mode = 'fv';                   // qv or fv mode  and stuff
    this.header = true;                 // days of week header on off  
    this.daysHeaderId = 'daysHeader' ;  // id of days of week header container  - default daysHeader
    this.customOnclick;                 //  custom onclick for day boxes
    this.customEventOnclick;                 //  custom onclick for day boxes

    this.UNIQID  = false;                        //  uniq id for qv day box ids
    this.daysInMonth;
}



function set_day_box_dimensions(width,height){

  this.day_box_width = width;
  this.day_box_height = height;
        $(this.name).style.width = parseInt( width ) * 7 + 14  + 'px'; 
}



function init_calendar()
{
  this.master_day_count = 0;

  ////////////////////////////////////////  
  // set the current month calendar to 
  // the first day of the month
  //////////////////////////////////////// 
  this.current_month.setFullYear(this.year,this.month-1,1); 
  this.current_month.setHours(3);
  this.current_month.setMinutes(0);
  this.current_month.setSeconds(0)
  this.current_month.setMilliseconds(0);


  //////////////////////////////////////  
  // get the number of calendar days in
  // previous month
  //////////////////////////////////////
  this.prev_month_days=this.current_month.getDay();    
  this.prev_month.setTime(this.current_month.getTime()-(86400000 * this.prev_month_days))
  this.first_date = new Date();
  this.first_date.setTime(this.prev_month.getTime());

  //////////////////////////////////////  
  // get the number of calendar days in
  // next month
  //////////////////////////////////////
  this.next_month.setFullYear( get_next_year( this.month - 1 ,this.year) , this.month  , 1 ); 
  this.next_month.setHours(3);
  this.next_month.setMinutes(0);
  this.next_month.setSeconds(0)
  this.next_month.setMilliseconds(0);

  document.getElementById(this.name).innerHTML = "";
}




function show_prev_month()
{

  var col = 1;
  var month;
  var day;
  var year;

  //Event.unloadCache();

  if ( this.header == true ) { 

      this.daysHeader(); 

  }

  for(i=0;i<this.prev_month_days;i++)
  {  
    day = document.createElement('div');
    day.setAttribute('class','first_day');
    day.setAttribute('className','first_day')

    ///////////////////////////////
    // let the css do the styling
    ///////////////////////////////
    //day.style.width=this.day_box_width;
    //day.style.height=this.day_box_height;

    month = this.prev_month.getMonth() + 1;
    day_number   = this.prev_month.getDate();
    year         = this.prev_month.getFullYear();
    text         = document.createTextNode(day_number);


    ////////////////////
    // id for day boxes - previous days 
    ////////////////////
    did = 'day_' + month + "_" + day_number + "_" + year;

    if ( this.UNIQID ) { 

      did = did + "_" + this.UNIQID;

    }

    day.setAttribute('id', did ); 

    if (this.onclickDay!="" && this.onclickDay!=undefined  ){

      day.setAttribute('onClick',this.onclickDay + "('" + did + "')");

    }


    day.appendChild(text);

    document.getElementById(this.name).appendChild(day);

    /////////////////////////////////////
    // Add this day to the calendar map
    /////////////////////////////////////

    this.map[month + "_" + day_number + "_" + year] = new create_map_day(month,day_number,year,1,col);

    col++;

    this.prev_month.setTime(this.prev_month.getTime() + 86400000);

    this.master_day_count++;

 }  

}



function show_current_month( )
{


 ///////////////////////////
 //  Todays date 
 //////////////////////////
var currDate = new Date(); 

var thisDay =  currDate.getDate(); 
var thisMonth = currDate.getMonth() + 1; 
var thisYear = currDate.getFullYear(); 


  var classname;
  var day_number=1;
  var row = 1;
  var col = this.prev_month_days;

  ////////////////////////////////////////////////////
  // Iterate this loop while the current month
  // is the same month number matches the current 
  // month.  That is, we are not processing days for
  // next month
  /////////////////////////////////////////////////////     

  while(this.current_month.getMonth()==(this.month-1))
  {
    ////////////////////////////////////////////////////////
    // increment the row number, if we have displayed the 
    // the last day of the week.
    ///////////////////////////////////////////////////////

    if (this.master_day_count % 7 == 0 && this.master_day_count != 0)
    {
    row++;  
    col=1;
     }else{
    col++;

     }

    this.column = this.master_day_count % 7;
    temp = this.master_day_count % 6;

    ///////////////////////////////
    // Set a default class
    // and then change it if
    // the day falls on the first
    // or last day of the week
    //////////////////////////////

    classname="middle_day";

    if ( col == 0 ) classname='first_day'
  if ( col == 7 ) classname='last_day'

     /////////////////////////////////////////
    // Create the day element and add styles
    /////////////////////////////////////////

    day = document.createElement('div');

    ////////////////////////
    // day box id for current month 
    ////////////////////////
    day.id = 'day_' + this.month + "_" + day_number + "_" + this.year;

    day.setAttribute('class',classname);

    day.setAttribute('className',classname);

    ////////////////////////
    // day box id for current month 
    ////////////////////////
    did = 'day_' + this.month + "_" + day_number + "_" + this.year;

    if ( this.UNIQID ) { 

      did = did + this.year;

    }

    if ( (  this.month == thisMonth ) && ( day_number == thisDay ) && ( this.year == thisYear ) ) {  

            day.className += " today"; 

    }


/***********
    if ( this.onclick ==  true) {


        if ( document.all ) { 

            day.onclick = function () {
                var splitDate  = this.id.split("_"); 
                hide_balloon(); show_quick_add(event.clientX,event.clientY, null,'DESC_POPUP ',splitDate[1] , splitDate[2] , splitDate[3] ); 
            }; 

        } else { 

            day.setAttribute('onclick',"hide_balloon(); show_quick_add(event.clientX,event.clientY, null,'DESC_POPUP '," + this.month + "," + day_number + "," + this.year + ")" );
        }

    } else if ( this.onclick == 'custom'  && this.customOnclick.length )   { 
        ///////////////////////
        //  Custom onclicks 
        ///////////////////////

        // parse tokens - month day year 
        var cOnclick =this.customOnclick.replace('month', this.month ) ;  
        cOnclick =cOnclick.replace('day', day_number ) ;  
        cOnclick =cOnclick.replace('year', this.year ) ;  

        if ( document.all ) { 

            day.onclick = function() {  eval( cOnclick );} ; 

        } else { 

            day.setAttribute('onclick', cOnclick ) ; 

        }

    } 
***********/

    //////////////////////////////////////////////////
    // remove the hard setting  of width and height
    // 10/10/2007 - klee
    //////////////////////////////////////////////////
    //day.style.width  = this.day_box_width;
    //day.style.height = this.day_box_height;
    text = document.createTextNode(day_number);

    ///////////////////////////////////////////////////////
    // Here is where we should set the day number styles
    ///////////////////////////////////////////////////////

    //text.setAttribute('className',"day_number_text");

    day.appendChild(text)

    /////////////////////////////////
    // Add the day div to the page
    //////////////////////////////////

    document.getElementById(this.name).appendChild(day);

    if (this.onclickDay!="" && this.onclickDay!=undefined){

      temp = this.onclickDay;
      
      Event.observe( did, 'click', function(event){ eval( temp+"('"+Event.element(event).id+"')" );});

    }

    ////////////////////////////////////////////
    // Add this day to the calendar map
    //
    // The calendar map maintains the physical
    // location and event information for each
    // day.  This is where the entry is created.
    //
    // this.map is an associative array that 
    // is made up of day objects
    /////////////////////////////////////////////

    this.map[this.month + "_" + day_number + "_" + this.year] = new create_map_day(this.month,day_number,this.year,row,col,this.current_month.getTime());

    //////////////////////////////
    // Advance the current month
    //////////////////////////////  

    this.master_day_count++;      

    day_number++;      

    this.current_month.setTime(this.current_month.getTime() + 86400000);
  }  
   this.last_row = row;
}





function show_next_month()
{
  var col;
  var dcount = 7 - this.next_month.getDay();
  var month;
  var year;
  var text;
  col = this.next_month.getDay() + 1;

  if (dcount == 7){
    this.last_row++ ;      

  }

  for( i = 0 ; i < dcount ;i++)
  {  
    day = document.createElement('div');
    classname = "next_month_day";
    if ( (i+1) == dcount ){
    classname = "next_month_last_day";
  }

    day.setAttribute('class',classname);
    day.setAttribute('className',classname);

    ///////////////////////////////
    // let the css do the styling
    ///////////////////////////////
    //day.style.width=this.day_box_width;
    //day.style.height=this.day_box_height;

    month = this.next_month.getMonth() + 1;
    day_number   = this.next_month.getDate();
    year         = this.next_month.getFullYear();
    text         = document.createTextNode(day_number);



    ///////////////////////////////
    // day box id for next month 
    ///////////////////////////////
    did = 'day_' + month + "_" + day_number + "_" + year;

    if ( this.UNIQID ) { 

      did = did + "_" + this.UNIQID;

    }
             
    day.setAttribute( 'id', did ) ; 

    day.appendChild(text);

    document.getElementById(this.name).appendChild(day);

    if (this.onclickDay!="" && this.onclickDay!=undefined  ){

      day.setAttribute('onClick',this.onclickDay + "('" + did + "')");

    }
    /////////////////////////////////////
    // Add this day to the calendar map
    /////////////////////////////////////


    this.map[month + "_" + day_number + "_" + year] = new create_map_day(month,day_number,year,this.last_row,col);

    col++;

    this.next_month.setTime(this.next_month.getTime() + 86400000);
    this.master_day_count++;
 }  

  this.next_month.setTime(this.next_month.getTime() - 86400000);
  this.last_date = this.next_month;

}



/**
  * Display the prev month
  *
  * Tie this function to a 
  * a form element which will
  * display the prev month
  */
function prev()
{
  original_month = this.month;
  this.month = get_prev_month(original_month);
  this.year = get_prev_year(original_month,this.year);

  document.getElementById(this.name).innerHTML = "";

    this.init();
  this.show_prev_month();
  this.show_current_month();
    this.show_next_month();
    this.show_events(); 


    var x = [ this.month, this.year] ; 
    return x; 
}


// go to specific calendar 
function switchCal(month, year ) { 

   this.month = month -1; 
   this.year = year; 
   this.name = 'newcal'; 

   this.next(); 
   return x; 
}



/**
  * Display the next month
  *
  * Tie this function to a 
  * a form element which will
  * display the next month
  */
function next()
{
    original_month = this.month ;
    this.month = get_next_month(original_month);
    this.year = get_next_year(original_month,this.year);

    document.getElementById(this.name).innerHTML = "";

    this.init();
    this.show_prev_month();
    this.show_current_month();
    this.show_next_month();
    this.show_events();     

    var x = [this.month, this.year]; 

    return  x;
}

/**
  * Display any month passed in
  *
  * Tie this function to a 
  * a form element which will
  * display and passed month
  */
function goTo(month,year)
{
    original_month = this.month ;

    this.month = month;

    this.year = year;

    document.getElementById(this.name).innerHTML = "";

    this.init();

    this.show_prev_month();

    this.show_current_month();

    this.show_next_month();

    this.show_events();     

    var x = [this.month, this.year]; 

    return  x;
}




function create_map_day(month,day,year,row,column){

  this.month  = month;
  this.day    = day;
  this.year   = year;
  this.row    = row;
  this.column = column;
  this.event_count =0;

        return(this);  
}



//////////////////
//displays new 
//////////////////
function month_txt_header_display ( txt, id )
{
    $(id).innerHTML = monthsList[txt[0]] + ' '  + txt[1]; 

}


//setup the  header that list days 
// trys to position in middle
function daysHeader() 
{

    var parentDiv = $( this.daysHeaderId ); 
    parentDiv.innerHTML = ''; 
    var days; 
    for ( var i = 0 ; i < 7 ; ++i ) { 
        days = document.createElement('div' ) ; 
        days.style.width  = this.day_box_width; 

        if ( document.all ) { 
            days.className =  'days_of_week'; 

        } else { 

            days.setAttribute( 'class' , 'days_of_week'); 
        }

        days.innerHTML = daysText[i]; 
        parentDiv.appendChild( days ) ; 
    }
}


/*////////////////////////////////////////////////////////////////////////////////////////
// function populateSelectBox(monthID, yearID)
// Anthony Carcelli: 10.11.2007
//
// The functions below only need to be supplied with an appropriate id for the select
// boxes representing month and year <select id="...">.  These should be set globally on
// the page so they can be plug and play in the date and month select dropdown boxes
// onclick as well.  When you change month or year, days have to be recalculated.
// First function fills the years dropdown.  populateSelectBox adds the days.
// The months select box is not populated here at this time.
////////////////////////////////////////////////////////////////////////////////////////*/
// create dynamic list of year choices

function fillYears(monthID, yearID, postYear, hasMonth) {
    var today = new Date();
    var thisYear = postYear;
    var yearChooser = $(yearID);
    var counter=0;
    
    for (i = thisYear - 5 ; i <= thisYear + 5; i++) {
        yearChooser[counter] = new Option(i,i);
        if (i == thisYear) { 
           yearChooser.selectedIndex = counter;
        }
      counter++;
    }

    if (!hasMonth) setCurrMonth(today, monthID)
}
// set month choice to current month
function setCurrMonth(today, monthID) {
    $(monthID).selectedIndex = today.getMonth();
}

function populateSelectBox(monthID, yearID, dayID, isInit, hasDay) {
    var today = new Date();
    var theMonth = $(monthID).selectedIndex
    var theDay = $(dayID).selectedIndex
    var theYear = ( $(yearID).selectedIndex == -1 )? today.getFullYear() : parseInt( $(yearID).options[$(yearID).selectedIndex].text );
    // initialize date-dependent variables
    var howMany = getMonthLen(theYear, theMonth)

    for (var i = 1; i < howMany+1; i++) {
      $(dayID)[i-1] =  new Option(i, i);
    }

    $(dayID).selectedIndex = (isInit == 1 && !hasDay)? today.getDate()-1: hasDay-1 ;
    
    if(popup_calendar) {
      popup_calendar.month = theMonth;
      popup_calendar.year = theYear;
      popup_calendar.next();
      updateHeader(popup_calendar);
    }
}

// number of days in the month
function getMonthLen(theYear, theMonth) {
    var oneDay = 1000 * 60 * 60 * 24
    var thisMonth = new Date(theYear, theMonth, 1)
    var nextMonth = new Date(theYear, theMonth + 1, 1)
    var len = Math.ceil((nextMonth.getTime() - thisMonth.getTime())/oneDay)
    return len
}

////////////////////// End Required Dropdown selects ////////////////////////////////////////////////

