/*
*	日历组件
*
*
*	功能说明：
*		1、该日历组件组件提供选择单个日期及日期区间的功能，可自定义日历显示的月份数；
*	
*	使用方法：
*		$("#calendar_table").calendar({
*			startDateInputName: "start-date",	// 必须。保持时间区间开始日期的input元素name字段。如果不允许选取日期区间，则两个元素保持的值一样。
*			endDateInputName: "end-date",		// 必须。保持时间区间结束日期的input元素name字段。
*			startDateInputId: startDateInputId,	// 可选。保持时间区间开始日期的input元素id字段。
*			endDateInputId: endDateInputId,		// 可选。保持时间区间开始日期的input元素id字段。
*			prevTarget: prevTarget,				// 第一次调用时，该参数可省略；同一个标签重复调用生成日历是，该参数必填
*			enableSelectRange: true,			// 可选。是否允许选取日期区间。默认为true。
*			numberOfMonth: 3,					// 可选。日历中显示的月份数目。默认为显示3个月。
*			todayDate: "2013-06-03",			// 可选。初始显示日历的日期，格式为"yyyy-MM-dd"。
*			startDate: "2013-06-03",			// 可选。初始显示日历的选中区间的起始日期，格式为"yyyy-MM-dd"。
*			endDate: "2013-07-01"				// 可选。初始显示日历的选中区间的结束日期，格式为"yyyy-MM-dd"。
*		});
*
*	参数说明：如上所示
*
*
*	Author:	NieJinliang
*	Date:	2013.07.05
*
*
*
*	更新:
*		日期: 2013-07-17
*		说明：
*			1、所有与日历相关的元素都在该组件中拼接；
*			2、需提供保存所选日历区间起止日期的input的name字段；
*			3、添加限制只能选择单日的功能。
*		
*	
*		日期：2013-08-06
*		说明：
*			日历选择最近15天，最近一个月的功能，暂时在日历中不提供其他支持，由调用方实现。
*			在点击触发事件中传递新的参数重新调用日历组件生成一个新的日历。
*		示例：
*			// 前一次生成日历，使用变量保存日历
*			var prevTarget = $('#table_calendar').calendar(options);
*			
*			// 点击"button15"，清除选中最近15天
*			$("#button15").unbind().click(function() {
*				var options2 = {
*					startDateInputName: "start-date",
*					endDateInputName: "end-date",
*					numberOfMonth: 3,
*					todayDate: "2013-08-02",
*					startDate: "2013-07-19",
*					endDate: "2013-08-02",
*					prevTarget: prevTarget,	// 同一个标签重新生成日历，该参数必须
*					rangeDays: 31	// 所选日期区间范围大小
*				};
*					
*				$('#table_calendar').empty().calendar(options2);
*			});
*
*		
*		日期：2013-08-06
*			保持时间区间的input元素添加id属性，且为可选字段。
*
*
*
*		日期：2013-12-12
*		修改人：聂金良
*		修改内容：
*			添加参数rangeDays，表示所选日期的前后可选范围。默认值-1，表示没有范围限制。
*			如选中日期2013-11-01，那么另一个参数只能选择这一天的前后rangeDays范围内的日期，即只能选择2013-10-02至2013-12-01范围内的日期。
*
*
*/

var ebCalendar = {};

