function create_event(sm,sd,sy,em,ed,ey,title,onclick,onmouseover, onmouseout, bgcolor){

	this.sm = sm;
	this.sd   = sd;
	this.sy  = sy;
	this.em   = em;
	this.ed     = ed;
	this.ey    = ey;
	this.title = title;
	this.onclick = onclick;
	this.onmouseover = onmouseover;	 
	this.onmouseout = onmouseout;	 

    ///////////////////////  
    // set the start date
    /////////////////////// 
    this.sdate = new Date();

    this.sdate.setFullYear( sy , sm - 1 , sd ); 
    this.sdate.setHours(3);
    this.sdate.setMinutes(0);
    this.sdate.setSeconds(0)
    this.sdate.setMilliseconds(0);

    //////////////////////  
    // set the end date
    ////////////////////// 

    this.edate = new Date();
    this.edate.setFullYear( ey ,em - 1 , ed ); 
    this.edate.setHours(3);
    this.edate.setMinutes(0);
    this.edate.setSeconds(0)
    this.edate.setMilliseconds(0);

    if(bgcolor=="")

      this.bgcolor = "lightsteelblue";

    else

      this.bgcolor = bgcolor;

    return(this);
}







function add_event(sm,sd,sy,em,ed,ey,title,onclick,onmouseover,onmouseout, bgcolor){

	if (bgcolor=="")

	bgcolor = "lightsteelblue"

	this.events[this.event_count] = new create_event(sm,sd,sy,em,ed,ey,title,onclick ,onmouseover,onmouseout, bgcolor);

	this.event_count++;

}



