
Af.BaseCalendar = Class.create();

Af.BaseCalendar.prototype = {

	initialize: function() {
	   this.days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
	   this.months = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];
	   this.daysLong = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
	   this.monthsShort = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
	   this.schedules = null;
	   this.dateUtil = new Af.DateUtil();	   
	   this.evtObj = new Object();
	   this.actualDate = null;
	},

	tableClicked: function(ev) {
	   var eventTarget = ev.target ? ev.target : ev.srcElement;
	   if (eventTarget.tagName == 'A' && eventTarget.id != null) {
	      if (eventTarget.id.indexOf("E_") == 0) {
	         this.eventDetailView(eventTarget.id, eventTarget.name);
	         return false;
	      }
	      try {
			var l = parseInt(eventTarget.id);
			var dt = new Date(l);
			dt.setHours(0,0,0,0);
			this.listener.dateClicked(this, dt);
		  } catch (e) {};
	   }
	   return false;
	},
	
	scheduleListChanged: function(schedules) {
	   this.render(schedules, this.date);
	},
	
	getEventLink: function(sc, scindex, event, eventindex) {
	   var bc;
	   var isDriver = false;
	   if (sc.UUID != event["scheduleId"] && (sc.UUID == event["driver1"] || sc.UUID == event["driver2"])) {
	     var schedules = app.workspace["schedule"];
	     var sc2 = findObjById(schedules, event["scheduleId"]);
	     if (sc2 == null) {
	        bc = sc["color"];
	     } else {
	        bc = sc2["color"];
	        isDriver = true;
	     }
	   } else {
	      bc = sc["color"];
	   }
	   if (isDriver) {
	      c = "#c2c2c2";
	      bc = "#f2f2f2";
	   } else {
          var c = getTextColor(bc);
          bc = getBackground(bc);
       }
       if (sc.sharing == "FREE_TIME") {
           var a = document.createElement('span');
		   if (bc != null) {
			  a.style.backgroundColor = bc;
		   }
		   if (c != null) {
			  a.style.color = c;
		   }
          a.innerHTML = get_nbsp(event.displayName);
          a.style.margin = "0 -2px";
          a.id = "E_" + scindex + "_" + eventindex;
          return a;
       } else {
		   var a = document.createElement('a');
		   if (bc != null) {
			  a.style.backgroundColor = bc;
		   }
		   if (c != null) {
			  a.style.color = c;
		   }
		   a.href = "#";
		   a.innerHTML = event.displayName;
		   a.id = "E_" + scindex + "_" + eventindex;
           a.style.cursor = "move";

		   this.evtObj[a.id] = event;

		   if (is_ie || is_ie7) {
			 a.onmouseover = this.showToolTip.bindAsEventListener(this);
		   } else {
			 var dispMsg = "";
			 dispMsg += event.displayName; 			
			 if(event.locationName != null) {
				 dispMsg += "<br/><b> Location:</b> " + event.locationName;
			 }			
			 if(event.noTimeFlag != null && "true" == trim("" + event.noTimeFlag)){
				 dispMsg += "<br/><b>Time:</b> " + "No " + "  " + "Time"; 
			 }else{
				 dispMsg += "<br/><b>Time:</b> " + getDisplayTimeFromMins(event.fromTime) + " to " + getDisplayTimeFromMins(event.toTime); 
			 }
			   
			 a.setAttribute("onmouseover","javascript:Tip('"+ dispMsg + "<br/>', SHADOW, true, TITLE, 'Click for Event Details', PADDING, 9 ,FONTSIZE, '8pt', SHADOWCOLOR, '#99957E', BGCOLOR, '#C9CCC1', BORDERCOLOR, '#fff', WIDTH, 180, TITLEBGCOLOR, '#BAA32B')");
		  }
		  return a;
	   }
	},
	
	getTravelLink: function(sc, scindex, event, eventindex, driverNumber) {
	   
       if (sc.sharing == "FREE_TIME") {
          return null;
       } 
       
       s = trim(event["driver" + driverNumber]);
	   if (s == "") {
		 return null;
	   }
	   var schedules = app.workspace["schedule"];
	   var sc2 = findObjById(schedules, s);
	   if (sc2 == null) {
	      return null;
	   }
       var bc = sc2["color"];
       var c = getTextColor(bc);
       bc = getBackground(bc);
       
	   var a = document.createElement('a');
	   if (bc != null) {
		  a.style.backgroundColor = bc;
	   }
	   if (c != null) {
		  a.style.color = c;
	   }
	   
	   s = event["minuteBefore" + driverNumber];
	   var t = 15;
       if (s != null) {
         t = parseInt(s);
         if (isNaN(t)) {
           t = 15;
         }
         if (t > 59) {
           t = 59;
         }
       }  
	   
	   
	   a.href = "#";
	   a.innerHTML = "Travel (" + event.displayName + ")";
	   a.id = "E_" + scindex + "_" + eventindex;
       a.style.cursor = "move";
	   if (is_ie || is_ie7) {
			a.onmouseover = this.showToolTip.bindAsEventListener(this);
	   } else {
			a.setAttribute("onmouseover","javascript:Tip('"+ event.displayName +"', SHADOW, true, TITLE, 'Click for Event Details', PADDING, 9 ,FONTSIZE, '8pt', SHADOWCOLOR, '#dd99aa', BGCOLOR, '#FF9A47', BORDERCOLOR, '#fff', WIDTH, 200, TITLEBGCOLOR, '#ADD57C')");
	   }
	   var o = new Object();
	   o.link = a;
	   o.duration = t;
       return o;
	  
	},
	
	showToolTip: function(evt) {	
		var e = evt.target ? evt.target : evt.srcElement;		 	
		var msg = "";
		var obj = this.evtObj[e.id];
		if(obj != null) {
			msg = obj.displayName; 
		}else {
			msg = "Click on Me";
			obj = new Object();
		}
		 var dispMsg = "";
		 dispMsg += msg; 		
		 if(obj.locationName != null) {
			 dispMsg += "<br/><b> Location:</b> " + obj.locationName;
		 }	
		
		 if(obj.noTimeFlag != null && "true" == trim("" + obj.noTimeFlag)){
			dispMsg += "<br/><b>Time:</b> " + "No " + "  " + "Time"; 
		 }else{
			 dispMsg += "<br/><b>Time:</b> " + getDisplayTimeFromMins(obj.fromTime) + " to " + getDisplayTimeFromMins(obj.toTime); 
		 }	  

		javascript:Tip(dispMsg , SHADOW, true, TITLE, 'Click for Event Details', PADDING, 9 ,FONTSIZE, '8pt', SHADOWCOLOR, '#dd99aa', BGCOLOR, '#FF9A47', BORDERCOLOR, '#fff', WIDTH, 200, TITLEBGCOLOR, '#ADD57C');		
		return false;	
	},
	getEventByIndex: function(id) {
	   var idx = id.indexOf("_");
       var idx2 = id.lastIndexOf("_");
       var scindex = parseInt(id.substring(idx+1, idx2));
       var eindex = parseInt(id.substring(idx2+1));
       var sc = this.schedules[scindex];
       var event = sc["event"][eindex];
       return event;
	},
	
	getScheduleByIndex: function(id) {
	   var idx = id.indexOf("_");
       var idx2 = id.lastIndexOf("_");
       var scindex = parseInt(id.substring(idx+1, idx2));
       var sc = this.schedules[scindex];
       return sc;
	},
	
	eventDetailView: function(id, name) {
	   var idx = id.indexOf("_");
       var idx2 = id.lastIndexOf("_");
       var scindex = parseInt(id.substring(idx+1, idx2));
       var eindex = parseInt(id.substring(idx2+1));
       var sc = this.schedules[scindex];
       var event = sc["event"][eindex];
       var actualTime = -1;
       if (name != null) {
         actualTime = parseInt(name);
         if (isNaN(actualTime)) {
            actualTime = -1;
         }
       }
       var schId = sc.UUID;
       var driverSch = null; 
       if (schId != event["scheduleId"] && (event.driver1 == schId || event.driver2 == schId)) {
          driverSch = sc;
          sc = findObjById(app.workspace["schedule"], event["scheduleId"]);
       }
       app.schedule.editEventDetails(event, sc, false, actualTime, driverSch);
	},
	
	
	 getTimeCell: function(sc, event) {
	      var bc = sc["color"];
		  var c = getTextColor(bc);
	      bc = getBackground(bc);
		  var td = document.createElement("td");
		  var s = parseInt(event["startDT"]);
		  var dt = new Date(s);
		  if (bc != null) {
			  td.style.backgroundColor = bc;
		  }
		  if (c != null) {
			  td.style.color = c;
		  }
		  if (event["timeFlag"] + "" == "false") {
		      td.innerHTML = " ";
		  } else {
			  var m = "" + dt.getMinutes();
			  if (m.length == 1) {
				 m = "0" + m;
			  }
			  var h = dt.getHours();
			  
			  var s;
			  if (h >= 12) {
				 if (h > 12) {
					h = h - 12;
				 }
				 s = h + ":" + m + " pm";
			  } else {
				 if(h == 0){
					h = 12;
				 }
				 s = h + ":" + m + " am";
			  }
			  var s2 = parseInt(event["endDT"]);
		      dt = new Date(s2);
		      var m = "" + dt.getMinutes();
			  if (m.length == 1) {
				 m = "0" + m;
			  }
			  var h = dt.getHours();
		      if (h >= 12) {
				 if (h > 12) {
					h = h - 12;
				 }
				 s += " - " + h + ":" + m + " pm";
			  } else {
				 if(h == 0){
					h = 12;
				 }
				 s += " - " + h + ":" + m + " am";
			  }
			  td.innerHTML = s;
		  }
		  
		  return td;
	 },
	 
	 getAgendaEventCell: function(sc, scindex, event, eventindex, actualDate) {
	      var bc = sc["color"];
		  var c = getTextColor(bc);
		  bc = getBackground(bc);
		  var td = document.createElement("td");
		  var a;
	      if (bc != null) {
			  td.style.backgroundColor = bc;
		  }
		  var a;
		  var s;
		  if (sc.sharing == "FREE_TIME") {
			   var a = document.createElement('span');
			   if (bc != null) {
				  a.style.backgroundColor = bc;
			   }
			   if (c != null) {
				  a.style.color = c;
			   }
			  s = get_nbsp(event.displayName);
			  a.id = "E_" + scindex + "_" + eventindex;
	          a.style.margin = "0 -2px";
		  } else {
			  var a = document.createElement('a');
			  a.href = "#";
			  s = event.displayName;
			  a.id = "E_" + scindex + "_" + eventindex;
			  if (c != null) {
				  a.style.color = c;
			  }
          }
          a.name = actualDate.getTime();
          var tt = null;
          if (trim(event["driver1"]) != "") {
             var s2 = event["minuteBefore1"];
             if (s2 != null) {
                tt = " (Travel " + s2 + " mins before";
             }          
          } 
          
          if (trim(event["driver2"]) != "") {
             var s2 = event["minuteBefore2"];
             if (s2 != null) {
                if (tt == null) {
                   tt = " (Travel ";
                } else {
                   tt += " - ";
                }
                tt += s2 + " mins after";
             }          
          } 
	      
	      if (tt != null) {
	        s += tt + ")";
	      }
	      
	      a.innerHTML = s;
	      td.appendChild(a);

		  return td;
	 },
	
	 processDragBegin: function(draggable) {
     },
      
      
     processDragged: function(draggable, e) {
         
     },
     
     moveToNewStartTime: function(source, stTime) {
     
        var sc = this.getScheduleByIndex(source.key);
        var event = this.getEventByIndex(source.key);
        if (this.isPastEvent(event, stTime)) {
           return;
        }
        var t1 = parseInt(event["startDT"]);
        var t2 = parseInt(event["endDT"]);
        var l = stTime.getTime() - parseInt(event["startDT"]);
        t1 += l;
        t2 += l;
        event["startDT"] = "" + t1;
	    event["endDT"] = "" + t2;
	    event["timeFlag"] = "true";
	    event["noTimeFlag"] = "false";
	    t1 = new Date(t1);
	    var h = t1.getHours();
	   
	    event["fromTime"] = h * 60 + t1.getMinutes();
	    t2 = new Date(t2);
	    h = t2.getHours();
	    event["toTime"] = h * 60 + t2.getMinutes();
	    this.save2(sc, event);
     },
     
     moveToNoTime: function(source, stTime) {   
        var sc = this.getScheduleByIndex(source.key);
        var event = this.getEventByIndex(source.key);
        if (this.isPastEvent(event, stTime)) {
           return;
        }
        event["startDT"] = "" + stTime;
		event["endDT"] = "" + (stTime + (30 * 60 * 1000));
	    event["timeFlag"] = "false";
	    event["noTimeFlag"] = "true";
	    this.save2(sc, event);
     },
     
     save: function(event) {
   
      var sch = app.schedule.getSelectedSchedule();
      
      if (sch == null) {
         return;
      }
     
      if (sch["event"] == null) {
         createOneToManyAssoc(sch, "event", "Event");
      }
      
      initializeCreatedObject(sch["event"], event);
      sch["event"].push(event);
      
      this.doSave(sch, event);
      
     },
     
     doSave: function(sch, event, addlAction) {
	   
	   // Date 2 Nov 07 
	   //Code to fix repeating events dragging, if single event is dragged among repeating events
	   if(event["repeatFlag"]+"" == "true"){		
		  // if(parseInt(event["startDT"]) > parseInt(event["repeatUntil"])){			   
			addlAction = "modifyInstance";		
		 //  }
	   }

	  this.addlAction = addlAction;
	  this.obj = event;
	  this.originalSch = sch;
      var editor = new Af.ObjEditor();
     
      var xmlString = editor.getChangeXmlForObj(event, ["displayName", "startDT", "endDT", "timeFlag", "noTimeFlag", "fromTime", "toTime"], "ObjModify", null);
      
	  var req = new Af.DataRequest(svcURL, this.saveSuccessful.bind(this), this.saveFailed.bind(this), null, 
				this.saveTimedOut.bind(this));
      req.addService("WorkspaceService", "saveEventDetails"); 
      req.addParameter("parentId", sch.UUID);  
      event["scheduleId"] = sch.UUID;
      if (event.UUID != null) {
         req.addParameter("UUID", event.UUID);
      } 
      if (addlAction != null) {
         req.addParameter("addlAction", addlAction); 
      }  
	  if (this.actualDate != null) {
         req.addParameter("actualDate", this.actualDate); 
      } 
    
	  req.xmlDoc = xmlString;
      this.savedObj = event;
      ajaxEngine.processRequest(req);
   },
   
  
   saveSuccessful: function(response) {
      if (this.addlAction == "resendEmail") {
          showMessageDialog("Your event details have been saved.  A notification of the event changes has been sent to your guests.", "Success", 300, 120);
      }
	  var xds = new Af.XMLToDataSet(response.responseXML);
	  var e = xds.data;
	  if (this.savedObj .UUID == null) {	    
         this.savedObj.UUID = e.UUID;
         app.schedule.miniCalendar.updateMiniCalendar(this.savedObj);
      }
	  // Modified on 2 Nov By Gabbar, modify only current instance(among repeating events)
	  //which is dragged and keeps anothers as it is.
	  if (this.addlAction == "modifyInstance") {
	  
	     replaceInArray(this.originalSch["event"], this.obj, e["Event"][0]);
	     this.originalSch["event"].push(e["Event"][1]);
	     app.schedule.selectScheduleAndRefresh(this.originalSch);
		// showMessageDialog("Your event details have been saved.", "Success", 300, 120);
	     return;
	  }	
   },   
   
   saveFailed: function(dataRequest, msg) {
      showMessageDialog("We are currently unable to save these event details.  Please try again.", "Excuse us!", 350, 130);
   },
   
   saveTimedOut: function(dataRequest) {
	   showMessageDialog("A bit of network congestion has caused a delay.  Nonetheless, be assured that"+
						" your event has been saved.", "Excuse us!", 400, 150);	       
   },
   
   scrollTo7AM: function() {
   
   },
   
   handleScroll: function() {
   
   },
   
   getVisibleEventsList: function(idate, startTime, endTime, showRepeatEvent) {
	   var eventList = new Array();
	   var t1 = startTime.getTime();
	   var t2 = endTime.getTime();
	   for (var i=0; i<this.schedules.length; i++) {
	       var sc = this.schedules[i];
	       var l = sc["event"];
	       
	       if (l != null) {
	       
	          for (var j=0; j<l.length; j++) {
	              var event = l[j];
	              var s = parseInt(event["startDT"]);
	              var e = parseInt(event["endDT"]);
	              
	              var tempDt = new Date(s);
	              tempDt.setHours(0,0,0,0);	
	              
	              if (showRepeatEvent && tempDt.getTime() <= idate.getTime() && (event["repeatFlag"] + "" == "true")) {
	                 if (event["deletedSeqList"] == null) {
	                    setEventDeleteSeqList(event);
	                 }
	                 if (event["modifiedSeqList"] == null) {
	                    setEventModifySeqList(event);
	                 }
	                 if (!isEventInSeq(event, idate.getTime())) {
	                    continue;
	                 }
	                 event = this.getRpt(event, idate, startTime, endTime);
	                 
	                 if (event == null) {
	                    continue;
	                 }
	              } else if (s < t1 || s >= t2) {
	                 continue;
	              }
	              	              
                  var o = new Object();
                  o.schedule = sc;
                  o.scindex = i;
                  o.event = event;
                  o.eventindex = j;
                  o.actualDate = idate;
                  eventList.push(o);
	             
	          }
	       }
	   }
	   if(eventList!=null && eventList.length > 0){
		eventList.sort(sortEventByStartTime);
	   }
	   return eventList;
	   
	 },
	 
	 getEventMatrics: function(tbl, idate, startTime, endTime) {

	   var m = new Array(25);
	   for (var i=0; i<25; i++) {
	      m[i] = new Array();
	   }
	   
	   var t1 = startTime.getTime();
	   var t2 = endTime.getTime();
	   
	       
	   for (var i=0; i<this.schedules.length; i++) {
	       var sc = this.schedules[i];
	       var l = sc["event"];
	       
	       if (l != null) {
	       
	          for (var j=0; j<l.length; j++) {
	              var event = l[j];
	              var s = parseInt(event["startDT"]);
	              var e = parseInt(event["endDT"]);
	              if (isNaN(s) || isNaN(e)) {
	                 continue; // old events have garbage data
	              }

	              var tempDt = new Date(s);
	              tempDt.setHours(0,0,0,0);
	              if (tempDt.getTime() <= idate.getTime() && (event["repeatFlag"] + "" == "true")) {
	                 if (event["deletedSeqList"] == null) {
	                    setEventDeleteSeqList(event);
	                 }
	                 if (event["modifiedSeqList"] == null) {
	                    setEventModifySeqList(event);
	                 }
	                 if (!isEventInSeq(event, idate.getTime())) {
	                    continue;
	                 }
	                 event = this.getRpt(event, idate, startTime, endTime);
	                 if (event == null) {
	                    continue;
	                 }
	              } else if (s < t1 || s >= t2) {
	                 continue;
	              }
	              
	              var o = new Object();
                  o.schedule = sc;
                  o.scindex = i;
                  o.event = event;
                  o.eventindex = j;
	              o.link = this.getEventLink(sc, i, event, j);
	              o.link.name = idate.getTime();
	              o.cols = 1;
	              o.offsetInCell = 0;
	              o.isRendered = false;
	              
	              o.driver1 = this.getTravelLink(sc, i, event, j, 1);
	              if (o.driver1 != null) {
	                 o.driver1.link.name = idate.getTime();
	              }
	              o.driver2 = this.getTravelLink(sc, i, event, j, 2);
	              if (o.driver2 != null) {
	                 o.driver2.link.name = idate.getTime();
	              }
                 
                  if (event["timeFlag"] + "" == "false") {
                  	// r is the begining row in the calendar where event is rendered
                     o.r = 24;
                     o.endRow = 24;
                     m[24].push(o);
                  } else {
                      // set start row
					  var dt = new Date(s);
		              var fromTime = parseInt(event["fromTime"]);
		              
		              if (!isNaN(fromTime)) {
		            	  var hours = fromTime % 60;
		            	  var minutes = fromTime - (hours * 60);
		            	  dt.setHours(hours, minutes, 0, 0);
		              }
		              
					  if (o.driver1 != null) {
					    dt.setMinutes(dt.getMinutes() - o.driver1.duration);
					  }
					  var h = dt.getHours();
					  o.minuteOffsetStart = dt.getMinutes() / 60;
					  var dt2 = new Date(e);
		              var toTime = parseInt(event["toTime"]);
		              if (!isNaN(toTime)) {
		            	  var hours = toTime % 60;
		            	  var minutes = toTime - (hours * 60);
		            	  dt2.setHours(hours, minutes, 0, 0);
		              }
					  if (o.driver2 != null) {
					    dt2.setMinutes(dt2.getMinutes() + o.driver2.duration);
					  }
					  var h2 = dt2.getHours();
					  if (h2 < h) {
					     h2 = 24;
					  }
					  var rows = 0;
					  o.r = h;
					  try {
						  m[h].push(o);
					  } catch(exc) {
						 if ( o.driver1 != null) {
						    var dddd =  o.driver1.duration;
						 }
						 alert (exc + " : " + h + " : " + event["displayName"] + " : " + o.driver1 + " : " + dddd);
					  }
					  
					  if (h < h2) {
						  while (h < h2 && h <24) {
							 rows++;
							 h++;
						     m[h].push(o);
						  }
					  }
					  o.minuteOffsetEnd = (60 - dt2.getMinutes()) / 60;
					  if (o.minuteOffsetEnd > 0) {
					     rows++;
					  }
					  o.rows = rows;
				  }
				  if (this.dndMgr2 != null && sc["sharing"] != "ALL_TIME" && sc["sharing"] != "FREE_TIME") {
				     var a = o.link;
					 var key = a.id;
					 this.dndMgr2.registerDraggable("Event", key, a, event.displayName);
				  }
	          }
	       }
	   }
	   for (var i=0; i<24; i++) {
	      var a = m[i];
	      var n = a.length;
	      for (var j=0; j<n; j++) {
	         var o = a[j];
	         if (o.offsetInCell < j) {
	            o.offsetInCell = j;
	         }
	         if (o.cols < n) {
	            o.cols = n;
	         }
	      }
	   }
	   	   
	  return m;
	   
	 },
	 
	 renderMatrics: function(m, tbl, cindex) {
	 
   		var allDayEventsElem = document.getElementById("allDayEvents");
   		var allDayEventsElemPos = RicoUtil.toDocumentPosition(allDayEventsElem);
	  
	   var tblPosDoc = RicoUtil.toDocumentPosition(tbl);
	   var wrapperPosDoc = RicoUtil.toDocumentPosition(document.getElementById("wrapper"));
	   
	   var yb = allDayEventsElemPos.y + allDayEventsElem.offsetHeight + this.calendarArea.offsetHeight;
	   
	   var cellH = 0;
	   
	   var ptemp = RicoUtil.toDocumentPosition(tbl.rows[0].cells[0]);
	   cellH = ptemp.y;
	   ptemp = RicoUtil.toDocumentPosition(tbl.rows[1].cells[0]);
	   cellH = ptemp.y - cellH;
	   var firstVisibleRow = 1;
	   while ((firstVisibleRow*cellH <this.calendarArea.scrollTop)) {
		   	firstVisibleRow++;
	   }
	   firstVisibleRow--;
	   	       
	   for (var i=0; i<24; i++) {
	       
	       var list = m[i];
	      
	       if (list.length == 0) {
	          continue;
	       } 
	      
		   var cell = tbl.rows[i].cells[cindex];
		   if (cell.childNodes.length > 1) {
			 removeAll(cell);
			 cell.innerHTML = "&nbsp;"
		   }
		   var cellPosDoc = RicoUtil.toDocumentPosition(cell);
		   var cellPosViewport = RicoUtil.toViewportPosition(cell);

		   
	       for (var j=0; j<list.length; j++) {
	       
		       var o = list[j];
		       
		       // make sure that event is rendered once if it is visible
		       if (o.r == i) {
		       	  o.isRendered = false;
		       }
		       
		       if ((o.r + o.rows)< i || i<firstVisibleRow) {
		          continue;
		       }
	
			   if (o.isRendered) {
			   	  continue;
			   }
			   o.isRendered = true;
	
			   var endCellIdx = i + (o.rows - (i - o.r)); //assume that o.r is always less than or equal to i
			   while (!(endCellIdx <= 24)) {
			   		endCellIdx--;
			   }
			   endCellIdx--;
			   var endCell = tbl.rows[endCellIdx].cells[cindex];
			   var endCellPosDoc = RicoUtil.toDocumentPosition(endCell);
			   var enCellPosViewport = RicoUtil.toViewportPosition(endCell);
	
		       var p = new Object();
		       p.x = cellPosDoc.x - wrapperPosDoc.x;
		       p.y = cellPosDoc.y - wrapperPosDoc.y;
		       var toffset = parseInt(o.minuteOffsetStart * cellH);
		       var boffset = parseInt(o.minuteOffsetEnd * cellH);
		       
		       var y = 0;
		       if (i == o.r && i > firstVisibleRow) { // set offset only if event is fully rendered
		       		p.y += toffset;
		       		y = p.y;
		       } else {
		       		p.y = allDayEventsElemPos.y + allDayEventsElem.offsetHeight;
		       		y = p.y;
		       }
		       if (y >= (allDayEventsElemPos.y + allDayEventsElem.offsetHeight) && y < yb) {
		          var a = o.link;
			      var w = parseInt((cell.offsetWidth - o.cols * list.length) / o.cols);
				  var div = document.createElement("div");
				  div.style.width = w + "px";
				  div.style.position = "absolute";
				  div.style.left = (p.x + ((w + 1) * o.offsetInCell)) + "px";
				  div.style.top = (p.y + 1) + "px";
				  if (navigator.userAgent.toLowerCase().indexOf("msie") != -1) {
				  	// userAgent string contains "msie" => it is IE browser
				  	div.style.top = (p.y + (cellPosDoc.y - cellPosViewport.y) + 1) + "px";
				  }
				  div.style.overflow = "hidden";
				  div.style.padding = "0px";
				  div.style.margin = "0px";
				  a.style.verticalAlign = 'top';
				  a.style.padding = "0px";
				  a.style.bottomPaddding = "2px";
				  a.style.margin = "0px";
				  var h = (cellH * (o.rows - (i-o.r))) - 1 - toffset - boffset;
				  // var h = (endCellPosDoc.y-p.y) + cellH - boffset;
				  if (h < 10) {
				    h = 10;
				    a.style.fontSize = "7px";
				  }

				  var y2 = y + h;
				  if (y2 > yb) {
				     h -= y2 - yb;
				  }
				  
				  var drv = o.driver1;
				  var hd1 = 0;
				  if (drv != null) {
				     var div2 = document.createElement("div");
				     div2.style.width = w + "px";
				     div2.style.backgroundColor = drv.link.style.backgroundColor;
				     var h2 = parseInt((drv.duration * cellH) / 60);
				     if (h2 < 10) {
				        h += 10 - h2;
				        h2 = 10;
				        drv.link.style.fontSize = "8px";
				     }
				     div2.style.height = h2 + "px";
				     div2.appendChild(drv.link);
				     div.appendChild(div2);
				     hd1 = h2;
				  }
				  
				  
				  
				  div.id = a.id;
				  
				  drv = o.driver2;
				  hd2 = 0;
				  if (drv != null) {
				     var div2 = document.createElement("div");
				     div2.style.width = w + "px";
				     div2.style.backgroundColor = drv.link.style.backgroundColor;
				     var h2 = parseInt((drv.duration * cellH) / 60);
				     if (h2 < 10) {
				        h += 10 - h2;
				        h2 = 10;
				        drv.link.style.fontSize = "8px";
				     }
				     div2.style.height = h2 + "px";
				     div2.appendChild(drv.link);
				    
				     
				     var div3 = document.createElement("div");
				     div3.style.width = w + "px";
				     div3.style.backgroundColor = a.style.backgroundColor;
				     div3.style.height = (h - hd1 - h2) + "px";
				     div3.appendChild(a);
				     div.appendChild(div3);
				     div.appendChild(div2);
				  } else {
				     div.appendChild(a);
				  }
				  div.style.height = h + "px";
				  div.style.backgroundColor = a.style.backgroundColor;
				  cell.appendChild(div);
		       }
	       } // for loop for all events to be rendered in a cell
	   }
	   
	 },
	
     
     getRpt: function(ev, idate, startTime, endTime) {
       var repeatUntil = parseInt(ev["repeatUntil"]);
       if (repeatUntil < startTime.getTime()) {
           return null;
       }
       var t = ev["repeatType"];
       
       if (t == "ED") {
          return this.getEDRpt(ev, idate);
       } else if (t == "EWD") {
          return this.getEWDRpt(ev, idate);
       } else if (t == "EW_SAME_DAY") {
          return this.getEW_SAME_DAYRpt(ev, idate);
       } else if (t == "A_DATE") {
          return this.getA_DATERpt(ev, idate);
       } else if (t == "NTH_WEEK_A_DAY") {
          return this.getNTH_WEEK_A_DAYRpt(ev, idate);
       } else if (t == "LAST_WEEK_A_DAY") {
          return this.getLAST_WEEK_A_DAYRpt(ev, idate);
       } else if (t == "MORE") {
          return this.getMoreRpt(ev, idate);
       }
      
       return null; 
     },
     
     getEDRpt: function(ev, idate) {
        
        return ev;
     },
     
     getEWDRpt: function(ev, idate) {
        var n = idate.getDay();
        if (n >=1 && n <=5) { 
          return ev;
        } 
        
        return null;
     },
     
     getEW_SAME_DAYRpt: function(ev, idate) {
        var s = parseInt(ev["startDT"]);
        var dt = new Date(s);
        var n1 = dt.getDay();
        var n2 = idate.getDay();
        if (n1 == n2) { 
          return ev;
        } 
        
        return null;
     },
     
     getA_DATERpt: function(ev, idate) {
        var s = parseInt(ev["startDT"]);
        var dt = new Date(s);
        var n1 = dt.getDate();
        var n2 = idate.getDate();
        if (n1 == n2) { 
          return ev;
        } 
        
        return null;
     },
     
     
     getNTH_WEEK_A_DAYRpt: function(ev, idate) {
        var s = parseInt(ev["startDT"]);
        var dt = new Date(s);
        var n1 = dt.getDay();
        var n2 = idate.getDay();
        if (n1 == n2) { 
          n1 = this.dateUtil.getWeekOfMonth(dt);
          n2 = this.dateUtil.getWeekOfMonth(idate);
          if (n1 == n2) {
             return ev;
          }
        } 
       
        return null;
     },
     
     getLAST_WEEK_A_DAYRpt: function(ev, idate) {
        var s = parseInt(ev["startDT"]);
        var dt = new Date(s);
        var n1 = dt.getDay();
        var n2 = idate.getDay();
        if (n1 == n2) { 
          if (this.dateUtil.isDayInLastWeek(idate)) {
             return ev;
          }
        } 
       
        return null;
     },
     
     getMoreRpt: function(ev, idate) {
        var t = ev["repeatSubtype"];
        if (t.indexOf("REPEAT") == 0) {
           return this.getMoreRepeatAfter(ev, idate);
        } else {
           return this.getMoreByWeek(ev, idate);
        }
        
         return null;
     },
     
     getMoreRepeatAfter: function(ev, idate) {
        var t = ev["repeatSubtype"];
        if (t == "REPEAT_AFTER_DAYS") {
           return this.getRepeatAfterDays(ev, idate);
        } else if (t == "REPEAT_AFTER_WEEKS") {
           return this.getRepeatAfterWeeks(ev, idate);
        } else if (t == "REPEAT__AFTER_MONTHS_BY_DATE") {
           return this.getRepeatAfterMonthsDate(ev, idate);
        } else if (t == "REPEAT_AFTER_MONTHS_BY_DAY") {
           return this.getRepeatAfterMonthsDay(ev, idate);
        } else if (t == "REPEAT_AFTER_YEARS") {
           return this.getRepeatAfterYear(ev, idate);
        }
        
        
        return null;
     },
     
     getRepeatNumber: function(ev) {
        var t = ev["repeatNumber"];
        if (t == null) {
           return 1;
        }
        t = parseInt(t);
        if (t < 1) {
           t = 1;
        }
        return t;
     },
     
     getRepeatAfterDays: function(ev, idate) {
        var s = parseInt(ev["startDT"]);
        var dt = new Date(s);
        var n1 = this.dateUtil.getDaysAfter(dt, idate);
        if (n1 > -1) {
           var n2 = this.getRepeatNumber(ev);
           if ((n1 % n2) == 0) {
              return ev;
           }
        }
        return null;
     },
     
     getRepeatAfterWeeks: function(ev, idate) {
        var s = parseInt(ev["startDT"]);
        var dt = new Date(s);
        var n1 = this.dateUtil.getDaysAfter(dt, idate);
        if (n1 > -1) {
           var n2 = this.getRepeatNumber(ev);
           if ((n1 % (n2*7)) == 0) {
              return ev;
           }
        }
        return null;
     },
     
     getRepeatAfterMonthsDate: function(ev, idate) {
        var s = parseInt(ev["startDT"]);
        var tDate = new Date(s);
        tDate.setHours(0, 0, 0, 0);
        if (idate.getTime() < tDate.getTime()) {
           return null;
        }
        var t = idate.getTime();
        var dt = new Date(s);
        var sdate = dt.getDate();
        var n = this.getRepeatNumber(ev);
        while (dt.getTime() < t) {
           dt.setMonth(dt.getMonth() + n);
        }
        if (dt.getMonth() == idate.getMonth()) {
			if (dt.getDate() != sdate) {
			   var m = dt.getMonth();
			   while (m == dt.getMonth()) {
				  dt.setDate(dt.getDate() - 1);
			   }
			}
			if (idate.getDate() == dt.getDate()) {
			   return ev;
			}
        }
        return null;
     },
     
     getRepeatAfterMonthsDay: function(ev, idate) {
        var s = parseInt(ev["startDT"]);
        var tDate = new Date(s);
        tDate.setHours(0, 0, 0, 0);
        if (idate.getTime() < tDate.getTime()) {
           return null;
        }
        var t = idate.getTime();
        var dt = new Date(s);
        var sdate = dt.getDate();
        var n = this.getRepeatNumber(ev);
        var y1 = dt.getFullYear();
        var y2 =  idate.getFullYear();
        var m1 = dt.getMonth();
        var m2 = idate.getMonth();
        while (y1 < y2 || (y1 == y2 && m1 < m2)) {
           dt.setMonth(dt.getMonth() + n);
           y1 = dt.getFullYear();
		   m1 = dt.getMonth();
        }
       
        if (idate.getMonth() == dt.getMonth()) {
            dt = new Date(s);
			var n1 = dt.getDay();
			var n2 = idate.getDay();
			if (n1 == n2) { 
			  n1 = this.dateUtil.getWeekOfMonth(dt);
			  n2 = this.dateUtil.getWeekOfMonth(idate);
			  if (n1 == n2) {
				 return ev;
			  }
			} 
        }
        return null;
     },
     
     getRepeatAfterYear: function(ev, idate) {
        var s = parseInt(ev["startDT"]);
        var tDate = new Date(s);
        tDate.setHours(0, 0, 0, 0);
        if (idate.getTime() < tDate.getTime()) {
           return null;
        }
        var t = idate.getFullYear();
        
        var dt = new Date(s);
       
        if (idate.getDate() != dt.getDate() || idate.getMonth() != dt.getMonth()) {
           return null;
        }
        var sdate = dt.getDate();
        var n = this.getRepeatNumber(ev);
        
        while (dt.getFullYear() < t) {
           dt.setFullYear(dt.getFullYear() + n);
        }
        if (idate.getFullYear() == dt.getFullYear()) {
           return ev;
        }
        return null;
     },
     
     getMoreByWeek: function(ev, idate) {
        var t = ev["repeatSubtype"];
        if (t == "EVERY_WEEK") {
           return this.getMoreEveryWeek(ev, idate);
        } else if (t == "OTHER_WEEK") {
           return this.getMoreEveryOtherWeek(ev, idate);
        } else if (t == "1st_WEEK") {
           return this.getMoreNthWeek(ev, idate, 0);
        } else if (t == "2nd_WEEK") {
           return this.getMoreNthWeek(ev, idate, 1);
        } else if (t == "3rd_WEEK") {
           return this.getMoreNthWeek(ev, idate, 2);
        } else if (t == "4th_WEEK") {
           return this.getMoreNthWeek(ev, idate, 3);
        } else if (t == "LAST_WEEK") {
           return this.getMoreLastWeek(ev, idate);
        }
        return null;
     },
     
     getMoreEveryWeek: function(ev, idate) {
        
        var n1 = idate.getDay();
        var n2 = this.getRepeatNumber(ev);
        
        var n3 = (1 << n1) & n2;
        
        if (n3 != 0) {
           return ev;
        }
        
        return null;
     },
     
     
     getMoreEveryOtherWeek: function(ev, idate) {
     
       var s = parseInt(ev["startDT"]);
       var dt = new Date(s);
       var n1 = this.dateUtil.getDaysAfter(dt, idate);
       if (n1 > -1) {
           var n2 = parseInt(n1/7);
           if (n2 % 2 == 0) {
				var n1 = idate.getDay();
				var n2 = this.getRepeatNumber(ev);
		        
				var n3 = (1 << n1) & n2;
		        
				if (n3 != 0) {
				   return ev;
				}
           }
       }
       return null;
     },
     
     getMoreNthWeek: function(ev, idate, n) {
       var s = parseInt(ev["startDT"]);
       var dt = new Date(s); 
	   n2 = this.dateUtil.getWeekOfMonth(idate);
       if (n2 == n) {
          var n1 = idate.getDay();
		  var n2 = this.getRepeatNumber(ev);
	        
		  var n3 = (1 << n1) & n2;
	        
		  if (n3 != 0) {
		     return ev;
		  }
       }
       return null;
     },
     
     getMoreLastWeek: function(ev, idate, n) {
       var s = parseInt(ev["startDT"]);
       var dt = new Date(s); 
       if (this.dateUtil.isDayInLastWeek(idate)) {
          var n1 = idate.getDay();
		  var n2 = this.getRepeatNumber(ev);
	        
		  var n3 = (1 << n1) & n2;
	        
		  if (n3 != 0) {
		     return ev;
		  }
       }
       return null;
     },
     
     getDayNumber: function(t) {
	   var t1 = new Date(this.startTime.getTime());
	   var n = 0;
	   while(t1.getTime() <= t) {
	      n++;
	      t1.setDate(t1.getDate() + 1);
	   }
	   return n;
	 },
	
     mouseDownOnTable: function(e) {
     
         var eventTarget = e.target ? e.target : e.srcElement;
         
         var f = false;
         var t = eventTarget;
         while (t != null) {
            if (t == this.table) {
               f = true;
               break;
            }
            t = t.parentNode;
         }
         
         
         if (f) {
         
             this.table.onmousemove= this.mouseMoveOnTable.bindAsEventListener(this);
			 this.table.onmouseup = this.mouseUpOnTable.bindAsEventListener(this);
			 document.onmouseup= this.mouseUpOnTable.bindAsEventListener(this);
	         document.onmousemove= this.mouseMoveOnTable.bindAsEventListener(this);
	         
            
			 this.startIdx = htmlTableRowIndexAt(this.table, e);
			 this.cellIdx = htmlTableCellIndexAt(this.table, this.table.rows[this.startIdx], e);
			 this.endIdx = -1;
	      
			 this.msDownX = this.mx1 = e.clientX;
			 this.msDownY = this.my1 = e.clientY;
	        
			 return consumeEvent(e);
         }
      },
     
      mouseMoveOnTable: function(e) {
         var x = e.clientX;
         var y = e.clientY;
         var dx = x - this.mx1;
         var dy = y - this.my1;
         if (this.endIdx < 0) {
            if (Math.abs(dx) >= 2 || Math.abs(dy) >= 2) {
               this.endIdx = htmlTableRowIndexAt(this.table, e);
               if (this.endIdx < 0) {
                  this.endIdx = this.startIdx;
               }
            }
         } else {
            this.deselectRows();
            this.endIdx = htmlTableRowIndexAt(this.table, e);
            if (this.endIdx < 0) {
                this.endIdx = this.startIdx;
            }
         }
         
         this.selectRows();
         
         return consumeEvent(e);
      },
      
      mouseUpOnTable: function(e) {
         this.table.onmousemove= null;
         document.onmousemove = null;
         this.table.onmouseup= null;
         document.onmouseup= null;
         if (this.endIdx > 0) {
            this.showQuickEventDialog();
         }
         this.deselectRows();
         return consumeEvent(e);
      },
      
      
      mouseDownOnAllDaysTable: function(e) {
     
         var eventTarget = e.target ? e.target : e.srcElement;
         
         var f = false;
         var t = eventTarget;
         while (t != null) {
            if (t == this.allDayEvents) {
               f = true;
               break;
            }
            t = t.parentNode;
         }
         
         
         if (f) {
         
             this.allDayEvents.onmousemove= this.mouseMoveOnAllDaysTable.bindAsEventListener(this);
			 this.allDayEvents.onmouseup = this.mouseUpOnAllDaysTable.bindAsEventListener(this);
			 document.onmouseup= this.mouseUpOnAllDaysTable.bindAsEventListener(this);
	         document.onmousemove= this.mouseMoveOnAllDaysTable.bindAsEventListener(this);
	         this.startIdx = 8;
	         this.cellIdx = htmlTableCellIndexAt(this.allDayEvents, this.allDayEvents.rows[0], e);
	         this.cellIdx++; // since all days events have no cell for the time label
	         this.endIdx = -1;
			 this.msDownX = this.mx1 = e.clientX;
			 this.msDownY = this.my1 = e.clientY;
	        
			 return consumeEvent(e);
         }
      },
     
      mouseMoveOnAllDaysTable: function(e) {
         var x = e.clientX;
         var y = e.clientY;
         var dx = x - this.mx1;
         var dy = y - this.my1;
         if (this.endIdx < 0) {
            if (Math.abs(dx) >= 2 || Math.abs(dy) >= 2) {
               this.endIdx = this.startIdx;
            }
         }
         
         return consumeEvent(e);
      },
      
      mouseUpOnAllDaysTable: function(e) {
         this.allDayEvents.onmousemove= null;
         document.onmousemove = null;
         this.allDayEvents.onmouseup= null;
         document.onmouseup= null;
         if (this.endIdx > 0) {
            this.showQuickEventDialog(true);
         }
         return consumeEvent(e);
      },
      
      selectRows: function() {
         if (this.endIdx < 0) {
            return;
         }
         var s;
         var e;
         if (this.startIdx <= this.endIdx) {
            s = this.startIdx;
            e = this.endIdx;
         } else {
            e = this.startIdx;
            s = this.endIdx;
         }
         var cidx = this.cellIdx;
         for (var i=s; i<=e; i++) {
            this.table.rows[i].cells[cidx].style.backgroundColor = "#c2c2c2";
         }
      },
      
      deselectRows: function() {
         if (this.endIdx < 0) {
            return;
         }
         var s;
         var e;
         if (this.startIdx <= this.endIdx) {
            s = this.startIdx;
            e = this.endIdx;
         } else {
            e = this.startIdx;
            s = this.endIdx;
         }
         var cidx = this.cellIdx;
         for (var i=s; i<=e; i++) {
            this.table.rows[i].cells[cidx].style.backgroundColor = "#ffffff";
         }
      },
      
      showQuickEventDialog: function() {
      
      },
      
      save2: function(sch, event) {
		if(event["rsvp"] != null && event["rsvp"] != "") {
		   this.scheduleToBeSaved = sch;
		   this.eventToBeSaved = event;
		   this.openConfirmDialog();
		} else {
		  this.doSave(sch, event);
		}
      },
     
     isPastEvent: function(event, stTime) {
        var t1 = (new Date()).getTime();
		if((stTime < t1) && (event["rsvp"] != null && event["rsvp"] != ""))  {
			showMessageDialog("You are not allowed to move this event to a past date because you have already invited guests to this event.","Excuse us!", 350, 120);
			return true;
		}
		return false;
	 },
	
     openConfirmDialog: function() {
		if (app.confDialog == null) {
            var handler = {
               templateLoaded: function() {
                  this.parent.confirmDialogLoaded();
               },
				parent:this
            }
            app.confDialog = new Af.HtmlDialog("Notify Guests?", handler, null);
            app.confDialog.width = "300px";
         }
         app.confDialog.showHTMLTemplate(basePageURL + "ConfirmDialog.htm", "MainArea", "confirmHTMLDailog");     
		 app.confDialog.centerDialog(350, 350);
	},
	confirmDialogLoaded: function() {
		this.messageText = document.getElementById("messageText");
		this.sendButton = document.getElementById("sendButton");
		this.dontSendButton = document.getElementById("dontSendButton");
		this.sendButton.onclick = this.doSendChangeNotification.bind(this);
		this.dontSendButton.onclick = this.doDontSendChangeNotification.bind(this);
		
		this.messageText.innerHTML = "Would you like to notify your guests of changes to this event?";
	},
	doSendChangeNotification: function() {		
		 app.confDialog.hide();
		 this.doSave(this.scheduleToBeSaved, this.eventToBeSaved, "resendEmail");		
	},
	doDontSendChangeNotification: function() {		
		 app.confDialog.hide();		 
		 this.doSave(this.scheduleToBeSaved, this.eventToBeSaved);
	}

}