;(function($){
	$.fn.calendar = function(options) {
		var numberOfMonth = options.numberOfMonth || 3;	// 日历显示的月份个数
		var enableSelectRange = options.enableSelectRange;
		
		var target = this;
		var calendarContainer;
		var prefix = getUniqueId();
		var calendarContainerId = prefix + "-calendar-container";
		var dateRangeContainerId = prefix + "-date-range-container";
		var startDateInputName = options.startDateInputName;
		var endDateInputName = options.endDateInputName;
		var startDateInputId = options.startDateInputId;
		var endDateInputId = options.endDateInputId;
		
		var todayDate = options.todayDate;	// 当天日期
		var startDate = options.startDate;	// 选中的起始日期
		var endDate = options.endDate;	// 选中的结束日期
		var prevStartDate;
		var prevEndDate;
		var selectedDate = null;	// 已选中表格中的一个日期
		var rangeDays = options.rangeDays || -1;
		var dateFormatRegex = "yyyy-MM-dd";	// 日期格式化形式
		var dateFormatSplit = "-";
		var dateFormatRegex2 = "yyyy-MM-dd";
		var dateFormatSplit2 = "-";
		
		var containerDivClass ="calendar-box";
		var parentTableClass = "wrap";
		var parentTableTdClass = "cal-wrap";
		var tdClass = "date-thismonth";
		var selectedTdClass = "date-selected";
		var footerDivClass = "btn-bar clearfix";
		var tipDivClass = "date-select-tip";
		var monthHeadClass = "cal-head";
		var monthHeadSelectdClass = "cal-head-selected";
		var prevMonthClass = "prevmonth";
		var nextMonthClass = "nextmonth";
		var nextMonthEndClass = "nextmonth-ed";
		var prevMonthActiveClass = "prevmonth-active";
		var nextMonthActiveClass = "nextmonth-active";
		var prevYearClass = "prevyear";
		var nextYearClass = "nextyear";
		var dateChangeClass = "date-change";
		var dateRangeTargetDropClass = " drop";
		var dateInvalidClass = "date-invalid";
		
		return init();
		
		function init() {
			if (enableSelectRange == null) {
				enableSelectRange = true;
			}
			
			// 限制日历显示的月份数为1~5个
			if (numberOfMonth < 0 || numberOfMonth > 5) {
				return null;
			}
			
			// 设置（或转换）起止日期
			if (todayDate == null || todayDate == undefined || todayDate == '') {
				todayDate = new Date();
			} else {
				todayDate = stringToDate(todayDate, dateFormatRegex);
				if (todayDate == null) {
					return null;
				}
			}
			
			if (startDate == null || startDate == undefined  || startDate == '') {
				startDate = new Date();
			} else {
				startDate = stringToDate(startDate, dateFormatRegex);
				if (startDate == null) {
					return null;
				}
			}
			
			if (endDate == null || endDate == undefined  || endDate == '') {
				endDate = new Date();
			} else {
				endDate = stringToDate(endDate, dateFormatRegex);
				if (endDate == null) {
					return null;
				}
			}
			
			// 如果传过来的起止日期不符合要求，重置为当前日期
			if (compareDate(startDate, endDate) > 0) {
				startDate = new Date();
				endDate = new Date();
			}
			
			prevStartDate = startDate;
			prevEndDate = endDate;
			
			// 创建显示所选日期区间的a元素
			var dateRangeContainerA = document.createElement("a");
			dateRangeContainerA.onclick = toggleShowCalendar;	// 绑定点击事件：点击即显示日历
			dateRangeContainerA.id = dateRangeContainerId;
			dateRangeContainerA.className = "div-data-select cur";
			dateRangeContainerA.setAttribute("href", "javascript:void(0)");
			target.append(dateRangeContainerA);
			
			// 创建保持起始、结束日期的input元素
			var startDateInput = document.createElement("input");
			startDateInput.id = startDateInputId;
			startDateInput.setAttribute("name", startDateInputName);
			startDateInput.setAttribute("type", "hidden");
			target.append(startDateInput);
			
			var endDateInput = document.createElement("input");
			endDateInput.id = endDateInputId;
			endDateInput.setAttribute("name", endDateInputName);
			endDateInput.setAttribute("type", "hidden");
			target.append(endDateInput);
			
			// 创建日历
			var calendarDiv = document.createElement("div");
			calendarDiv.id = calendarContainerId;
			calendarDiv.className = containerDivClass;
			
			// 设置日历显示位置
			var left = $("#" + dateRangeContainerId).position().left + 118 - numberOfMonth * 160;
			var top = $("#" + dateRangeContainerId).position().top + 18;
			calendarDiv.setAttribute("style", "display: block; top: " + top + "px; left:" + left + "px;");
			
			target.append(calendarDiv);
			
			calendarContainer = $(calendarDiv);
			renderCalendar(calendarContainer);
			calendarContainer.hide();
			
			// 解绑前一个日历的点击事件
			if (options.prevTarget && options.prevTarget.length > 0) {
				$(document).unbind('mousedown', options.prevTarget.closeCalendar);
			}
			
			$(document).bind('mousedown', closeCalendar);	// 绑定日历外的点击事件
			
			return target;
		}
		
		// 当点击超过当前日历组件范围，隐藏日历
		function closeCalendar(event) {
			var dateRangeTarget = document.getElementById(dateRangeContainerId);
			//解决系统dom删除后依然执行此部分的问题
			if(dateRangeTarget == null){
				event.preventDefault();
				return ;
			}
			if (event.target != dateRangeTarget) {
				var isChildAndSelf = false;
				$("#" + calendarContainerId).find('*').each(function(i, n) {
					if(event.target == n) {
						isChildAndSelf = true;
		            }
				});
				
				if (!isChildAndSelf) {
					cancelDateSelect();
				}
			}
		}
		
		// 切换显示日历
		function toggleShowCalendar() {
			if (calendarContainer.is(":hidden")) {
				// 设置样式
				var dateRangeTarget = document.getElementById(dateRangeContainerId);
				if (dateRangeTarget.className.indexOf(dateRangeTargetDropClass) < 0) {
					dateRangeTarget.className += dateRangeTargetDropClass;
				}
				
				// 保存原始值
				prevStartDate = new Date(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
				prevEndDate = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());
				
				renderCalendar(calendarContainer);
				
				calendarContainer.show();
			} else {
				cancelDateSelect();
			}
		}
		
		// 生成日历
		function renderCalendar(calendarContainer) {
			// 首先清空日历
			calendarContainer.empty();
			
			// 创建表格
			var tablesDiv = document.createElement("div");
			var parentTable = document.createElement("table");
			parentTable.className = parentTableClass;
			var tbody = document.createElement("tbody");
			
			// 生成第一列（上一年、上一月按钮）
			var tr = document.createElement("tr");
			var td = document.createElement("td");
			td.setAttribute("valign", "top");
			
			var prevYearDiv = document.createElement("div");
			prevYearDiv.id = prefix + "PrevYear";
			prevYearDiv.className = prevYearClass;
			prevYearDiv.onclick = prevYear;
			td.appendChild(prevYearDiv);
			
			var prevMonthDiv = document.createElement("div");
			prevMonthDiv.id = prefix + "PrevMonth";
			prevMonthDiv.className = prevMonthClass;
			prevMonthDiv.onclick = prevMonth;
			prevMonthDiv.onmousedown = setPrevMonthDivActive;
			prevMonthDiv.onmouseup = resetPrevMonthDivClass;
			td.appendChild(prevMonthDiv);
			
			tr.appendChild(td);
			
			// 生成月份表格
			for (var i = numberOfMonth; i > 0; i--) {
				td = document.createElement("td");
				td.setAttribute("valign", "top");
				td.className = parentTableTdClass;
				if (i == 1) {
					td.className += " cal-wrap-last";
				}
				
				var tmpDate = new Date(todayDate.getFullYear(), todayDate.getMonth() - i + 1, 1);
				td.appendChild(renderMonthTable(tmpDate.getFullYear(), tmpDate.getMonth()));
				tr.appendChild(td);
			}
			
			td = document.createElement("td");
			td.setAttribute("valign", "top");
			
			var nextYearDiv = document.createElement("div");
			nextYearDiv.id = prefix + "NextYear";
			nextYearDiv.className = nextYearClass;
			nextYearDiv.onclick = nextYear;
			td.appendChild(nextYearDiv);
			
			var nextMonthDiv = document.createElement("div");
			nextMonthDiv.id = prefix + "NextMonth";
			
			var currentDate = new Date();
			if (todayDate.getFullYear() > currentDate.getFullYear() || (	// 月份超出范围，隐藏下月按钮
				todayDate.getFullYear() == currentDate.getFullYear() && todayDate.getMonth() >= currentDate.getMonth())) {
				nextMonthDiv.className = nextMonthEndClass;
			} else {
				nextMonthDiv.className = nextMonthClass;
				nextMonthDiv.onclick = nextMonth;
				nextMonthDiv.onmousedown = setNextMonthDivActive;
				nextMonthDiv.onmouseup = resetNextMonthDivClass;
			}
			td.appendChild(nextMonthDiv);
			
			tr.appendChild(td);
			
			tbody.appendChild(tr);
			parentTable.appendChild(tbody);
			tablesDiv.appendChild(parentTable);
			calendarContainer.append(tablesDiv);
			
			var tipDiv = document.createElement("div");
			tipDiv.className = tipDivClass;
			tipDiv.setAttribute("style", "display: block;");
			calendarContainer.append(tipDiv);
			
			// 生成footer bar
			var footerDiv = document.createElement("div");
			footerDiv.className = footerDivClass;
			
			// 日期输入框
			var dateRangeDiv = document.createElement("div");
			dateRangeDiv.className = "date-range";
			
			// 月份数只有1个时或不能选择日期区间时隐藏日期输入框
			if  (numberOfMonth == 1 || !enableSelectRange) {
				dateRangeDiv.setAttribute("style", "display: none;");
			}
			
			var descSpan = document.createElement("span");
			descSpan.innerHTML = "日期区间";
			dateRangeDiv.appendChild(descSpan);
			
			var startDateInput = document.createElement("input");
			startDateInput.id = prefix + "startDate";
			startDateInput.type = "text";
			startDateInput.setAttribute("style", "IME-MODE: disabled");
			startDateInput.value="";
			startDateInput.setAttribute("placeholder", "起始日期");
			startDateInput.className = "date-start";
			startDateInput.setAttribute("maxlength", "10");
			startDateInput.onkeyup = inputStartDate;	// 绑定keyup事件
			dateRangeDiv.appendChild(startDateInput);
			
			var dateLinkSpan = document.createElement("span");
			dateLinkSpan.innerHTML = "-";
			dateRangeDiv.appendChild(dateLinkSpan);
			
			var endDateInput = document.createElement("input");
			endDateInput.id = prefix + "endDate";
			endDateInput.type = "text";
			endDateInput.setAttribute("style", "IME-MODE: disabled");
			endDateInput.value="";
			endDateInput.setAttribute("placeholder", "终止日期");
			endDateInput.className = "date-end";
			endDateInput.setAttribute("maxlength", "10");
			endDateInput.onkeyup = inputEndDate;	// 绑定keyup事件
			dateRangeDiv.appendChild(endDateInput);
			
			footerDiv.appendChild(dateRangeDiv);
			
			// 按钮
			var dateChangeDiv = document.createElement("div");
			dateChangeDiv.className = dateChangeClass;
			var changeDateInput = document.createElement("input");
			changeDateInput.id = prefix + "ChangeDate";
			changeDateInput.type = "button";
			changeDateInput.value = "确定";
			changeDateInput.onclick = submitDateSelect;
			dateChangeDiv.appendChild(changeDateInput);
			
			var cancelChangeDateInput = document.createElement("input");
			cancelChangeDateInput.id = prefix + "CancelChangeDate";
			cancelChangeDateInput.type = "button";
			cancelChangeDateInput.value = "取消";
			cancelChangeDateInput.onclick = cancelDateSelect;
			dateChangeDiv.appendChild(cancelChangeDateInput);
		
			footerDiv.appendChild(dateChangeDiv);
			calendarContainer.append(footerDiv);
			
			selectedDateRange(startDate, endDate);
			
			// 刷新选中日期保存框
			renderSelectedDateInput(dateFormatRegex);
		}
		
		// 提交日期选择数据
		function submitDateSelect() {
			// 重置样式
			var dateRangeTarget = document.getElementById(dateRangeContainerId);
			dateRangeTarget.className = dateRangeTarget.className.replace(dateRangeTargetDropClass, "");
			
			todayDate = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());
			prevStartDate = startDate;
			prevEndDate = endDate;
			
			selectedDate = null;
			calendarContainer.hide();
			
			//执行回调函数
			if(options.callback){
				options.callback();
			}
		}
		
		// 取消日期选择
		function cancelDateSelect() {
			// 重置样式和值
			var dateRangeTarget = document.getElementById(dateRangeContainerId);
			
			dateRangeTarget.className = dateRangeTarget.className.replace(dateRangeTargetDropClass, "");
			startDate = new Date(prevStartDate.getFullYear(), prevStartDate.getMonth(), prevStartDate.getDate());
			endDate = new Date(prevEndDate.getFullYear(), prevEndDate.getMonth(), prevEndDate.getDate());
			setDateRangeTarget();
			
			todayDate = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());
			selectedDate = null;
			calendarContainer.hide();
		}
		
		// 输入完开始日期后触发
		function inputStartDate() {
			var startDateElem = document.getElementById(prefix + "startDate");
			var endDateElem = document.getElementById(prefix + "endDate");
			
			var tmpStartDate = stringToDate(startDateElem.value, dateFormatRegex);
			var tmpEndDate = stringToDate(endDateElem.value, dateFormatRegex);
			
			// 开始日期大于当天，重置为当天
			if (compareDate(tmpStartDate, new Date()) > 0) {
				tmpStartDate = new Date();
			}
			
			if (tmpStartDate == null) {
				setTip("开始日期输入有误，日期格式为" + dateFormatRegex);
				startDateElem.className = "date-start" +  " " + dateInvalidClass;
				return;
			} else if (compareDate(tmpStartDate, tmpEndDate) > 0) {
				setTip("结束日期不能小于开始日期");
				endDateElem.className = "date-end" +  " " + dateInvalidClass;
				return;
			}
			
			// 清除提示和样式
			clearTip();
			
			startDate = new Date(tmpStartDate.getFullYear(), tmpStartDate.getMonth(), tmpStartDate.getDate());
			endDate = new Date(tmpEndDate.getFullYear(), tmpEndDate.getMonth(), tmpEndDate.getDate());
			
			// 如果所选起止月份不在当前显示的日历中，则调整刷新日历的today参数
			if (endDate.getFullYear() != todayDate.getFullYear()
				|| endDate.getMonth() > todayDate.getMonth()
				|| endDate.getMonth() < (todayDate.getMonth() - numberOfMonth + 1)) {
				todayDate = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());
			}
			
			renderCalendar(calendarContainer);
		}
		
		// 输入完终止日期后触发
		function inputEndDate() {
			var startDateElem = document.getElementById(prefix + "startDate");
			var endDateElem = document.getElementById(prefix + "endDate");
			
			var tmpStartDate = stringToDate(startDateElem.value, dateFormatRegex);
			var tmpEndDate = stringToDate(endDateElem.value, dateFormatRegex);
			
			if (tmpEndDate == null) {
				setTip("结束日期输入有误，日期格式为" + dateFormatRegex);
				endDateElem.className = "date-end" +  " " + dateInvalidClass;
				return;
			} else if (compareDate(tmpEndDate, new Date()) > 0) {	// 终止日期大于当天，重置为当天
				tmpEndDate = new Date();
			}
			
			if (compareDate(tmpStartDate, tmpEndDate) > 0) {
				setTip("结束日期不能小于开始日期");
				endDateElem.className = "date-end" +  " " + dateInvalidClass;
				return;
			}
			
			// 清除提示和样式
			clearTip();
			
			startDate = new Date(tmpStartDate.getFullYear(), tmpStartDate.getMonth(), tmpStartDate.getDate());
			endDate = new Date(tmpEndDate.getFullYear(), tmpEndDate.getMonth(), tmpEndDate.getDate());
			
			// 如果所选起止月份不在当前显示的日历中，则调整刷新日历的today参数
			if (endDate.getFullYear() != todayDate.getFullYear()
				|| endDate.getMonth() > todayDate.getMonth()
				|| endDate.getMonth() < (todayDate.getMonth() - numberOfMonth + 1)) {
				todayDate = new Date(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());
			}
			
			renderCalendar(calendarContainer);
		}
		
		// 设置保存日期的目标元素的值为最新值
		function setDateRangeTarget() {
			var dateRangeTarget = document.getElementById(dateRangeContainerId);
			if (compareDate(startDate, endDate) == 0) {
				$("#" + dateRangeContainerId).text(formateDate(startDate, dateFormatRegex2));
			} else {
				$("#" + dateRangeContainerId).text(formateDate(startDate, dateFormatRegex2) + " 至 " + formateDate(endDate, dateFormatRegex2));
			}
			
			// 保持起止日期值
			target.find("input[name='" + startDateInputName + "']").val(formateDate(startDate, dateFormatRegex));
			target.find("input[name='" + endDateInputName + "']").val(formateDate(endDate, dateFormatRegex));
		}
		
		// 往前一年
		function prevYear() {
			todayDate.setYear(todayDate.getFullYear() - 1);
			renderCalendar(calendarContainer);
		}
		
		// 往后一年
		function nextYear() {
			var currentDate = new Date();
			if ( currentDate.getFullYear() - todayDate.getFullYear() >= 2
					|| (currentDate.getFullYear() - todayDate.getFullYear() == 1 && todayDate.getMonth() <= currentDate.getMonth())) {
				todayDate.setYear(todayDate.getFullYear() + 1);
				renderCalendar(calendarContainer);
			}
		}
		
		// 往前一月
		function prevMonth() {
			todayDate.setMonth(todayDate.getMonth() - 1);
			renderCalendar(calendarContainer);
		}
		
		// 往后一月
		function nextMonth() {
			todayDate.setMonth(todayDate.getMonth() + 1);
			renderCalendar(calendarContainer);
		}
		
		function setPrevMonthDivActive() {
			this.className = this.className + " " + prevMonthActiveClass;
		}
		
		function resetPrevMonthDivClass() {
			this.className = prevMonthClass;
		}
		
		function setNextMonthDivActive() {
			this.className = this.className + " " + nextMonthActiveClass;
		}
		
		function resetNextMonthDivClass() {
			this.className = nextMonthClass;
		}
		
		/*
			生成一个日历的月份表格
			
			参数：
				year：年
				month：月
		*/
		function renderMonthTable(year, month) {
			var NUM_OF_WEEK = 7;
			var WEEK_ARRAY = ["日", "一", "二", "三", "四", "五", "六"];
			
			var day = new Date(year, month, 1);
			var firstDay = day.getDay();	// 获取该月第一天是星期几
			day = new Date(year, month+1, 0);
			var days = day.getDate();	// 获取该月天数
			
			// 计算表格需要的行数
			var row = Math.floor((days + firstDay) / NUM_OF_WEEK) 
				+ ((days + firstDay) % NUM_OF_WEEK == 0 ? 0 : 1);
			
			var table = document.createElement("table");
			table.setAttribute("cellspacing", "0");
			table.setAttribute("cellpadding", "0");
			table.setAttribute("border", "0");
			
			var tbody = document.createElement('tbody');
			
			// 生成表头
			var tr = document.createElement("tr");
			for (var i = 0; i < NUM_OF_WEEK; i++) {
				var td = document.createElement("td");
				var node = document.createTextNode(WEEK_ARRAY[i]);
				td.appendChild(node);
				tr.appendChild(td);
			}
			tbody.appendChild(tr);
			
			// 生成表格主体内容
			var count = 1;
			var allowedStartDate = new Date();
			var allowedEndDate = new Date();
			if (rangeDays != -1 && selectedDate) {
				allowedStartDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate() - rangeDays + 1);
				allowedEndDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate() + rangeDays - 1);
			}
			for (var i = 0; i < row && count <= days; i++) {
				var tr = document.createElement("tr");
				var j = 0;
				if (i == 0) {
					for (;j < firstDay; j++) {
						var td = document.createElement("td");
						tr.appendChild(td);
					}
				}
				for (;j < NUM_OF_WEEK; j++, count++) {
					var td = document.createElement("td");
					if (count <= days) {
						var node = document.createTextNode(count);
						td.className = tdClass;
						td.setAttribute("d", count);
						td.setAttribute("m", month );
						td.setAttribute("y", year);
						td.setAttribute("sign", "month");
						td.onclick = selectThisDay; // 绑定点击事件
						td.appendChild(node);
					}
					
					// 判断日期是否在当天之后
					if (compareDate(new Date(year, month, count), new Date()) > 0
							|| (rangeDays != -1 && selectedDate && (compareDate(new Date(year, month, count), allowedStartDate) < 0 
									|| compareDate(new Date(year, month, count), allowedEndDate) > 0))) {
						td.setAttribute("style", "color:#999;cursor:default;background:#fff");
					}
					
					tr.appendChild(td);
				}
				tbody.appendChild(tr);
			}

			table.appendChild(tbody);
			table.setAttribute("border", "1");
			
			var parentDiv = document.createElement("div");
			var divMonth = document.createElement("div");
			divMonth.id = prefix + "Calendar" + year + month;
			divMonth.setAttribute("m", month);
			divMonth.setAttribute("y", year);
			divMonth.setAttribute("sign", "month");
			divMonth.className = monthHeadClass;
			divMonth.innerHTML = year + "年" + (++month) + "月";
			
			// 如果可以选择日期区间，则绑定事件
			if (enableSelectRange) {
				divMonth.onclick = selectThisMonth;	// 绑定点击事件
			}
			
			parentDiv.appendChild(divMonth);
			parentDiv.appendChild(table);
			
			return parentDiv;
		}
		
		// 选中当月
		function selectThisMonth() {
			var year = this.getAttribute("y"),
			month = this.getAttribute("m");
			var tmpStartDate = new Date(year, month, 1);
			var tmpEndDate = new Date(year, ++month, 0);
			
			// 点击的月份超过当天
			if (compareDate(tmpEndDate, new Date()) > 0) {
				setTip("月份超过当月");
				return;
			}
			clearTip();
			
			// 刷新月份表格头部样式
			var selectddMonths = getElementsByClassName(monthHeadSelectdClass, "div");
			for (var i = 0; i < selectddMonths.length; i++) {
				selectddMonths[i].className = monthHeadClass;
			}
			
			this.className = monthHeadSelectdClass;
			
			startDate = new Date(tmpStartDate.getFullYear(), tmpStartDate.getMonth(), tmpStartDate.getDate());
			endDate = new Date(tmpEndDate.getFullYear(), tmpEndDate.getMonth(), tmpEndDate.getDate());
			selectedDate = null;
			
			// 刷新一个月的表格
			clearAllSeleced();
			selectedDateRange(startDate, endDate);
			
			// 刷新选中日期保存框
			renderSelectedDateInput(dateFormatRegex);
		}
		
		// 选中当天
		function selectThisDay() {
			var year = this.getAttribute("y"),
			month = this.getAttribute("m"),
			day = this.getAttribute("d");
			
			var tmpDate = new Date(year, month, day);
			// 点击的日期在当天之后
			if (compareDate(tmpDate, new Date()) > 0) {
				setTip("日期超过当天");
				return;
			}
			clearTip();
			
			if (!enableSelectRange) {	// 如果不能选取日期区间
				startDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate());
				endDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate());
				
				setSelected(this);
			} else if (selectedDate == null) {
				selectedDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate());
				startDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate());
				endDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate());
				
				setSelected(this);
				renderCalendar(calendarContainer);	//重新刷新前后日期区间的可选范围
			} else {
				if (rangeDays != -1 && selectedDate) {
					var allowedStartDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate() - rangeDays + 1);
					var allowedEndDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate() + rangeDays - 1);
					
					if ((compareDate(tmpDate, allowedStartDate) < 0 || compareDate(tmpDate, allowedEndDate) > 0)) {
						setTip("日期区间超过" + rangeDays + "天");
						return;
					}
				}
				
				if (compareDate(selectedDate, tmpDate) < 0) {
					startDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate());
					endDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate());
				} else {
					startDate = new Date(tmpDate.getFullYear(), tmpDate.getMonth(), tmpDate.getDate());
					endDate = new Date(selectedDate.getFullYear(), selectedDate.getMonth(), selectedDate.getDate());
				}
				
				selectedDate = null;
				renderCalendar(calendarContainer);	//重新刷新前后日期区间的可选范围
			}
			
			// 更新选中的日期状态
			clearAllSeleced();
			selectedDateRange(startDate, endDate);
			
			// 刷新选中日期保存框
			renderSelectedDateInput(dateFormatRegex);
		}
		
		// 设置提示
		function setTip(content) {
			var tipDivElements = getElementsByClassName("date-select-tip", "div");
			for (var i = 0; i < tipDivElements.length; i++) {
				tipDivElements[i].innerHTML = content;
			}
		}
		
		// 清除提示
		function clearTip() {
			var tipDivElements = getElementsByClassName("date-select-tip", "div");
			for (var i = 0; i < tipDivElements.length; i++) {
				tipDivElements[i].innerHTML = "";
			}
		}
		
		// 设置选中日期区间的单元格状态
		function selectedDateRange(startDate, endDate) {
			var allTdElements = getElementsByClassName(tdClass, "td");
			for (var i = 0; i < allTdElements.length; i++) {
				var year = allTdElements[i].getAttribute("y"),
				month = allTdElements[i].getAttribute("m"),
				day = allTdElements[i].getAttribute("d");
				var tmpDate = new Date(year, month, day);
				if (compareDate(startDate, tmpDate) <= 0 && compareDate(endDate, tmpDate) >= 0) {
					setSelected(allTdElements[i]);
				}
			}
			
			setDateRangeTarget();
		}
		
		// 重置所有选中的元素的样式为未选中状态
		function clearAllSeleced() {
			var selectedTds = getElementsByClassName(selectedTdClass, "td");
			for (var i = 0; i < selectedTds.length; i++) {
				setUnselected(selectedTds[i]);
			}
		}
		
		// 将当前对象设置为选中状态
		function setSelected(obj) {
			obj.setAttribute("class", selectedTdClass);
		}
		
		// 将当前对象设置为非选中状态
		function setUnselected(obj) {
			obj.setAttribute("class", tdClass);
		}
		
		// 刷新选中日期保存框
		function renderSelectedDateInput(regex) {
			var localRegex = regex || dateFormatRegex2;
			var startDateElem = document.getElementById(prefix + "startDate");
			var endDateElem = document.getElementById(prefix + "endDate");
			
			startDateElem.value = formateDate(startDate, localRegex);
			endDateElem.value = formateDate(endDate, localRegex);
			
			startDateElem.className = "date-start";
			endDateElem.className = "date-end";
		}
		
		/* 字符串转换成日期
		 *
		 * 返回值：
		 * 	null：非法日期
		 *	date：合法的日期
		 * 
		 * 注：
		 *	目前只能按照比较死的格式转换，且只支持yyyy-MM-dd和yyyy/MM/dd两种格式
		 *	后期考虑自动进行所有格式的匹配
		 */
		function stringToDate(dateString, regex) {
			if (!dateString || dateString.length != 10) {
				return null;
			}
			
			var splitString;
			if (regex == dateFormatRegex) {
				splitString = dateFormatSplit;
			} else if (regex == dateFormatRegex2) {
				splitString = dateFormatSplit2;
			} else {
				return null;
			}
			
			var dateArray = dateString.split(splitString);
			if (dateArray.length != 3) {
				return null;
			}
			
			var year = parseInt(dateArray[0]);
			var month = parseInt(dateArray[1]);
			var day = parseInt(dateArray[2]);
			
			var currentDate = new Date();
			if ((year < 1 || year > currentDate.getFullYear())
				|| (month < 1 || month > 12)
				|| (day < 1 || day > 31)) {
				return null;
			}
			
			var newDate = new Date(year, month-1, day);
			if (year != newDate.getFullYear()
				|| month != newDate.getMonth() + 1
				|| day != newDate.getDate()) {
				return null;
			}
			
			return newDate;
		}
		
		/* 	比较两个日期的先后
			返回值：
				小于 0： date1 在 date2 之前
				等于 0： date1 和 date2 是同一天
				大于 0：date1 在 date2 之后
		*/
		function compareDate(date1, date2) {
			var tmpDate1 = new Date(date1.getFullYear(), date1.getMonth(), date1.getDate());
			var tmpDate2 = new Date(date2.getFullYear(), date2.getMonth(), date2.getDate());
			return (tmpDate1.getTime() - tmpDate2.getTime());
		}
		
		// 格式化日期
		function formateDate(date, regex) {
			if ("string" != typeof regex) {
				return date.toString();
			}
			
			var year = date.getFullYear(),
			month = date.getMonth() + 1,
			day = date.getDate();
			
			if (month < 10) {
				month = "0" + month;
			}
			if (day < 10) {
				day = "0" + day;
			}
			
			regex = regex.replace(/yyyy/, year)
						 .replace(/YYYY/, year)
						 .replace(/MM/, month)
						 .replace(/mm/, month)
						 .replace(/dd/, day)
						 .replace(/DD/, day);
			
			return regex;
		}
		
		/* 
		 * clsName:给定类名 
		 * tagName：给定的HTML元素，如果为任意 tagName='*' 
		 * ClassElements：返回值 
		 */  
		function getElementsByClassName(clsName, tagName) {
			return $("#" + calendarContainerId + " " + tagName + "." + clsName); // 该处使用了JQuery的选择器
		}
		
		// 生成随机码
		function getUniqueId(count) {
			var localCount = count || 8;
			var ret = "";
			while (localCount--) {
				ret += getRandomChar();
			}
			
			return ret;
		}
		
		function getRandomChar() {
			var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
			var length = chars.length;
			return chars.charAt(Math.floor(Math.random() * length));
		}
	};
})(jQuery);