function show_events(){

    var this_month;	
    var day_count;
    var start_date = new Date();
    start_date.setHours(3);
    start_date.setMinutes(0);
    start_date.setSeconds(0)
    start_date.setMilliseconds(0);

    var end_date   = new Date();
    end_date.setHours(3);
    end_date.setMinutes(0);
    end_date.setSeconds(0)
    end_date.setMilliseconds(0);

    this.debug_show_map();    

    for (i=0;i<this.event_count;i++){
	      this_month=false;
	      var last_row="";
	      day_count = 0; 
	      var highest_event_count = 0;
	      var current_event;

	      ///////////////////////////////
	      // see if the event falls in
	      // month
	      ///////////////////////////////

      //////////////////////////////////////////////
      // Start or end date is in the current month
      ///////////////////////////////////////////////

      if ( ( this.month == this.events[i].sm  && this.year == this.events[i].sy ) || 
	       ( this.month == this.events[i].em  && this.year == this.events[i].ey )   ){

        //this_month = true;
      }

      //////////////////////////////////////////////
      // Start date is before this month
      // and End date is after the current month
      ///////////////////////////////////////////////

      if ( ( this.events[i].em > this.month && this.events[i].ey ==this.year  || this.events[i].ey > this.year ) &&
		   ( this.events[i].sm < this.month && this.events[i].sy == this.year || this.events[i].sy < this.year ) )  			 
	  {

	        //this_month=true;
      }


   //////////////////////////////////
   // Make a copy of this event.
   // If this is multi-week event,
   // the actual event object is 
   // broken up (dates changed) for
   // the display.  A copy is made
   // in order to preserve the
   // original data (for prev &
   // next)
   //////////////////////////////////

       current_event = new create_event(this.events[i].sm,this.events[i].sd,this.events[i].sy,this.events[i].em,this.events[i].ed,this.events[i].ey,this.events[i].title,this.events[i].onclick,this.events[i].onmouseover,this.events[i].onmouseout, this.events[i].bgcolor);

      this_month = this.is_valid_date(current_event);

      ////////////////////////////////////////////////////////////////
      // If the start date falls within the current displayable month
      // reset the start day to the first day of the month.
      ////////////////////////////////////////////////////////////////

      if (this_month && current_event.sdate.getTime() < this.first_date.getTime() ){
	    current_event.sy = this.first_date.getFullYear();
            current_event.sm = this.first_date.getMonth() + 1;
	    current_event.sd = this.first_date.getDate();
      }

      ////////////////////////////////////////////////////////////////
      // If the end date falls within the current displayable month
      // reset the end day to the last day of this month.
      ////////////////////////////////////////////////////////////////
      if (this_month && current_event.edate.getTime() > this.last_date.getTime() ){
		current_event.ey = this.last_date.getFullYear();
		current_event.em = this.last_date.getMonth() + 1;
		current_event.ed = this.last_date.getDate();
      }


	  /////////////////////////////////////////////
          // If the event day should be displayed
	  // display the event
	  /////////////////////////////////////////////	

	  if (this_month){
               //////////////////////////////////
	       // get the y position for 
	       // the current event.  We
	       // must cycle through all the
	       // days in the date range and
	       // see if the day exists in our
	       // date map
	       //////////////////////////////////		

	       start_date.setFullYear(current_event.sy,current_event.sm - 1,current_event.sd);
	       end_date.setFullYear(current_event.ey,current_event.em -1 ,current_event.ed);	
	       c=0;

           //////////////////////////
           // Assume we are not done
           //////////////////////////

	   done=false;	


	   ///////////////////////////
	   // event and determine the highest number 
	   // of events for any given day in the range.
	   //////////////////////////////////////////////

	   do{

               /////////////////////////////////////////////////////
               // If we are processing the last day of this event
               // then, this event is done.
               /////////////////////////////////////////////////////

               if ( ( start_date.getMonth()  == end_date.getMonth())  &&
                    ( start_date.getFullYear()   == end_date.getFullYear())   &&
			        ( start_date.getDate()   == end_date.getDate())   && c < 366  ){

						done=true;
		}

		month = start_date.getMonth() + 1;
		day   = start_date.getDate();
		year  = start_date.getFullYear();

	 	 ///////////////////////////
	        // Advance the current day
	       ///////////////////////////

                start_date.setTime(start_date.getTime() + 86400000);

                if (this.map[month + "_" + day + "_" + year] != null  ){

			/////////////////////////
			// check the event count
			/////////////////////////
			//////////////////////////////////
			// check if this event is in the 
			// same week as the last event
			//////////////////////////////////

			if (last_row != "" && last_row != this.map[month + "_" + day + "_" + year].row){

                if ( this.mode == 'fv') { 

                    this.show_event(current_event,highest_event_count,day_count);
                } 

				current_event.sd = day;
				current_event.sm = month;
				current_event.sy = year;

				highest_event_count = this.map[month + "_" + day + "_" + year].event_count;                        
				day_count = 0;

			} else if ( this.map[month + "_" + day + "_" + year].event_count > highest_event_count){

				highest_event_count = this.map[month + "_" + day + "_" + year].event_count;                        
			}

			last_row = this.map[month + "_" + day + "_" + year].row;

			this.map[month + "_" + day + "_" + year].event_count++;

            if ( this.mode != 'fv' ) { 

                if ( $('day_' + month + "_"+ day + "_" + year ) || $( 'day_' + month + "_"+ day + "_" + year + "_" + this.UNIQID )  )  {  

                    if ( this.UNIQID ) { 

                        $('day_' + month + "_"+ day + "_" + year + "_" + this.UNIQID ).className += ' eventqv' ; 

                        
                    //////////////////////
                    // Custom add event onclick - used for qv cals 
                    //////////////////////
                    if ( this.customEventOnclick ) { 

                        var clicking = this.customEventOnclick.replace( 'month', month ) ; 
                        clicking = clicking.replace( 'day', day ) ; 
                        clicking = clicking.replace( 'year', year ) ; 

                        if ( document.all ) { 
                            var g = document.getElementById( 'day_' + month + "_"+ day + "_" + year + "_" + this.UNIQID ); 
                            g.onclick  =   function () {  eval( clicking  ) ; }  ;   

                        } else { 
                            $('day_' + month + "_"+ day + "_" + year + "_" + this.UNIQID ).setAttribute( 'onclick',  clicking ) ; 
                        }

                    } 

                    } else { 

                        $('day_' + month + "_"+ day + "_" + year).className += ' eventqv' ; 
                    }

                    //////////////////////
                    // Custom add event onclick - used for qv cals 
                    //////////////////////
                    if ( this.customEventOnclick ) { 

                        //this.show_event(current_event,highest_event_count,day_count);

                    } 
                }
            }

			///////////////////////////
			// Increment the day count
			////////////////////////////
			day_count = day_count + 1;
		}

               c++;

	       } while(!done)

                if ( this.mode == 'fv' ) { 

                   this.show_event(current_event,highest_event_count,day_count);	       

                } 


	       }
	}
}




//////////////////////
// is_valid_date
//////////////////////

