(function($) {

	$.fn.extend({
		calendar : function(config) {
			if($("#"+this.attr("id") + "_calendar_container").length == 0){
				this.options = $.extend({}, $.calendar.options, config);
				this.initialize();
			}
			return this;
		}
	});

	var calendar = {

		date : null, year : null, month : null, day : null, max_date : null, min_date : null, container_id : null, calendar_id : null, navigation_id : null,
		initialize : function(){

			this.date = new Date();

			if(this.val() == ""){ this.setInitialDate(this.date.getTime()); }
			else if(Date.parse(this.val()) < Date.parse("Jan 1, 1998")){ this.setInitialDate(this.date.getTime()); }
			else{ this.setDate(Date.parse(this.val())); }

			this.container();
			this.events();

		},

		events : function(){

			var element = this;
			this.keydown(function(){ return false; });
			this.focus(function(){ element.showCalendar(); });

		},

		showCalendar : function(){

			$(document).trigger("click");

			$("#"+this.calendar_id).empty();
			this.generate();

			$("#"+this.container_id).show();
			var element = this;
			$(document).click(function(e){ element.hideCalendar(e); });

		},

		hideCalendar : function(e){
			var target = $(e.target);
			if ($(target).attr("id") != $(this).attr("id") && target.parents("#"+this.container_id).length == 0){
				$("#"+this.container_id).hide();
				$(document).unbind("click");
			}
		},

		generate : function(){

			var day_of_week = this.dayOfWeek();
			var days_in_month = this.daysInMonth();
			var start_timestamp = Date.parse(this.year+"/"+this.month+"/1");
			var display_date = new Date();

			var html = "<tr class='calendar_header'><td>S</td><td>M</td><td>T</td><td>W</td><td>T</td><td>F</td><td>S</td></tr>";

			display_date.setTime(start_timestamp);
			display_date.setDate(display_date.getDate()-day_of_week);

			for(days=0;days<42;days++){

				if(display_date.getDay() == 0) html += "<tr>";
				if(display_date.getMonth() != this.date.getMonth()){ html += "<td class='calendar_old'>"+display_date.getDate()+"</td>"; }
				else if(display_date.getDate() == this.date.getDate() && this.isToday(display_date)){ html += "<td class='calendar_cell calendar_selected calendar_today'>"+display_date.getDate()+"</td>"; }
				else if(display_date.getDate() == this.date.getDate()){ html += "<td class='calendar_selected'>"+display_date.getDate()+"</td>"; }
				else if(this.isToday(display_date)){ html += "<td class='calendar_cell calendar_today'>"+display_date.getDate()+"</td>"; }
				else{ html += "<td class='calendar_cell'>"+display_date.getDate()+"</td>"; }

				if(display_date.getDay() == 6) html += "</tr>";
				display_date.setDate(display_date.getDate()+1);

			}

			$("#"+this.calendar_id).append(html);
			$("#"+this.navigation_id).find(".current").html(formatDate(this.date.getTime(), "mmmm yyyy"));

			var element = this;
			$("#"+this.container_id).find(".calendar_cell").click(function(){
				$(".calendar_selected").removeClass("calendar_selected").addClass("calendar_cell");
				$(this).addClass("calendar_selected").removeClass("calendar_cell");
				element.changeDate($(this).html());
                element.hideCalendar($(this)); //-- MOD: 2009/06/15 10:34:13 C.C.
			});

            //-- MOD: 2009/06/15 10:34:13 C.C. Start
            $("#"+this.container_id).find(".calendar_selected").click(function(){
                element.hideCalendar($(this));
            });
            //-- MOD: 2009/06/15 10:34:13 C.C. End

		},

		container : function(){

			var goleft = this.offset().left;
			this.container_id = this.attr("id") + "_calendar_container";
			var container = $("<div></div>").attr({ id : this.container_id }).addClass("calendar_container");
			$(container).addClass("calendar_tbl").css({ display : "none", left : goleft });
			this.after(container);

			this.calendar_id = this.attr("id") + "_calendar";
			var display = $("<table cellspacing='0'></table>").attr({ id : this.calendar_id }).addClass("calendar_tbl");
			$("#"+this.container_id).append(display);

			this.navigation();

		},

		navigation : function(){

			html = "<tr class='calendar_header'>"
				+"<td style='cursor: pointer;' class='calendar_previous'> < </td>"
				+"<td colspan='5' class='current'></td>"
				+"<td style='cursor: pointer;' class='calendar_next'> > </td>"
				+"</tr>";

			this.navigation_id = this.attr("id") + "_navigation";
			var display = $("<table cellspacing='0'></table>").attr({ id : this.navigation_id }).addClass("calendar_tbl").html(html);
			$("#"+this.container_id).append(display);

			var element = this;
			$("#"+this.navigation_id).find(".calendar_previous").click(function(){ element.previousCalendar(); });
			$("#"+this.navigation_id).find(".calendar_next").click(function(){ element.nextCalendar(); });

		},

		previousCalendar : function(){
			this.date.setMonth(this.date.getMonth() - 1);
			this.setDate(this.date.getTime());
			$("#"+this.calendar_id).empty();
			this.generate();
		},

		nextCalendar : function(){
			this.date.setMonth(this.date.getMonth() + 1);
			this.setDate(this.date.getTime());
			$("#"+this.calendar_id).empty();
			this.generate();
		},

		changeDate : function(day){
			var timestamp = Date.parse(this.year+"/"+this.month+"/"+day);
			this.setDate(timestamp);
			$(this).trigger("relativeDateChanged");
		},

		setDate : function(timestamp){
			this.date.setTime(timestamp);
			this.day = this.date.getDate();
			this.month = this.date.getMonth() + 1;
			this.year = this.date.getFullYear();
			$(this).val(formatDate(this.date.getTime(), "mmm d, yyyy"));
		},

		setInitialDate : function(timestamp){
			this.date.setTime(timestamp);
			this.day = this.date.getDate();
			this.month = this.date.getMonth() + 1;
			this.year = this.date.getFullYear();
			$(this).val("");
		},

		dayOfWeek : function(){
			var date = new Date();
			date.setTime(Date.parse(this.year+"/"+this.month+"/1"));
			if(date.getDay() == 0){ return 7; }
			else{ return date.getDay(); }
		},

		daysInMonth : function(){
			var date = new Date();
			date.setTime(Date.parse(this.year+"/"+this.month+"/1"));
			for(i=1;i<=31;i++){
				date.setDate(date.getDate()+1);
				if((date.getMonth()+1) != this.month){ return i; }
			}
		},

		isToday : function(date){
			if(date.getFullYear() == new Date().getFullYear() && date.getMonth() == new Date().getMonth()	&& date.getDate() == new Date().getDate()){
				return true;
			}else{
				return false;
			}
		},

		getDate : function(){
			var return_date = new Date();
			return_date.setTime(this.date.getTime());
			return return_date;
		}

	};

	$.each(calendar, function(i){ $.fn[i] = this; });

	$.calendar = {
		options : {}
	};

})(jQuery);