//计算选中的时间区间
var caculateTimeZone = function (option){
	var dateFormatRegex = "yyyy-MM-dd";
	
	var currDate = new Date();
	var endDate = new Date(currDate.getFullYear(), currDate.getMonth(), currDate.getDate() - 1);
	var startDate = new Date(currDate.getFullYear(), currDate.getMonth(), currDate.getDate() - option.days);
	
	var opt = {
			todayDate: formateDate(endDate,dateFormatRegex),
			startDate: formateDate(startDate,dateFormatRegex),
			endDate: formateDate(endDate,dateFormatRegex)
		};
	opt = $.extend(true, opt, option);
	// 格式化日期
	function formateDate(date, regex) {
		if ("string" != typeof regex) {
			return date.toString();
		}
		
		var year = date.getFullYear(),
		month = date.getMonth() + 1,
		day = date.getDate();
		
		if (month < 10) {
			month = "0" + month;
		}
		if (day < 10) {
			day = "0" + day;
		}
		
		regex = regex.replace(/yyyy/, year)
					 .replace(/YYYY/, year)
					 .replace(/MM/, month)
					 .replace(/mm/, month)
					 .replace(/dd/, day)
					 .replace(/DD/, day);
		
		return regex;
	}
	option.prevTarget = $("#" + option.target).empty().calendar(opt);
	return option.prevTarget;
}