function is_valid_date(event){

      var this_month=false;	

      //////////////////////////////////////////////
      // Start date is before this month
      // and End date is after the current month
      ///////////////////////////////////////////////

      if (event.sdate.getTime() >= this.first_date.getTime() &&

	      event.sdate.getTime() <= this.last_date.getTime()    ){

	       debug ("start date within range: " + this.events[i].title);   

	      this_month = true;

      } else{

		debug("failed start date:" + this.events[i].title );

      }

      if (event.edate.getTime() >= this.first_date.getTime() &&
	      event.edate.getTime() <= this.last_date.getTime()    ){
	  
	      debug ("end date within range: " + this.events[i].title);   

	      this_month = true;

      } else{

	    debug("failed end date:" + this.events[i].title );
      }

	  
      if (event.sdate.getTime() < this.first_date.getTime() &&
	      event.edate.getTime() > this.last_date.getTime()    ){

	    this_month = true;

      } else{

	    debug("failed month span  date:" + this.events[i].title );
      }	

      return(this_month);	
}



function show_event(event,y_text_pos,day_count)
{
        int_day_box_with = parseInt(this.day_box_width);

        ///////////////////////////////
        // get the x position of the 
        // starting day of the event
        ///////////////////////////////

        x = this.map[event.sm + "_" + event.sd + "_" + event.sy].column -1;

        x = x * int_day_box_with;

        x = x + "px";

        ///////////////////////////////
        // get the y position of the 
        // starting day of the event
        ///////////////////////////////

        y = this.map[event.sm + "_" + event.sd + "_" + event.sy].row -1;

        y = y * int_day_box_with + ( ( y_text_pos + 1)  * 21);  // <- 21 should be set the height of the pixels of the event

        if ( this.header == true ) { 
            y = y + 20 +  "px";
        } else { 
            y = y  +  "px";

        }

        event_width = day_count * int_day_box_with;

        event_width = event_width + "px";

        event_obj = document.createElement('span');



        if ( document.all ) { 

                event_obj.onclick = function() {  eval( this.onclick ) ;  }  ; 

        } else { 

            event_obj.onclick = this.onclick ; 
        }

        event_obj.setAttribute('class','event');

        event_obj.setAttribute('id',this.month + "_" + event.sd + "_" + this.year);

        event_obj.setAttribute('className','event')

        event_obj.style.width=this.day_box_width;

        event_obj.style.left = x;

        event_obj.style.top=y;

        event_obj.style.width = event_width;

        //////////////////////////
        // create a text object
        // with the event title
        /////////////////////////

        text = document.createTextNode( event.title );

        event_obj.style.backgroundColor = event.bgcolor;

        event_obj.style.cursor = "pointer"; 

        if ( document.all ) { 

            event_obj.onclick  = function() {  eval( event.onclick  );  } ; 
            event_obj.onmouseover =   function() { showMouseOver( event.onmouseover ) ;  } 
                
            event_obj.onmouseout  = function () {  eval( event.onmouseout  ) ;} ; 

        } else { 
            event_obj.setAttribute('onclick',  event.onclick  ); 
            event_obj.setAttribute('onmouseover', "showMouseOver(\"" +  event.onmouseover + "\");show_balloon(event.clientX,event.clientY,'', '','','','', 'mouseOverContainer' )");
            event_obj.setAttribute('onmouseout',  event.onmouseout  );
        }

        event_obj.setAttribute("title",event.sdate + " to " + event.edate)

        event_obj.appendChild(text);

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

}



function debug_show_events(){

	for (i=0;i<this.event_count;i++){

		debug ("<p style='border: solid 1px'>event");
		debug ("start date: " + this.events[i].sm + "/" + this.events[i].sd + "/" + this.events[i].sy);
		debug ("end date: " + this.events[i].em + "/" + this.events[i].ed + "/" + this.events[i].ey);
		debug ("title: " + this.events[i].title);
		debug ("onclick: " + this.events[i].onclick);
		debug ("onmouseover: " + this.events[i].onmouseover);
		debug ("bgcolor: " + this.events[i].bgcolor);
		debug ("</p>");
	}		
}



function debug_show_map(){

  document.getElementById("debug").innerHTML="";
  for ( keyVar in this.map ) {
	   debug("Key: '" + keyVar + "'")
	   debug("month:" + this.map[keyVar].month);
	   debug("day:"   + this.map[keyVar].day);
	   debug("year:"  + this.map[keyVar].year);
	   debug("row:"   + this.map[keyVar].row);
	   debug("column:"   + this.map[keyVar].column);
	   debug("event count:"   + this.map[keyVar].event_count);
	   debug("<hr/>");
  }  	
}



function init_droppable_days(){

	for ( keyVar in this.map ) {
      debug("droppable: " + this.map.id)

/*
	 Droppables.add(this.map.id,{
    	  onDrop: function(element) { alert('test'); }
		}

		)
*/
	}
}	