function eventOrder(o1, o2) {
   var e1 = o1.event;
   var e2 = o2.event;
   if (e1["timeFlag"] + "" == "false" || e1["fromTime"] == null) {
      return -1;
   }
   if (e2["timeFlag"] + "" == "false" || e2["fromTime"] == null) {
      return 1;
   }
   try {
	   var s1 = parseInt(e1["fromTime"]);
	   var s2 = parseInt(e2["fromTime"]);
   		return s1 - s2;
   } catch (exc) {
   		return 0;
   }
}

function setEventDeleteSeqList(event) {
   var a = new Array();
   var s = event["deletedSeqs"];
   if (s != null) {
      var a = s.split(",");
      for (var i=0; i<a.length; i++) {
         a[i] = parseInt(a[i]);
      }
   }
   event["deletedSeqsList"] = a;
}

function setEventModifySeqList(event) {
   var a = new Array();
   var s = event["modifiedSeqs"];
   if (s != null) {
      var a = s.split(",");
      for (var i=0; i<a.length; i++) {
         a[i] = parseInt(a[i]);
      }
   }
   event["modifiedSeqsList"] = a;
}


function isEventInSeq(event, t) {
  
   var a = event["deletedSeqsList"];
   if (a != null) {
      for (var i=0; i<a.length; i++) {
         if (a[i] == t) return false;;
      }
   }
   
   a = event["modifiedSeqsList"];
   if (a != null) {
      for (var i=0; i<a.length; i++) {
         if (a[i] == t) return false;;
      }
   }
   
   return true;
}

function appendDeleteSeq(event, t) {
   var s = event["deletedSeqs"];
   if (s == "" || s == null) {
     s = "" + t;
   } else {
     s += "," + t;
   }
   event["deletedSeqs"] = s;
   setEventDeleteSeqList(event);
}

function appendModifySeq(event, t) {
   var s = event["modifiedSeqs"];
   if (s == "" || s == null) {
     s = "" + t;
   } else {
     s += "," + t;
   }
   event["modifiedSeqs"] = s;
   setEventModifySeqList(event);
}

