if (typeof Date.prototype.getFullYear == "undefined") {
  Date.prototype.getFullYear = function() {
    var y = this.getYear();
    if (y < 1900) y += 1900;
    return y;
  };
}

Date.prototype.clone = function () {
  return new Date(this.getTime());
}

// BEGIN: DATE OBJECT PATCHES

/** Adds the number of days array to the Date object. */
Date._MD = new Array(31,28,31,30,31,30,31,31,30,31,30,31);

/** Constants used for time computations */
Date.SECOND = 1000 /* milliseconds */;
Date.MINUTE = 60 * Date.SECOND;
Date.HOUR   = 60 * Date.MINUTE;
Date.DAY    = 24 * Date.HOUR;
Date.WEEK   =  7 * Date.DAY;

/** Returns the number of days in the current month */
Date.prototype.getMonthDays = function(month) {
  var year = this.getFullYear();
  if (typeof month == "undefined") {
    month = this.getMonth();
  }
  if (((0 == (year%4)) && ( (0 != (year%100)) || (0 == (year%400)))) && month == 1) {
    return 29;
  } else {
    return Date._MD[month];
  }
};

/** Returns the number of day in the year. */
Date.prototype.getDayOfYear = function() {
  var now = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
  var then = new Date(this.getFullYear(), 0, 0, 0, 0, 0);
  var time = now - then;
  return Math.floor(time / Date.DAY);
};

/** Returns the number of the week in year, as defined in ISO 8601. */
Date.prototype.getWeekNumber = function() {
  var d = new Date(this.getFullYear(), this.getMonth(), this.getDate(), 0, 0, 0);
  var DoW = d.getDay();
  d.setDate(d.getDate() - (DoW + 6) % 7 + 3); // Nearest Thu
  var ms = d.valueOf(); // GMT
  d.setMonth(0);
  d.setDate(4); // Thu in Week 1
  return Math.round((ms - d.valueOf()) / (7 * 864e5)) + 1;
};

if(typeof VYRE === "undefined") {
    VYRE = {
        name:"VYRE"
    };
}

VYRE.Calendar = function (settings) {
    this.container = null;
    this.title="put title here";
    this.nextText="  »";
    this.previousText="«  ";
    this.shiftOnInactive = false;
    if( typeof settings != "undefined" ) {
        for( var property in this) {
            if(typeof settings[property] != "undefined") {
                this[property] = settings[property];
            }
        }
    }
    this.clickHandler = function () {};
    this.callBackFunction = function () {};
    this.date = new Date();
    this.date.setDate(1);
};

VYRE.Calendar.months = ["January","February","March","April","May","June","July","August","September","October","November","December"];