/**
 * 快捷时间选择工具条模板
 */
ebCalendar.quickDateSelectBarT = template.compile(
'<div class="date-control-bar-wrapper">'+
	'<div class="date-control-bar bg-iframe">'+
        '<div class="l date-select-bar">'+
        	'<span class="prefix">时间宽度:</span>'+
            '<a href="#-1" class="trackable date-bar-single-day" memo="yesterday" value="1">昨天</a><span class="seprator"></span>'+
            '<a href="#-6" class="trackable date-bar-single-day cur" memo="sevenDay" value="7">最近7天</a><span class="seprator"></span>'+
            '<a href="#-6" class="trackable date-bar-single-day" memo="fifteenDay" value="15">最近15天</a><span class="seprator"></span>'+
            '<a href="#-29" class="trackable date-bar-single-day" memo="thirtyDay" value="30">最近30天</a><span class="seprator"></span>'+
         '</div>'+
         '<div id="CustomDateSelect" class="l time-select-bar custom-date-select">'+
         '</div>'+
    '</div>'+
'</div>'
);

/**
 * 快捷时间选择工具条
 */
;(function($){
    $.fn.quickDateSelectBar = function(option){
        var defaults = {};
        var option = $.extend(true,defaults,option);
        var $html = $( ebCalendar.quickDateSelectBarT(option) );
        $(this).append($html);
        return this;
    }
})(jQuery)

