HJ.NewHomePageCalendar = Class.create();

HJ.NewHomePageCalendar.prototype = Object.extend(new HJ.Calendar(), {

    /**
     * @param signedIn true if we are signed in, false otherwise
     * 
     * @param table 
     *  A table of 7 rows, two cells in each row.  First row is the
     *  title, second row holds the events
     * 
     * @param weeks 
     * a 6-long array, each entry of which is a 
     * 7-long array (a week).  Each week contains a reference to the
     * list items <li> that are to contain the numbers and anchors of each 
     * day. 
     * The class of each item will be set to "past" for days in the previous
     * month, empty for the days in the current month, and "today" for 
     * today. 
     *
     * @param weeksContainer 
     * a container of weeks on which to set onclick
     * 
     * @param monthName 
     * an element (a span) to contain the month name
     *
     * @param previousMonth 
     * an element that's clicked to go to the previous month
     * 
     * @param nextMonth 
     * an element that's clicked to go to the next month
     */
	initialize: function(signedIn, 
                         weekTable, 
                         weeks, 
                         weeksContainer,
                         monthName, 
                         previousMonth, 
                         nextMonth) {
        this.signedIn = signedIn;
        this.weekTable = weekTable;
        this.weeks = weeks;
        this.weeksContainer = weeksContainer;
        this.monthName = monthName;
        this.previousMonth = previousMonth;
        this.nextMonth = nextMonth;
        this.DATE_CELL = 0;
        this.EVENTS_CELL = 1;
        this.DAYS_TO_DISPLAY = 7;
        
        // milliseconds in a day
        this.DAY_MILLISECONDS = 86400000;

        if (this.signedIn) {
            // XXX: tableClicked is defined in BaseCalendar
            // we should probably just use our own here.
            // (see Event handler in Archive.js)
            this.weekTable.onclick 
                = this.tableClicked.bindAsEventListener(this);
        }
        this.previousMonth.onclick 
            = this.previousMonthClicked.bindAsEventListener(this);
        this.nextMonth.onclick 
            = this.nextMonthClicked.bindAsEventListener(this);

        this.weeksContainer.onclick 
            = this.weeksContainerClicked.bindAsEventListener(this);

        this.LAST_MONTH="LM_";
        this.THIS_MONTH="TM_";
        this.NEXT_MONTH="NM_";
        this.firstTime = true;
    },

    cleanup: function() {
        // XXX: need to cleanup click handlers, etc. 
        // See WeeklyCalendar and BaseCalendar
    },

	render: function(schedules, date) {
        // mostly copied from WeeklyCalendar.js.  It might be better 
        // to extend weekly calendar, but that would be lots of 
        // code changes, especially since WeeklyCalendar does the 
        // remove and replace pattern, rather than filling in the 
        // elements, which we do here.
        this.schedules = schedules;
        this.date = date;

        // make sure we have the events for the correct month loaded. 
        // we will get another render call from Schedules.js when the 
        // data has been received. 
        if (this.signedIn) {
        	if (this.firstTime) {
        		this.firstTime = false;
            	app.schedule.loadEventData(this.date, true); // force loading of event data for the first time
        	} else {
            	app.schedule.loadEventData(this.date);
        	}
        }

        // render the monthly calendar view
        this.renderWeeks(date);
        this.monthName.innerHTML = this.months[date.getMonth()];

        this.startTime = new Date(this.date.getTime());
        this.endTime = new Date(this.startTime.getTime());
        this.endTime.setDate(this.endTime.getDate() + this.DAYS_TO_DISPLAY);
        var dt = new Date(this.startTime.getTime());

        // Set the contents of the headers
        var dt = new Date(this.startTime.getTime());
        for (var i=0; i < this.DAYS_TO_DISPLAY; i++) {
            // XXX: better date format
            var row = this.weekTable.rows[i];
            var dateCell = row.cells[this.DATE_CELL];
            dateCell.className = 'homepageDateTD';
			if (i==0) {
            	dateCell.innerHTML             
                = "<div class=\"dateOrange\">" + "<span>" + this.daysLong[dt.getDay()] + "</span>" + "<div class=\"dateNumberOrange\">" + dt.getDate() + "</div></div>"; 	
			}
            else {
            	dateCell.innerHTML             
                = "<div class=\"date\">" + "<span>" + this.daysLong[dt.getDay()] + "</span>" + "<div class=\"dateNumber\">" + dt.getDate() + "</div></div>"; 
            }    
                //this.months[dt.getMonth()] + " " + dt.getDate();
            // clear events cell
            var eventsCell = row.cells[this.EVENTS_CELL];
            eventsCell.innerHTML = "";
            // don't need to clear the events cell
            dt.setDate(dt.getDate() + 1);
        }

        if (this.signedIn) {
            this.renderEvents(this.weekTable);
            if (HJ.getPostLoginAction() != null && 
            	HJ.getPostLoginAction() == HJ.POST_LOGIN_ACTION_ADD_EVENT &&
            	!HJ.postLoginActionProcessed) {
            	HJ.postLoginActionProcessed = true;
            	this.addEventClicked();
            }
        }
    }, 

    setNewDate: function(d) {
        if (this.signedIn) {
            app.schedule.setCalendarDate(d);
        } else {
            this.render(this.schedules, d);
        }
    },

    // XXX: not yet used
    next: function() {
        var d = this.date;
        d.setDate(d.getDate() + this.DAYS_TO_DISPLAY);
        this.setNewDate(d);
	},
	
    // XXX: not yet used
	previous: function() {
        var d = this.date;
        d.setDate(d.getDate() - this.DAYS_TO_DISPLAY);
        this.setNewDate(d);
	},

    nextMonthClicked: function(event) {
        var d = new Date(this.date);
        d.setMonth(d.getMonth() + 1);
        this.setNewDate(d);
    },

    previousMonthClicked: function(event) {
        var d = new Date(this.date);
        d.setMonth(d.getMonth() - 1);
        this.setNewDate(d);
    },

    // Mostly copied from MonthlyCalendar.js.  This functions looks
    // rather generic, and so could be move to BaseCalendar.js
    // only called if this.signedIn 
	renderEvents: function(tbl) {
	  
    	var startTimeInInt = this.startTime.getTime();
	   var dt1 = new Date(this.startTime.getTime());
       var row = 0;
	   while(dt1.getTime() < this.endTime.getTime()) {
           if (row >= this.DAYS_TO_DISPLAY) {
               alert("NewHomePageCalendar: ran out of rows");
               break;
           }
           var dt2 = new Date(dt1.getTime());
           dt2.setDate(dt2.getDate() + 1);
	     
           var t1 = dt1.getTime();
           var t2 = dt2.getTime();
	     
           var m = new Array();
	
           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 (tempDt.getTime() <= t1 && (event["repeatFlag"] + "" == "true")) {
                           // gaserre, 3/12/08: 
                           // I have no idea what deletedSeqList
                           // or modifiedSeqList are really used for
                           if (event["deletedSeqList"] == null) {
                               setEventDeleteSeqList(event);
                           }
                           if (event["modifiedSeqList"] == null) {
                               setEventModifySeqList(event);
                           }
                           if (!isEventInSeq(event, dt1.getTime())) {
                               continue;
                           }
                           event = this.getRpt(event, dt1, dt1, dt2);
                           if (event == null) {
                               continue;
                           }
                           s = dt1.getTime();
                       } else if (s < t1 || s >= t2) {
                           continue;
                       }
	              
	              
                       var temp = new Date(s);
                       var nday = this.getDayNumber(s) - 1;
                       if (nday < 0) {
                           debugA(event.displayName + " : " + temp.toString());
                           continue;
                       }
                       // Monthly row calculation
                       // var r = parseInt(nday / 7);
                       // var c = nday % 7;
                       // keep extra vars for now to retain similarity 
                       // with Monthly version
                  
                       var o = new Object();
                       o.schedule = sc;
                       o.scindex = i;
                       o.event = event;
                       o.eventindex = j;
                       o.link = this.getEventLink(sc, i, event, j, dt1.getTime());
                       // note: o.r and o.c are not used (I think) for this 
                       // calendar
                       o.r = row;
                       o.c = this.EVENTS_CELL;
	              
                       m.push(o);
                  
                       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);
                       }
	             
                   }
               }
           }
	       m.sort(eventOrder);

           var cell = tbl.rows[row].cells[this.EVENTS_CELL];
	       var ul = document.createElement("ul");
           for (j=0; j<m.length; j++) {
               var o = m[j];
               // note: o.link is already a li
               ul.appendChild(o.link);
           }
           cell.appendChild(ul);
           dt1 = dt2;
           row++;
	   }
	},

    renderWeeks: function(date) {
        var d = new Date(date.getTime());
        // set to start of the month
        d.setDate(1);
        var day = d.getDay();
        week = this.weeks[0];
        weekIndex = 0;

        var now = new Date();
        var today = now.getDate();
        if (now.getMonth() != date.getMonth() 
            || now.getFullYear() != date.getFullYear()) {
            // not in the right month. 
            today = -1;
        }

        if (day > 0) {
            // fill in the last dates of the previous month before date 1
            // of the current month
            var prevMonth = new Date(d.getTime() - this.DAY_MILLISECONDS);
            var prevDate = prevMonth.getDate();
            while (day > 0) {
                day--;
                week[day].innerHTML = "";
                week[day].className = "past";
                week[day].appendChild(this.createDayAnchor(prevDate, false, true));
                prevDate--;
            }
            day = d.getDay();
        }
        var startMonth = d.getMonth();
        var inNextMonth = false;
        while (true) {
            var d_date = d.getDate();
            var a = this.createDayAnchor(d_date, inNextMonth, false);
            var div = week[day];
            div.innerHTML = "";
            if (inNextMonth) {
                div.className = "future";
            } else if (d_date == today) {
                div.className = "today";
            } else {
                div.className = "";
            }
            div.appendChild(a);

            d.setDate(d_date + 1);
            day = d.getDay();
            if (d.getMonth() != startMonth) {
                inNextMonth = true;
            }
            if (day == 0) {
                // rolled back to Sunday
                if (inNextMonth ) {
                    // done
                    break;
                }
                weekIndex++;
                week = this.weeks[weekIndex];
            }
        }
        // fill in the last row (if any) with empty
        weekIndex++;
        if (weekIndex < this.weeks.length) {
            week = this.weeks[weekIndex];
            for (var i = 0; i < 7; i++) {
                week[i].innerHTML = "";
            }
        }
    },

    createDayAnchor: function(date, inFuture, inPast) {
        var a = document.createElement('a');
        a.innerHTML = date;
        a.href = "#";
        if (inFuture) {
            a.id = this.NEXT_MONTH + date;
        } else if (inPast) {
            a.id = this.LAST_MONTH + date;
        } else {
            a.id = this.THIS_MONTH + date;
        }
        return a;
    },

    // only called if this.signedIn
	getEventLink: function(sc, scindex, event, eventindex, eventName) {
	   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.id = "E_" + scindex + "_" + eventindex;
          a.style.margin = "0 -2px";
          return a;
       } else {
		   var li = document.createElement('li');
		   if (bc != null) {		   	  
               // XXX: It's not clear what we will
               // eventually want here
               // li.style.color = bc;
               // li.className = "frontPageSchedule";
		   }
		   
		   var a = document.createElement('a');
/*		   
          // Set background color for different schedules? 
          if (bc != null) {
			  a.style.backgroundColor = bc;
		   }
		   if (c != null) {
			  a.style.color = c;
		   }
*/ 		   
		   a.href = "#";
           var displayString = event.displayName + "<br>";
           if (event.timeFlag == "true") {
               displayString = getDisplayTimeFromMins(event.fromTime) 
                   + "&nbsp;&nbsp;" + displayString;
           }
		   a.innerHTML = displayString;
		   a.id = "E_" + scindex + "_" + eventindex;
           a.style.cursor = "move";
           if (eventName != null) {
         	  a.name = eventName;
           }

		   this.evtObj[a.id] = event;

           a.onmouseover = this.showToolTip.bindAsEventListener(this);
           li.appendChild(a);
		  return li;
	   }
	},
    // not implemented: WeeklyCalendar.showQuickEventDialog, 
    // other functions from WeeklyCalendar

    // only called if this.signedIn
    setAddEventOnClick: function(element) {
        element.onclick = this.addEventClicked.bindAsEventListener(this);
    },

    addEventClicked: function(clickEvent) {
        // check for paranoia.  
        // should not be called if not signed in
        if (this.signedIn) {
            app.schedule.addNewEvent(this.date);
        } else {
        	window.location.href ="/Signin.htm?"+HJ.POST_LOGIN_ACTION_PARAM+"="+HJ.POST_LOGIN_ACTION_ADD_EVENT;
        }
        return false;
    }, 

    weeksContainerClicked: function(event) {
        var target = event.target ? event.target : event.srcElement;
        if (target.tagName != 'A' || target.id == null) {
            // nothing to do
            return true;
        }

        var index = target.id.indexOf("_");
        if (index == -1) {
            return true;
        }
        index++;
        var whichMonth = target.id.substring(0, index);
        var dayOfMonth = target.id.substring(index);
        var date = new Date(this.date.getTime());
        switch (whichMonth) {
        case this.THIS_MONTH:
            // nothing
            break;
        case this.NEXT_MONTH:
            date.setMonth(date.getMonth() + 1);
            break;
        case this.LAST_MONTH:
            date.setMonth(date.getMonth() - 1);
            break;
        default:
            // not a supported action
            return true;
        }
        date.setDate(dayOfMonth);
        this.setNewDate(date);
    },

    // only called if this.signedIn
    eventChanged: function(event, wasDeleted) {
        if (document.getElementById("homePageCalendarContainer") == null) {
            // not displayed
            return;
        }
        this.render(this.schedules, this.date);
    }

});