VYRE.Calendar.prototype = {
    
    init : function (){
        var self = this;
        this.makeCalendar();
    },
    getFirstDay : function () {;
        startDate = new Date();
        startDate.setFullYear(this.date.getFullYear(),this.date.getMonth(),1);
        var firstDay = startDate.getDay();
        if(firstDay == 0) {firstDay = 7;}
        return firstDay;
    }, 
    makeCalendar : function () {
		var self = this;
		
		var startDay = this.getFirstDay();
		var daysInMonth = this.date.getMonthDays();
		var month = this.date.getMonth();
		var year = this.date.getFullYear();
		var endLoop = (Math.ceil((startDay + daysInMonth -1 )/7))*7;
		var today = new Date();
		
		var previousMonth = new Date();
                previousMonth.setDate(1);
		previousMonth.setMonth(this.date.getMonth()-1);
		previousMonthYear = previousMonth.getFullYear();
		previousMonthDays = previousMonth.getMonthDays();
		
		str="<h2><span>{title}</span></h2><div class='container'><div class='inner'>".supplant({title:this.title});
		str += "<h3><span id ='calPrev'>{previousText}</span><span class = 'monthYear'>{month} {year}</span><span id ='calNext'>{nextText}</span></h3>".supplant({month:VYRE.Calendar.months[month],year:year, previousText:this.previousText, nextText:this.nextText});
		str+="<table id=\"calendar\" border ='0' cellspacing ='0' cellpadding ='0'><thead><tr><th class=\"first\"><span>M</span></th><th><span>T</span></th><th><span>W</span></th><th><span>Th</span></th><th><span>Fr</span></th><th><span>Sa</span></th><th class=\"last\"><span>Su</span></th></tr></thead><tbody>";
		for(var i = 1;i<=endLoop; i++ ) {
			var mod = i % 7;
			if(mod == 1) {
				if(i<7) {
					str+="<tr class=\"first\">";
				} else if((i +7)>=endLoop){
					str+="<tr class=\"last\">";
				} else {
					str+="<tr>";
				}
			}
			var day1 = i-startDay +1 ;
			var extraClass=" d"+i%2;  
			
			var	dayText = "<span>{day}</span>".supplant({day:day1});
			if(today.getFullYear() == year && today.getMonth() == month && day1 == today.getDate()) {
				extraClass+=" today";
			}
			if(mod == 1){ extraClass += " first";}
			if(mod == 0){ extraClass += " last";}

			if(i < startDay) {
				var previousMonthDay =previousMonthDays -( startDay - i-1);
				var previousMonthDayText = "<span>{day}</span>".supplant({day:previousMonthDay});
				str += "<td id ='td{year}{month}{day}' class ='inactive{extraClass}'>{dayText}</td>".supplant({day:previousMonthDay,dayText:previousMonthDayText,extraClass:extraClass, month:previousMonth.getMonth(), year:previousMonthYear});
			} else if(day1 > daysInMonth){
				var nextMonthDay = day1 - daysInMonth;
				var nextMonthDayText = "<span>{day}</span>".supplant({day:nextMonthDay});
				var nextMonthYear = (month == 11)? year +1: year;
				str += "<td id ='td{year}{month}{day}' class ='inactive{extraClass}'>{dayText}</td>".supplant({day:nextMonthDay,dayText:nextMonthDayText,extraClass:extraClass, month:(month ==11)? 0 : month +1, year:nextMonthYear});		
			} else {
				str += "<td id ='td{year}{month}{day}' class ='active{extraClass}'>{dayText}</td>".supplant({day:day1,dayText:dayText,extraClass:extraClass, month:month, year:year});
			}
			if(mod == 0) {
				str+="</tr>";
			}
		}
		str+="</tbody></table></div><div class=\"clearer\"></div></div>";
		this.container.innerHTML = str;

		VYRE.Utils.gE("calPrev").onclick = function () {
			self.previous();
		};
		VYRE.Utils.gE("calNext").onclick = function () {
			self.next();
		};
		VYRE.Utils.gE("calendar").onmousedown= function (e) {
			var e = e || event;
			var targ = e.target || e.srcElement;
			var element = null;
			var clickedDate = self.date.clone();
			if(targ.nodeName=="TD") {
				element = targ.childNodes[0];
			} else if(targ.nodeName=="SPAN"){
				element = targ
			}

			if(element){
				var day = element.innerHTML;
				if(element.parentNode.className.indexOf("inactive") != -1){
					if(day <10) {
						clickedDate.setMonth(clickedDate.getMonth()+1);
					} else {
						clickedDate.setMonth(clickedDate.getMonth()-1);
					}
					if(self.shiftOnInactive) {
						self.date = clickedDate
						self.makeCalendar();
					}
				}
				
				if(day > 0) {
					clickedDate.setDate(day);
					self.clickHandler(clickedDate);
				}
			}

		};    
		this.callBackFunction();
    },
    keepDoubleDigit : function (number) {
        if(parseInt(number) <10) {number = "0"+number;}
        return number;
    },
    next : function () {
		this.date.setMonth(this.date.getMonth()+1);
		this.makeCalendar();
    },
    
    previous : function () {
		this.date.setMonth(this.date.getMonth()-1);
		this.makeCalendar();
    }
    
};



VYRE.CalendarSearch = function (settings) {
	this.calendar = null;
	this.ajaxSearch = null;
	this.dayOffset = 0;
	this.additionalDays = 21;
	this.lucenePrefix = null;
    if( typeof settings != "undefined" ) {
        for( var property in this) {
            if(typeof settings[property] != "undefined") {
                this[property] = settings[property];
            }
        }
    }
    this.currentDate = new Date();
    
    this.cookieName = window.location.href.replace(/[\.|:|\/|\?|&]/g,"_");
    
	this.init();
};

