(function($){$.widget("ui.weekCalendar",{_init:function(){var self=this;self._computeOptions();self._setupEventDelegation();self._renderCalendar();self._loadCalEvents();self._resizeCalendar();self._scrollToHour(self.options.date.getHours());$(window).unbind("resize.weekcalendar");$(window).bind("resize.weekcalendar",function(){self._resizeCalendar()})},refresh:function(){this._clearCalendar();this._loadCalEvents(this.element.data("startDate"))},clear:function(){this._clearCalendar()},today:function(){this._clearCalendar();this._loadCalEvents(new Date())},prevWeek:function(){var newDate=new Date(this.element.data("startDate").getTime()-(MILLIS_IN_WEEK/6));this._clearCalendar();this._loadCalEvents(newDate)},nextWeek:function(){var newDate=new Date(this.element.data("startDate").getTime()+MILLIS_IN_WEEK+(MILLIS_IN_WEEK/7));this._clearCalendar();this._loadCalEvents(newDate)},gotoWeek:function(date){this._clearCalendar();this._loadCalEvents(date)},removeEvent:function(eventId){var self=this;self.element.find(".wc-cal-event").each(function(){if($(this).data("calEvent").id===eventId){$(this).remove();return false}});self.element.find(".wc-day-column-inner").each(function(){self._adjustOverlappingEvents($(this))})},removeUnsavedEvents:function(){var self=this;self.element.find(".wc-new-cal-event").each(function(){$(this).remove()});self.element.find(".wc-day-column-inner").each(function(){self._adjustOverlappingEvents($(this))})},updateEvent:function(calEvent){this._updateEventInCalendar(calEvent)},getTimeslotTimes:function(date){var options=this.options;var firstHourDisplayed=options.businessHours.limitDisplay?options.businessHours.start:0;var startDate=new Date(date.getFullYear(),date.getMonth(),date.getDate(),firstHourDisplayed);var times=[];var startMillis=startDate.getTime();for(var i=0;i').appendTo(self.element);if(options.buttons){calendarNavHtml='
";$(calendarNavHtml).appendTo($calendarContainer);$calendarContainer.find(".wc-nav .wc-today").click(function(){self.element.weekCalendar("today");return false});$calendarContainer.find(".wc-nav .wc-prev").click(function(){self.element.weekCalendar("prevWeek");return false});$calendarContainer.find(".wc-nav .wc-next").click(function(){self.element.weekCalendar("nextWeek");return false})}calendarHeaderHtml='';for(var i=1;i<=options.daysToShow;i++){calendarHeaderHtml+=''}calendarHeaderHtml+='
';calendarBodyHtml='
";for(var i=1;i<=options.daysToShow;i++){calendarBodyHtml+=''}calendarBodyHtml+="
';var start=options.businessHours.limitDisplay?options.businessHours.start:0;var end=options.businessHours.limitDisplay?options.businessHours.end:24;for(var i=start;i
'}calendarBodyHtml+='
'}calendarBodyHtml+='
';for(var i=start;ii)?"wc-business-hours":"";calendarBodyHtml+='
';if(options.use24Hour){calendarBodyHtml+='
'+self._24HourForIndex(i)+"
"}else{calendarBodyHtml+='
'+self._hourForIndex(i)+''+self._amOrPm(i)+"
"}calendarBodyHtml+="
"}calendarBodyHtml+="
";$(calendarHeaderHtml+calendarBodyHtml).appendTo($calendarContainer);$weekDayColumns=$calendarContainer.find(".wc-day-column-inner");$weekDayColumns.each(function(i,val){$(this).height(options.timeslotHeight*options.timeslotsPerDay);if(!options.readonly){self._addDroppableToWeekDay($(this));self._setupEventCreationForWeekDay($(this))}});$calendarContainer.find(".wc-time-slot").height(options.timeslotHeight-1);$calendarContainer.find(".wc-time-header-cell").css({height:(options.timeslotHeight*options.timeslotsPerHour)-11,padding:5})},_setupEventCreationForWeekDay:function($weekDay){var self=this;var options=this.options;$weekDay.mousedown(function(event){var $target=$(event.target);if($target.hasClass("wc-day-column-inner")){var $newEvent=$('
');$newEvent.css({lineHeight:(options.timeslotHeight-2)+"px",fontSize:(options.timeslotHeight/2)+"px"});$target.append($newEvent);var columnOffset=$target.offset().top;var clickY=event.pageY-columnOffset;var clickYRounded=(clickY-(clickY%options.timeslotHeight))/options.timeslotHeight;var topPosition=clickYRounded*options.timeslotHeight;$newEvent.css({top:topPosition});$target.bind("mousemove.newevent",function(event){$newEvent.show();$newEvent.addClass("ui-resizable-resizing");var height=Math.round(event.pageY-columnOffset-topPosition);var remainder=height%options.timeslotHeight;if(remainder<(height/2)){var useHeight=height-remainder;$newEvent.css("height",useHeight"+self._formatDate(currentDay,options.dateFormat));if(self._isToday(currentDay)){$(this).addClass("wc-today")}else{$(this).removeClass("wc-today")}currentDay=self._addDays(currentDay,1)});currentDay=self._dateFirstDayOfWeek(self._cloneDate(self.element.data("startDate")));$weekDayColumns.each(function(i,val){$(this).data("startDate",self._cloneDate(currentDay));$(this).data("endDate",new Date(currentDay.getTime()+(MILLIS_IN_DAY)));if(self._isToday(currentDay)){$(this).parent().addClass("wc-today")}else{$(this).parent().removeClass("wc-today")}currentDay=self._addDays(currentDay,1)})},_renderEvents:function(events,$weekDayColumns){var self=this;var options=this.options;var eventsToRender;if($.isArray(events)){eventsToRender=self._cleanEvents(events)}else{if(events.events){eventsToRender=self._cleanEvents(events.events)}}if(events.options){var updateLayout=false;$.each(events.options,function(key,value){if(value!==options[key]){options[key]=value;updateLayout=true}});self._computeOptions();if(updateLayout){self.element.empty();self._renderCalendar();$weekDayColumns=self.element.find(".wc-time-slots .wc-day-column-inner");self._updateDayColumnHeader($weekDayColumns);self._resizeCalendar()}}$.each(eventsToRender,function(i,calEvent){var $weekDay=self._findWeekDayForEvent(calEvent,$weekDayColumns);if($weekDay){self._renderEvent(calEvent,$weekDay)}});$weekDayColumns.each(function(){self._adjustOverlappingEvents($(this))});options.calendarAfterLoad(self.element);if(!eventsToRender.length){options.noEvents()}},_renderEvent:function(calEvent,$weekDay){var self=this;var options=this.options;if(calEvent.start.getTime()>calEvent.end.getTime()){return }var eventClass,eventHtml,$calEvent,$modifiedEvent;eventClass=calEvent.id?"wc-cal-event":"wc-cal-event wc-new-cal-event";eventHtml='
';$calEvent=$(eventHtml);$modifiedEvent=options.eventRender(calEvent,$calEvent);$calEvent=$modifiedEvent?$modifiedEvent.appendTo($weekDay):$calEvent.appendTo($weekDay);$calEvent.css({lineHeight:(options.timeslotHeight-2)+"px",fontSize:(options.timeslotHeight/2)+"px"});self._refreshEventDetails(calEvent,$calEvent);self._positionEvent($weekDay,$calEvent);$calEvent.show();if(!options.readonly&&options.resizable(calEvent,$calEvent)){self._addResizableToCalEvent(calEvent,$calEvent,$weekDay)}if(!options.readonly&&options.draggable(calEvent,$calEvent)){self._addDraggableToCalEvent(calEvent,$calEvent)}options.eventAfterRender(calEvent,$calEvent);return $calEvent},_adjustOverlappingEvents:function($weekDay){var self=this;if(self.options.allowCalEventOverlap){var groupsList=self._groupOverlappingEventElements($weekDay);$.each(groupsList,function(){var curGroups=this;$.each(curGroups,function(groupIndex){var curGroup=this;if(self.options.overlapEventsSeparate){var newWidth=100/curGroups.length;var newLeft=groupIndex*newWidth}else{var newWidth=100-((curGroups.length-1)*10);var newLeft=groupIndex*10}$.each(curGroup,function(){if(!self.options.overlapEventsSeparate){$(this).bind("mouseover.z-index",function(){var $elem=$(this);$.each(curGroup,function(){$(this).css({"z-index":"1"})});$elem.css({"z-index":"3"})})}$(this).css({width:newWidth+"%",left:newLeft+"%",right:0})})})})}},_groupOverlappingEventElements:function($weekDay){var $events=$weekDay.find(".wc-cal-event:visible");var sortedEvents=$events.sort(function(a,b){return $(a).data("calEvent").start.getTime()-$(b).data("calEvent").start.getTime()});var lastEndTime=new Date(0,0,0);var groups=[];var curGroups=[];var $curEvent;$.each(sortedEvents,function(){$curEvent=$(this);if(curGroups.length>0){if(lastEndTime.getTime()<=$curEvent.data("calEvent").start.getTime()){groups.push(curGroups);curGroups=[]}}for(var groupIndex=0;groupIndex0){if(curGroups[groupIndex][curGroups[groupIndex].length-1].data("calEvent").end.getTime()<=$curEvent.data("calEvent").start.getTime()){curGroups[groupIndex].push($curEvent);if(lastEndTime.getTime()<$curEvent.data("calEvent").end.getTime()){lastEndTime=$curEvent.data("calEvent").end}return }}}curGroups.push([$curEvent]);if(lastEndTime.getTime()<$curEvent.data("calEvent").end.getTime()){lastEndTime=$curEvent.data("calEvent").end}});if(curGroups.length>0){groups.push(curGroups)}return groups},_findWeekDayForEvent:function(calEvent,$weekDayColumns){var $weekDay;$weekDayColumns.each(function(){if($(this).data("startDate").getTime()<=calEvent.start.getTime()&&$(this).data("endDate").getTime()>=calEvent.end.getTime()){$weekDay=$(this);return false}});return $weekDay},_updateEventInCalendar:function(calEvent){var self=this;var options=this.options;self._cleanEvent(calEvent);if(calEvent.id){self.element.find(".wc-cal-event").each(function(){if($(this).data("calEvent").id===calEvent.id||$(this).hasClass("wc-new-cal-event")){$(this).remove();return false}})}var $weekDay=self._findWeekDayForEvent(calEvent,self.element.find(".wc-time-slots .wc-day-column-inner"));if($weekDay){var $calEvent=self._renderEvent(calEvent,$weekDay);self._adjustForEventCollisions($weekDay,$calEvent,calEvent,calEvent);self._refreshEventDetails(calEvent,$calEvent);self._positionEvent($weekDay,$calEvent);self._adjustOverlappingEvents($weekDay)}},_positionEvent:function($weekDay,$calEvent){var options=this.options;var calEvent=$calEvent.data("calEvent");var pxPerMillis=$weekDay.height()/options.millisToDisplay;var firstHourDisplayed=options.businessHours.limitDisplay?options.businessHours.start:0;var startMillis=calEvent.start.getTime()-new Date(calEvent.start.getFullYear(),calEvent.start.getMonth(),calEvent.start.getDate(),firstHourDisplayed).getTime();var eventMillis=calEvent.end.getTime()-calEvent.start.getTime();var pxTop=pxPerMillis*startMillis;var pxHeight=pxPerMillis*eventMillis;$calEvent.css({top:pxTop,height:pxHeight})},_getEventDurationFromPositionedEventElement:function($weekDay,$calEvent,top){var options=this.options;var startOffsetMillis=options.businessHours.limitDisplay?options.businessHours.start*60*60*1000:0;var start=new Date($weekDay.data("startDate").getTime()+startOffsetMillis+Math.round(top/options.timeslotHeight)*options.millisPerTimeslot);var end=new Date(start.getTime()+($calEvent.height()/options.timeslotHeight)*options.millisPerTimeslot);return{start:start,end:end}},_adjustForEventCollisions:function($weekDay,$calEvent,newCalEvent,oldCalEvent,maintainEventDuration){var options=this.options;if(options.allowCalEventOverlap){return }var adjustedStart,adjustedEnd;var self=this;$weekDay.find(".wc-cal-event").not($calEvent).each(function(){var currentCalEvent=$(this).data("calEvent");if(newCalEvent.start.getTime()=currentCalEvent.end.getTime()){adjustedStart=currentCalEvent.end}if(newCalEvent.end.getTime()>currentCalEvent.start.getTime()&&newCalEvent.start.getTime()<=currentCalEvent.start.getTime()){adjustedEnd=currentCalEvent.start}if(!oldCalEvent.resizable||(newCalEvent.end.getTime()<=currentCalEvent.end.getTime()&&newCalEvent.start.getTime()>=currentCalEvent.start.getTime())){adjustedStart=oldCalEvent.start;adjustedEnd=oldCalEvent.end;return false}});newCalEvent.start=adjustedStart||newCalEvent.start;if(adjustedStart&&maintainEventDuration){newCalEvent.end=new Date(adjustedStart.getTime()+(oldCalEvent.end.getTime()-oldCalEvent.start.getTime()));self._adjustForEventCollisions($weekDay,$calEvent,newCalEvent,oldCalEvent)}else{newCalEvent.end=adjustedEnd||newCalEvent.end}if(newCalEvent.start.getTime()>=newCalEvent.end.getTime()){newCalEvent.start=oldCalEvent.start;newCalEvent.end=oldCalEvent.end}$calEvent.data("calEvent",newCalEvent)},_addDraggableToCalEvent:function(calEvent,$calEvent){var self=this;var options=this.options;var $weekDay=self._findWeekDayForEvent(calEvent,self.element.find(".wc-time-slots .wc-day-column-inner"));$calEvent.draggable({handle:".wc-time",containment:".wc-scrollable-grid",revert:"valid",opacity:0.5,grid:[$calEvent.outerWidth()+1,options.timeslotHeight],start:function(event,ui){var $calEvent=ui.draggable;options.eventDrag(calEvent,$calEvent)}})},_addDroppableToWeekDay:function($weekDay){var self=this;var options=this.options;$weekDay.droppable({accept:".wc-cal-event",drop:function(event,ui){var $calEvent=ui.draggable;var top=Math.round(parseInt(ui.position.top));var eventDuration=self._getEventDurationFromPositionedEventElement($weekDay,$calEvent,top);var calEvent=$calEvent.data("calEvent");var newCalEvent=$.extend(true,{start:eventDuration.start,end:eventDuration.end},calEvent);self._adjustForEventCollisions($weekDay,$calEvent,newCalEvent,calEvent,true);var $weekDayColumns=self.element.find(".wc-day-column-inner");var $newEvent=self._renderEvent(newCalEvent,self._findWeekDayForEvent(newCalEvent,$weekDayColumns));$calEvent.hide();options.eventDrop(newCalEvent,calEvent,$newEvent);$calEvent.data("preventClick",true);var $weekDayOld=self._findWeekDayForEvent($calEvent.data("calEvent"),self.element.find(".wc-time-slots .wc-day-column-inner"));if($weekDayOld.data("startDate")!=$weekDay.data("startDate")){self._adjustOverlappingEvents($weekDayOld)}self._adjustOverlappingEvents($weekDay);setTimeout(function(){$calEvent.remove()},1000)}})},_addResizableToCalEvent:function(calEvent,$calEvent,$weekDay){var self=this;var options=this.options;$calEvent.resizable({grid:options.timeslotHeight,containment:$weekDay,handles:"s",minHeight:options.timeslotHeight,stop:function(event,ui){var $calEvent=ui.element;var newEnd=new Date($calEvent.data("calEvent").start.getTime()+($calEvent.height()/options.timeslotHeight)*options.millisPerTimeslot);var newCalEvent=$.extend(true,{start:calEvent.start,end:newEnd},calEvent);self._adjustForEventCollisions($weekDay,$calEvent,newCalEvent,calEvent);self._refreshEventDetails(newCalEvent,$calEvent);self._positionEvent($weekDay,$calEvent);self._adjustOverlappingEvents($weekDay);options.eventResize(newCalEvent,calEvent,$calEvent);$calEvent.data("preventClick",true);setTimeout(function(){$calEvent.removeData("preventClick")},500)}})},_refreshEventDetails:function(calEvent,$calEvent){var self=this;var options=this.options;$calEvent.find(".wc-time").html(self._formatDate(calEvent.start,options.timeFormat)+options.timeSeparator+self._formatDate(calEvent.end,options.timeFormat));$calEvent.find(".wc-title").html(calEvent.title);$calEvent.data("calEvent",calEvent)},_clearCalendar:function(){this.element.find(".wc-day-column-inner div").remove()},_scrollToHour:function(hour){var self=this;var options=this.options;var $scrollable=this.element.find(".wc-scrollable-grid");var slot=hour;if(self.options.businessHours.limitDisplay){if(hour<=self.options.businessHours.start){slot=0}else{if(hour>self.options.businessHours.end){slot=self.options.businessHours.end-self.options.businessHours.start-1}else{slot=hour-self.options.businessHours.start}}}var $target=this.element.find(".wc-grid-timeslot-header .wc-hour-header:eq("+slot+")");$scrollable.animate({scrollTop:0},0,function(){var targetOffset=$target.offset().top;var scroll=targetOffset-$scrollable.offset().top-$target.outerHeight();$scrollable.animate({scrollTop:scroll},options.scrollToHourMillis)})},_hourForIndex:function(index){if(index===0){return 12}else{if(index<13){return index}else{return index-12}}},_24HourForIndex:function(index){if(index===0){return"00:00"}else{if(index<10){return"0"+index+":00"}else{return index+":00"}}},_amOrPm:function(hourOfDay){return hourOfDay<12?"AM":"PM"},_isToday:function(date){var clonedDate=this._cloneDate(date);this._clearTime(clonedDate);var today=new Date();this._clearTime(today);return today.getTime()===clonedDate.getTime()},_cleanEvents:function(events){var self=this;$.each(events,function(i,event){self._cleanEvent(event)});return events},_cleanEvent:function(event){if(event.date){event.start=event.date}event.start=this._cleanDate(event.start);event.end=this._cleanDate(event.end);if(!event.end){event.end=this._addDays(this._cloneDate(event.start),1)}},_disableTextSelect:function($elements){$elements.each(function(){if($.browser.mozilla){$(this).css("MozUserSelect","none")}else{if($.browser.msie){$(this).bind("selectstart",function(){return false})}else{$(this).mousedown(function(){return false})}}})},_dateFirstDayOfWeek:function(date){var self=this;var midnightCurrentDate=new Date(date.getFullYear(),date.getMonth(),date.getDate());var millisToSubtract=self._getAdjustedDayIndex(midnightCurrentDate)*86400000;return new Date(midnightCurrentDate.getTime()-millisToSubtract)},_dateLastDayOfWeek:function(date){var self=this;var midnightCurrentDate=new Date(date.getFullYear(),date.getMonth(),date.getDate());var millisToAdd=(6-self._getAdjustedDayIndex(midnightCurrentDate))*MILLIS_IN_DAY;return new Date(midnightCurrentDate.getTime()+millisToAdd)},_getAdjustedDayIndex:function(date){var midnightCurrentDate=new Date(date.getFullYear(),date.getMonth(),date.getDate());var currentDayOfStandardWeek=midnightCurrentDate.getDay();var days=[0,1,2,3,4,5,6];this._rotate(days,this.options.firstDayOfWeek);return days[currentDayOfStandardWeek]},_dateLastMilliOfWeek:function(date){var lastDayOfWeek=this._dateLastDayOfWeek(date);return new Date(lastDayOfWeek.getTime()+(MILLIS_IN_DAY))},_clearTime:function(d){d.setHours(0);d.setMinutes(0);d.setSeconds(0);d.setMilliseconds(0);return d},_addDays:function(d,n,keepTime){d.setDate(d.getDate()+n);if(keepTime){return d}return this._clearTime(d)},_rotate:function(a,p){for(var l=a.length,p=(Math.abs(p)>=l&&(p%=l),p<0&&(p+=l),p),i,x;p;p=(Math.ceil(l/p)-1)*p-l+(l=p)){for(i=l;i>p;x=a[--i],a[i]=a[i-p],a[i-p]=x){}}return a},_cloneDate:function(d){return new Date(d.getTime())},_cleanDate:function(d){if(typeof d=="string"){return $.weekCalendar.parseISO8601(d,true)||Date.parse(d)||new Date(parseInt(d))}if(typeof d=="number"){return new Date(d)}return d},_formatDate:function(date,format){var options=this.options;var returnStr="";for(var i=0;i