text: /*
   * PHPWind util Library
   * @Copyright 	: Copyright 2011, phpwind.com
   * @Descript	: datePicker 日历组件
   * @Author		: jquerytools (http://jquerytools.org/demos/dateinput/)
   * @Modify		: chaoren1641@gmail.com
   * @Depend		: jquery.js(1.7 or later)
   * $Id: datePicker.js 22586 2012-12-25 10:54:55Z hao.lin $			:
   */
  ;(function($, window, document, undefined) {
  	var pluginName = 'datePicker';
  	var instances = [];
  
  	// h=72, j=74, k=75, l=76, down=40, left=37, up=38, right=39
  	var KEYS = [75, 76, 38, 39, 74, 72, 40, 37], LABELS = {};
  	var defaults = {
  			format 		: 'yyyy-mm-dd',
  			selectors 	: true,
  			time		: false,
  			yearRange 	: [-200, 200],
  			lang 		: 'zh-CN',
  			offset : [0, 0],
  			speed : 0,
  			firstDay : 0, // The first day of the week, Sun = 0, Mon = 1, ...
  			min : undefined,
  			max : undefined,
  			trigger : false,
  
  			css : {
  
  				prefix : 'cal',
  				input : 'date',
  
  				// ids
  				root : 0,
  				head : 0,
  				title : 0,
  				prev : 0,
  				next : 0,
  				month : 0,
  				year : 0,
  				days : 0,
  
  				body : 0,
  				weeks : 0,
  				today : 0,
  				current : 0,
  
  				// classnames
  				week : 0,
  				off : 0,
  				sunday : 0,
  				focus : 0,
  				disabled : 0,
  				trigger : 0
  		}
  	};
  
  	var localize = function(language, labels) {
  		$.each(labels, function(key, val) {
  			labels[key] = val.split(",");
  		});
  		LABELS[language] = labels;
  	};
  
  	//多语言配置
  	localize("en", {
  		months : 'January,February,March,April,May,June,July,August,September,October,November,December',
  		shortMonths : 'Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec',
  		days : 'Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday',
  		shortDays : 'Sun,Mon,Tue,Wed,Thu,Fri,Sat'
  	});
  	localize("zh-CN", {
  		months : '一月,二月,三月,四月,五月,六月,七月,八月,九月,十月,十一月,十二月',
  		shortMonths : '一,二,三,四,五,六,七,八,九,十,十一,十二',
  		days : '周日,周一,周二,周三,周四,周五,周六',
  		shortDays : '日,一,二,三,四,五,六'
  	});
  
  	//{{{ private functions
  
  	//返回某年某月的天数
  	function dayAm(year, month) {
  		return 32 - new Date(year, month, 32).getDate();
  	}
  
  	function zeropad(val, len) {
  		val = '' + val;
  		len = len || 2;
  		while(val.length < len) {
  			val = "0" + val;
  		}
  		return val;
  	}
  
  	// thanks: http://stevenlevithan.com/assets/misc/date.format.js
  	var Re = /d{1,4}|m{1,4}|yy(?:yy)?|([HhMsTt])\1?|[LloSZ]|"[^"]*"|'[^']*'/g, tmpTag = $("<a/>");
  
  	//格式化时间
  	function format(date, fmt, lang) {
  		var d = date.getDate(), D = date.getDay(), m = date.getMonth(), y = date.getFullYear(),
  			h = date.getHours(),M = date.getMinutes(),
  			flags = {
  				d : d,
  				dd : zeropad(d),
  				ddd : LABELS[lang].shortDays[D],
  				dddd : LABELS[lang].days[D],
  				m : m + 1,
  				mm : zeropad(m + 1),
  				mmm : LABELS[lang].shortMonths[m],
  				mmmm : LABELS[lang].months[m],
  				yy : String(y).slice(2),
  				yyyy : y,
  				HH: zeropad(h),
  				MM : zeropad(M)
  			};
  		var ret = fmt.replace(Re, function($0) {
  			return $0 in flags ? flags[$0] : $0.slice(1, $0.length - 1);
  		});
  		// a small trick to handle special characters
  		return tmpTag.html(ret).html();
  
  	}
  
  	function integer(val) {
  		return parseInt(val, 10);
  	}
  
  	function isSameDay(d1, d2) {
  		return d1.getFullYear() === d2.getFullYear() && d1.getMonth() == d2.getMonth() && d1.getDate() == d2.getDate();
  	}
  
  	function parseDate(val) {
  		if(!val) {
  			return;
  		}
  		if(val.constructor == Date) {
  			return val;
  		}
  
  		if( typeof val == 'string') {
  			// rfc3339?
  			var els = val.split(" ");
  			var date,time;
  			var y,m,d,h,s;
  			date = els[0].split('-');
  			if(date.length !== 3) {
  				return;
  			}
  			if(els.length === 2) {
  				time = els[1].split(':');
  			}else {
  				time = '00:00'.split(':');
  			}
  			y = date[0],m = date[1]-1,d = date[2];
  			h = time[0],s = time[1];
  			return new Date(y,m,d,h,s,0);
  			// invalid offset
  			if(!/^-?\d+$/.test(val)) {
  				return;
  			}
  			// convert to integer
  			val = integer(val);
  		}
  		var date = new Date();
  		date.setDate(date.getDate() + val);
  		return date;
  	}
  
  	function Plugin( input, options ) {
  		this.options = $.extend( {}, defaults, options) ;
  		this.input = input;
  		this.init();
      }
  
  	Plugin.prototype.init = function() {
  		var options = this.options,input = this.input;
  		if(options.time) {
  			options.format = 'yyyy-mm-dd HH:MM'
  		}
  		// CSS prefix
  		$.each(options.css, function(key, val) {
  			if(!val && key != 'prefix') {
  				options.css[key] = (options.css.prefix || '') + (val || key);
  			}
  		});
  		// variables
  		var self = this, now = new Date(), css = options.css, labels = LABELS[options.lang], root = $("#" + css.root), title = root.find("#" + css.title), trigger, pm, nm, currYear, currMonth, currDay, value = input.attr("data-value") || options.value || input.val(), min = input.attr("min") || options.min, max = input.attr("max") || options.max, opened;
  		// zero min is not undefined
  		if(min === 0) {
  			min = "0";
  		}
  		// use sane values for value, min & max
  		value = parseDate(value) || now;
  		min = parseDate(min || options.yearRange[0] * 365);
  		max = parseDate(max || options.yearRange[1] * 365);
  
  		// check that language exists
  		if(!labels) {
  			throw "不存在的语言: " + options.lang;
  		}
  
  		// Replace built-in date input: NOTE: input.attr("type", "text") throws exception by the browser
  		if(input.attr("type") === 'date') {
  			var tmp = $("<input/>");
  
  			$.each("class,disabled,id,maxlength,name,readonly,required,size,style,tabindex,title,value".split(","), function(i, attr) {
  				tmp.attr(attr, input.attr(attr));
  			});
  			input.replaceWith(tmp);
  			input = tmp;
  		}
  		input.addClass(css.input);
  
  		var fire = input.add(self);
  
  		// construct layout
  		if(!root.length) {
  
  			// root
  			root = $('<div><div><a/><div/><a/></div><div><div/><div/></div></div>').hide().css({
  				position : 'absolute'
  			}).attr("id", css.root);
  
  			// elements
  			root.children().eq(0).attr("id", css.head).end().eq(1).attr("id", css.body).children().eq(0).attr("id", css.days).end().eq(1).attr("id", css.weeks).end().end().end().find("a").eq(0).attr("id", css.prev).end().eq(1).attr("id", css.next);
  
  			// title
  			title = root.find("#" + css.head).find("div").attr("id", css.title);
  
  			// year & month selectors
  			if(options.selectors) {
  				var monthSelector = $("<select/>").attr("id", css.month), yearSelector = $("<select/>").attr("id", css.year);
  				title.html(monthSelector.add(yearSelector));
  			}
  
  			// day titles
  			var days = root.find("#" + css.days);
  
  			// days of the week
  			for(var d = 0; d < 7; d++) {
  				days.append($("<span/>").text(labels.shortDays[(d + options.firstDay) % 7]));
  			}
  
  			var body = root.find("#" + css.body);
  			$('<div class="caltime"><button type="button" class="btn btn_submit fr" name="submit">确认</button><input id="calHour" type="number" class="input" min="0" max="23" size="2" value="0"><span>点</span><input id="calMin" class="input" type="number" size="2" min="1" max="59" value="0"><span>分</span></div>').appendTo(body);
  
  			$("body").append(root);
  
  			if($.browser.msie && $.browser.version < 7 ) {
  	            Wind.use('bgiframe',function() {
  	                root.bgiframe();
  	            });
  	        }
  		}
  
  		// trigger icon
  		if(options.trigger) {
  			trigger = $("<a/>").attr("href", "#").addClass(css.trigger).click(function(e) {
  				self.show();
  				return e.preventDefault();
  			}).insertAfter(input);
  		}
  
  		// layout elements
  		var weeks = root.find("#" + css.weeks);
  		yearSelector = root.find("#" + css.year);
  		monthSelector = root.find("#" + css.month);
  
  		//{{{ pick
  
  		function select(date, options, e) {
  			// current value
  			value = date;
  			currYear = date.getFullYear();
  			currMonth = date.getMonth();
  			currDay = date.getDate();
  
  			if (e.type == "click" && !$.browser.msie) {
  				input.focus();
  			}
  
  			// select
  			e = e || $.Event("api");
  			e.type = "select";
  
  			fire.trigger(e, [date]);
  			if(e.isDefaultPrevented()) {
  				return;
  			}
  			//如果选项有时间，则加上时间
  			if(options.time) {
  				var timeInput = root.find('input');
  				var hour = parseInt(timeInput.eq(0).val(),10);
  				var min = parseInt(timeInput.eq(1).val(),10);
  				if(isNaN(hour)) {
  					hour = 0;
  				}
  				if(isNaN(min)) {
  					min = 0;
  				}
  				if(hour < 10) {
  					hour = '0' + hour;
  				}else if(hour < 0 || hour > 23) {
  					hour = '00';
  				}
  				if(min < 10) {
  					min = '0' + min;
  				}else if(min < 0 || min > 59) {
  					min = '00';
  				}
  				date.setHours(hour);
  				date.setMinutes(min);
  			}
  			// formatting
  			var date = format(date, options.format, options.lang);
  			input.val(date);
  			// store value into input
  			input.data("date", date);
  			//设置val后，IE导致触发focus事件，导致窗口关闭后再次被打开
  			setTimeout(function() {
  				self.hide(e);
  			},100);
  		}
  
  		//}}}
  
  		//{{{ onShow
  
  		function onShow(ev) {
  
  			ev.type = "onShow";
  			fire.trigger(ev);
  
  			//快捷键处理
  			$(document).bind("keydown.d", function(e) {
  
  				if(e.ctrlKey) {
  					return true;
  				}
  				var key = e.keyCode;
  
  				// backspace clears the value
  				if(e.target == input[0]) {//如果是在当前input按back键，清除值并隐藏日历
  					if(key == 8 || key == 46) {
  						input.val("");
  						return self.hide(e);
  					}
  				}
  				// esc key
  				if(key == 27) {
  					return self.hide(e);
  				}
  				//如果有time，则不要快捷键
  				if(options.time) {
  					return;
  				}
  				if($(KEYS).index(key) >= 0) {
  
  					if(!opened) {
  						self.show(e);
  						return e.preventDefault();
  					}
  
  					var days = $("#" + css.weeks + " a"), el = $("." + css.focus), index = days.index(el);
  
  					el.removeClass(css.focus);
  
  					if(key == 74 || key == 40) {
  						index += 7;
  					} else if(key == 75 || key == 38) {
  						index -= 7;
  					} else if(key == 76 || key == 39) {
  						index += 1;
  					} else if(key == 72 || key == 37) {
  						index -= 1;
  					}
  
  					if(index > 41) {
  						self.addMonth();
  						el = $("#" + css.weeks + " a:eq(" + (index - 42) + ")");
  					} else if(index < 0) {
  						self.addMonth(-1);
  						el = $("#" + css.weeks + " a:eq(" + (index + 42) + ")");
  					} else {
  						el = days.eq(index);
  					}
  
  					el.addClass(css.focus);
  					return e.preventDefault();
  
  				}
  
  				// pageUp / pageDown
  				if(key == 34) {
  					return self.addMonth();
  				}
  				if(key == 33) {
  					return self.addMonth(-1);
  				}
  
  				// home
  				if(key == 36) {
  					return self.today();
  				}
  
  				// enter
  				if(key == 13) {
  					if(!$(e.target).is("select")) {
  						$("." + css.focus).dblclick();
  					}
  				}
  
  				return $([16, 17, 18, 9]).index(key) >= 0;
  			});
  
  			// 点击外部关闭窗口
  			/*$(document).bind("mousedown.d", function(e) {
  				var el = e.target;
  
  				if(!$(el).parents("#" + css.root).length && el != input[0] && (!trigger || el != trigger[0])) {
  					self.hide(e);
  				}
  
  			});*/
  
  			$(document.body).on("mousedown.d", function(e) {
  				if(e.target !== input[0] && !$.contains(root[0],e.target)) {
  					setTimeout(function(){
  						self.hide();
  					},100)
  				}
  			});
  		}
  
  		//}}}
  
  		$.extend(self, {
  
  			//{{{  show
  
  			show : function(e) {
  				if(input.attr("readonly") || input.attr("disabled") || opened) {
  					return;
  				}
  				// onBeforeShow
  				e = e || $.Event();
  				e.type = "onBeforeShow";
  				fire.trigger(e);
  				if(e.isDefaultPrevented()) {
  					return;
  				}
  
  				$.each(instances, function() {
  					this.hide();
  				});
  				opened = true;
  
  				// 月份下拉菜单
  				monthSelector.unbind("change").change(function() {
  					self.setValue(yearSelector.val(), $(this).val());
  				});
  				// 年下拉菜单
  				yearSelector.unbind("change").change(function() {
  					self.setValue($(this).val(), monthSelector.val());
  				});
  				// 上一月/下一月按钮
  				pm = root.find("#" + css.prev).unbind("click").click(function(e) {
  					if(!pm.hasClass(css.disabled)) {
  						self.addMonth(-1);
  					}
  					return false;
  				});
  				nm = root.find("#" + css.next).unbind("click").click(function(e) {
  					if(!nm.hasClass(css.disabled)) {
  						self.addMonth();
  					}
  					return false;
  				});
  				// 设置日期
  				self.setValue(value);
  
  				//是否显示时间选择
  				if(options.time) {
  					root.find('div.caltime').show();
  				}else{
  					root.find('div.caltime').hide();
  				}
  
  				// show calendar
  				var pos = input.offset();
  
  				// iPad position fix
  				if(/iPad/i.test(navigator.userAgent)) {
  					pos.top -= $(window).scrollTop();
  				}
  				var top = pos.top + input.outerHeight() + options.offset[0];
  				if(top + root.height() > $(window).scrollTop() + $(window).height()) {
  					top = pos.top - root.height();
  				}
  				root.css({
  					top : top,
  					left : pos.left + options.offset[1]
  				});
  
  				if(options.speed) {
  					root.show(options.speed, function() {
  						onShow(e);
  					});
  				} else {
  					root.show();
  					onShow(e);
  				}
  
  				return self;
  			},
  			//}}}
  
  			//{{{  setValue
  
  			setValue : function(year, month, day, hour, minute) {
  				var date = integer(month) >= -1 ? new Date(integer(year), integer(month), integer(day || 1)) : year || value;
  
  				if(date < min) {
  					date = min;
  				} else if(date > max) {
  					date = max;
  				}
  				year = date.getFullYear();
  				month = date.getMonth();
  				day = date.getDate();
  				hour = date.getHours();
  				minute = date.getMinutes();
  				// roll year & month
  				if(month == -1) {
  					month = 11;
  					year--;
  				} else if(month == 12) {
  					month = 0;
  					year++;
  				}
  
  				if(!opened) {
  					select(date, options);
  					return self;
  				}
  				currMonth = month;
  				currYear = year;
  
  				// variables
  				var tmp = new Date(year, month, 1 - options.firstDay), begin = tmp.getDay(), days = dayAm(year, month), prevDays = dayAm(year, month - 1), week;
  
  				// selectors
  				if(options.selectors) {
  
  					// month selector
  					monthSelector.empty();
  					$.each(labels.months, function(i, m) {
  						if(min < new Date(year, i + 1, -1) && max > new Date(year, i, 0)) {
  							monthSelector.append($("<option/>").html(m).attr("value", i));
  						}
  					});
  					// year selector
  					yearSelector.empty();
  					var yearNow = now.getFullYear();
  
  					for(var i = yearNow + options.yearRange[0]; i < yearNow + options.yearRange[1]; i++) {
  						if(min <= new Date(i + 1, -1, 1) && max > new Date(i, 0, 0)) {
  							yearSelector.append($("<option/>").text(i));
  						}
  					}
  
  					monthSelector.val(month);
  					yearSelector.val(year);
  
  					// title
  				} else {
  					title.html(labels.months[month] + " " + year);
  				}
  
  				// populate weeks
  				weeks.empty();
  				pm.add(nm).removeClass(css.disabled);
  
  				// !begin === "sunday"
  				for(var j = !begin ? -7 : 0, a, num; j < (!begin ? 35 : 42); j++) {
  					a = $("<a/>");
  
  					if(j % 7 === 0) {
  						week = $("<div/>").addClass(css.week);
  						weeks.append(week);
  					}
  
  					if(j < begin) {
  						a.addClass(css.off);
  						num = prevDays - begin + j + 1;
  						date = new Date(year, month - 1, num);
  
  					} else if(j >= begin + days) {
  						a.addClass(css.off);
  						num = j - days - begin + 1;
  						date = new Date(year, month + 1, num);
  
  					} else {
  						num = j - begin + 1;
  						date = new Date(year, month, num);
  
  						// current date
  						if(isSameDay(value, date)) {
  							a.attr("id", css.current).addClass(css.focus);
  
  							// today
  						} else if(isSameDay(now, date)) {
  							a.attr("id", css.today);
  						}
  					}
  
  					// disabled
  					if(min && date < min) {
  						a.add(pm).addClass(css.disabled);
  					}
  
  					if(max && date > max) {
  						a.add(nm).addClass(css.disabled);
  					}
  
  					a.attr("href", "#" + num).text(num).data("date", date);
  
  					week.append(a);
  
  					if(options.selectors) {
  						//console.log(year, month, day, hour, minute)
  					}
  				}
  
  				//时间选择
  				//!TODO:chaoren1641增加，有待重构
  				if(options.time) {
  					//如果有时间选项则点击确定或双击日期输入时间
  					// date picking
  					weeks.find("a").on('click',function(e) {
  						var el = $(this);
  						if(!el.hasClass(css.disabled)) {
  							$("#" + css.current).removeAttr("id");
  							el.attr("id", css.current);
  						}
  						return false;
  					}).off('dblclick').dblclick(function(e) {
  						var el = $(this);
  						if(!el.hasClass(css.disabled)) {
  							select(el.data("date"), options, e);
  							//在IE下，重新赋值会引起focus，导致日历控件再次激活打开，所以setTimeout下
  							setTimeout(function() {
  								self.hide();
  							},100);
  						}
  						return false;
  					});
  
  					var body = root.find("#" + css.body);
  					body.find('button').off('click.d').on('click.d',function(e) {
  						var el = root.find('#' + css.current);
  						select(el.data("date"), options, e);
  						//在IE下，重新赋值会引起focus，导致日历控件再次激活打开，所以setTimeout下
  						setTimeout(function() {
  							self.hide();
  						},100);
  						return false;
  					});
  					body.find('#calHour').val(hour);
  					body.find('#calMin').val(minute);
  				}else{
  					// date picking
  					weeks.find("a").click(function(e) {
  						var el = $(this);
  						if(!el.hasClass(css.disabled)) {
  							$("#" + css.current).removeAttr("id");
  							el.attr("id", css.current);
  							select(el.data("date"), options, e);
  						}
  						return false;
  					})
  				}
  				// sunday
  				if(css.sunday) {
  					weeks.find(css.week).each(function() {
  						var beg = options.firstDay ? 7 - options.firstDay : 0;
  						$(this).children().slice(beg, beg + 1).addClass(css.sunday);
  					});
  				}
  
  				return self;
  			},
  			//}}}
  
  			setMin : function(val, fit) {
  				min = parseDate(val);
  				if(fit && value < min) {
  					self.setValue(min);
  				}
  				return self;
  			},
  			setMax : function(val, fit) {
  				max = parseDate(val);
  				if(fit && value > max) {
  					self.setValue(max);
  				}
  				return self;
  			},
  			today : function() {
  				return self.setValue(now);
  			},
  			addDay : function(amount) {
  				return this.setValue(currYear, currMonth, currDay + (amount || 1));
  			},
  			addMonth : function(amount) {
  				return this.setValue(currYear, currMonth + (amount || 1), currDay);
  			},
  			addYear : function(amount) {
  				return this.setValue(currYear + (amount || 1), currMonth, currDay);
  			},
  			hide : function(e) {
  				if(opened) {
  					// onHide
  					e = $.Event();
  					e.type = "onHide";
  					fire.trigger(e);
  
  					$(document).unbind("click.d").unbind("keydown.d");
  
  					// cancelled ?
  					if(e.isDefaultPrevented()) {
  						return;
  					}
  
  					// do the hide
  					root.hide();
  					opened = false;
  				}
  
  				return self;
  			},
  			getConf : function() {
  				return options;
  			},
  			getInput : function() {
  				return input;
  			},
  			getCalendar : function() {
  				return root;
  			},
  			getValue : function(dateFormat) {
  				return dateFormat ? format(value, dateFormat, options.lang) : value;
  			},
  			isOpen : function() {
  				return opened;
  			}
  		});
  
  		// callbacks
  		$.each(['onBeforeShow', 'onShow', 'select', 'onHide'], function(i, name) {
  
  			// configuration
  			if($.isFunction(options[name])) {
  				$(self).bind(name, options[name]);
  			}
  
  			// API methods
  			self[name] = function(fn) {
  				if(fn) {
  					$(self).bind(name, fn);
  				}
  				return self;
  			};
  		});
  		// show dateinput & assign keyboard shortcuts
  		input.bind("focus click", self.show).keydown(function(e) {
  			var key = e.keyCode;
  
  			// open dateinput with navigation keyw
  			if(!opened && $(KEYS).index(key) >= 0) {
  				self.show(e);
  				return e.preventDefault();
  			}
  
  			// allow tab
  			return e.shiftKey || e.ctrlKey || e.altKey || key == 9 ? true : e.preventDefault();
  
  		});
  		// initial value
  		if(parseDate(input.val())) {
  			//!TODO关闭初始化的值，这里会出现BUG
  			//select(value, options);
  		}
  	};
  
  	$.expr[':'].date = function(el) {
  		var type = el.getAttribute("type");
  		return type && type == 'date' || !!$(el).data("dateinput");
  	};
  
  
  	$.fn[pluginName] = function(options) {
  		Wind.css('datePicker');
  		return this.each(function() {
  			if(!$.data(this, 'plugin_' + pluginName)) {
  				var instance = new Plugin($(this), options);
  				instances.push(instance);
  				$.data(this, 'plugin_' + pluginName, instance);
  			}
  		});
  	};
  
  	/*$.fn.dateinput = function(conf) {
  
  
  		// already instantiated
  		if(this.data("dateinput")) {
  			return this;
  		}
  
  		// configuration
  		conf = $.extend(true, {}, tool.conf, conf);
  
  		// CSS prefix
  		$.each(conf.css, function(key, val) {
  			if(!val && key != 'prefix') {
  				conf.css[key] = (conf.css.prefix || '') + (val || key);
  			}
  		});
  		var els;
  
  		this.each(function() {
  			var el = new Dateinput($(this), conf);
  			instances.push(el);
  			var input = el.getInput().data("dateinput", el);
  			els = els ? els.add(input) : input;
  		});
  		return els ? els : this;
  	};*/
  
  
  })(jQuery, window ,document);
  