VYRE.CalendarSearch.prototype = {
	init : function () {
		var self = this;

		
		this.calendar.clickHandler = function (date) {
			self.click(date);
		}
		this.calendar.callBackFunction = function () {
			self.highlightDays();
		}
		
		var time = VYRE.Utils.Cookie.read(this.cookieName);
		if(time != null) {
			this.currentDate = new Date(Number(time));
			this.calendar.date = new Date(Number(time));
			this.calendar.date.setDate(1);
			this.calendar.makeCalendar();
		}
		
		this.click(this.currentDate);
	},
	
	click : function (date) {
	  if(this.ajaxSearch.canSearch == true) {
		  this.currentDate = date.clone();
		  var vyreDate = new VYRE.Date();
		  vyreDate.setJSDate(date.clone());
		  vyreDate.addDays(this.dayOffset);
		  var vyreDate2 = new VYRE.Date();
		  vyreDate2.setJSDate(date.clone());
		  vyreDate2.addDays(this.additionalDays + this.dayOffset);
		  var luceneDate="["+vyreDate.getLuceneString().substring(0,8) +"000000 TO "+vyreDate2.getLuceneString().substring(0,8)+"000000]";
		  this.ajaxSearch.attributes.set(new VYRE.Attribute(this.lucenePrefix,luceneDate));
		  this.ajaxSearch.search(); 
		  this.highlightDays();  
	  	  
	  	  VYRE.Utils.Cookie.create(this.cookieName,this.currentDate.getTime(), 1);
	  }		
	}, 
	generateArrows : function () {
		var self = this;
		if(!(VYRE.Utils.gE("prevM") && VYRE.Utils.gE("nextM"))) {
			this.spanPrev = VYRE.Utils.createElement({tag:"span",id:"prevM", innerText:this.calendar.previousText});
			this.spanPrev.style.display="none";
			this.spanNext = VYRE.Utils.createElement({tag:"span",id:"nextM", innerText:this.calendar.nextText});
			this.spanNext.style.display="none";
			//this.calendar.container.appendChild(this.spanPrev);
			//this.calendar.container.appendChild(this.spanNext);
			$("#calendarWidget .inner table").before(this.spanPrev).after(this.spanNext);
		}

		this.spanPrev.onclick = function () {
			self.calendar.previous();
		}

		this.spanNext.onclick = function () {
			self.calendar.next();
		}
	
	},
	highlightDays : function () {
	

		this.generateArrows();
	
		var dateAcc = this.currentDate.clone();
		dateAcc.setDate(dateAcc.getDate()+this.dayOffset);
		$("#calendarWidget td").removeClass("current").removeClass("selected").removeClass("start").removeClass("end");
		
		var dateExists = false;
		var previousExists = false;
		var nextExists = false;
		for(var i = this.dayOffset; i<= (this.additionalDays+this.dayOffset); i++) {
			var  d = dateAcc.getDate();
			var  m = dateAcc.getMonth();
			var ye = dateAcc.getFullYear();
			var dateId = "#td"+ye+m+d;
			if(typeof $(dateId)[0] != "undefined") {
				dateExists = true;
				if(i==this.dayOffset) {
					previousExists = true;
				}
				if(i==(this.additionalDays+this.dayOffset)) {
					nextExists = true;
				}
			} 
			$(dateId).addClass("selected");
			if(i == this.dayOffset) {
				$(dateId).addClass("start");  
			}
			if(i == 0) {
				$(dateId).addClass("current");  	  		
			}
			if(i == (this.additionalDays+this.dayOffset)) {
				$(dateId).addClass("end");  
			}
			dateAcc.setDate(dateAcc.getDate()+1);
		}		
		
		if(dateExists == true) {
			this.spanPrev.style.display = (previousExists)? "none" : "block";
			this.spanNext.style.display = (nextExists)? "none" : "block";
		} else {
			this.spanPrev.style.display = "none";
			this.spanNext.style.display = "none";			
		}
	}
};

