/*
 *  @author yangzeming
 *  @date  2014-05-30
 *  @desc  日历服务的基础类，日历选择控件，复杂日历，都继承这个类

    default_date: "%j %M %Y",
	month_date: "%F %Y",
	load_date: "%Y-%m-%d",
	week_date: "%l",
	day_date: "%D, %F %j",
	hour_date: "%H:%i",
	month_day: "%d",
	xml_date: "%m/%d/%Y %H:%i",
	api_date: "%d-%m-%Y %H:%i",


%e	Day of the month without leading zeros (01..31)  不会自动补零的天数
%d	Day of the month, 2 digits with leading zeros (01..31)  会自动补零的2位天数
%j	Day of the year, 3 digits with leading zeros (001..366)  会自动补的 3位天数
%a	A textual representation of a day, two letters           2个字的天数
%W	A full textual representation of the day of the week     如星期一

%c	Numeric representation of a month, without leading zeros (0..12)  
%m	Numeric representation of a month, with leading zeros (00..12)
%b	A short textual representation of a month, three letters (Jan..Dec)
%M	A full textual representation of a month, such as January or March (January..December)

%y	A two digit representation of a year (93..03)
%Y	A full numeric representation of a year, 4 digits (1993..03)
 */
    var basecalendar = _.Class({
		initial : function(){
		
		},
		config : {
			default_date: "%j %M %Y",
			month_date: "%F %Y",
			load_date: "%Y-%m-%d",
			week_date: "%l",
			day_date: "%D, %F %j",
			hour_date: "%H:%i",
			month_day: "%d",
			xml_date: "%m/%d/%Y %H:%i",
			api_date: "%d-%m-%Y %H:%i"
		
		},
		// 
		datePart:function(date){
			date.setHours(0);
			date.setMinutes(0);
			date.setSeconds(0);
			date.setMilliseconds(0);
			if (date.getHours() != 0)
				date.setTime(date.getTime() + 60 * 60 * 1000 * (24 - date.getHours()));
			return date;
		},
		timePart:function(date){
			return (date.valueOf()/1000 - date.getTimezoneOffset()*60)%86400;
		},
		weekStart:function(date){
			var shift=date.getDay();
			if (this.options.startMonday){
				if (shift===0) shift=6;
				else shift--;
			}
			return this.datePart(this.add(date,-1*shift,"day"));
		},
		monthStart:function(date){
			date.setDate(1);
			return this.datePart(date);
		},
		yearStart:function(date){
			date.setMonth(0);
			return this.monthStart(date);
		},
		dayStart:function(date){
			return this.datePart(date);
		},
		add:function(date,inc,mode){
			var ndate=new Date(date.valueOf());
			switch(mode){
				case "week":
					inc *= 7;
				case "day":
					ndate.setDate(ndate.getDate() + inc);
					if (!date.getHours() && ndate.getHours()) //shift to yesterday
						ndate.setTime(ndate.getTime() + 60 * 60 * 1000 * (24 - ndate.getHours()));
					break;
				case "month": ndate.setMonth(ndate.getMonth()+inc); break;
				case "year": ndate.setYear(ndate.getFullYear()+inc); break;
				case "hour": ndate.setHours(ndate.getHours()+inc); break;
				case "minute": ndate.setMinutes(ndate.getMinutes()+inc); break;
				default:
					return "";
			}
			return ndate;
		},
		toFixed:function(num){
			if (num<10)	return "0"+num;
			return num;
		},
		copy:function(date){
			return new Date(date.valueOf());
		},
		date:{
			month_full:["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"],
			month_short:["一", "二", "三", "四", "五", "六", "七", "八", "九", "十", "十一", "十二"],
			day_full:["星期一","星期二","星期三","星期四","星期五","星期六","星期日"],//["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
			day_short: ["一","二","三","四","五","六","日"]//["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
		},
		dateToStr:function(format,utc){
			format=format.replace(/%[a-zA-Z]/g,function(a){
				switch(a){
					case "%d": return "\"+this.toFixed(date.getDate())+\"";
					//scase "%d": return "\"+this.toFixed(date.getDate())+\"";
					case "%m": return "\"+this.toFixed((date.getMonth()+1))+\"";
					case "%j": return "\"+date.getDate()+\"";
					case "%n": return "\"+(date.getMonth()+1)+\"";
					case "%y": return "\"+this.toFixed(date.getFullYear()%100)+\""; 
					case "%Y": return "\"+date.getFullYear()+\"";
					case "%D": return "\"+this.date.day_short[date.getDay()]+\"";
					case "%l": return "\"+this.date.day_full[date.getDay()]+\"";
					case "%M": return "\"+this.date.month_short[date.getMonth()]+\"";
					case "%F": return "\"+this.date.month_full[date.getMonth()]+\"";
					case "%h": return "\"+this.toFixed((date.getHours()+11)%12+1)+\"";
					case "%g": return "\"+((date.getHours()+11)%12+1)+\"";
					case "%G": return "\"+date.getHours()+\"";
					case "%H": return "\"+this.toFixed(date.getHours())+\"";
					case "%i": return "\"+this.toFixed(date.getMinutes())+\"";
					case "%a": return "\"+(date.getHours()>11?\"pm\":\"am\")+\"";
					case "%A": return "\"+(date.getHours()>11?\"PM\":\"AM\")+\"";
					case "%s": return "\"+this.toFixed(date.getSeconds())+\"";
					case "%W": return "\"+this.toFixed(this.getISOWeek(date))+\"";
					default: return a;
				}
			});
			if (utc) format=format.replace(/date\.get/g,"date.getUTC");
			
			var fun = new Function("date","return \""+format+"\";");
			//alert(fun);
			var self = this;
			
			return $.proxy(fun,self);
		},
		strToDate:function(format,utc){
			var splt="var temp=date.match(/[a-zA-Z]+|[0-9]+/g);";
			var mask=format.match(/%[a-zA-Z]/g);
			for (var i=0; i<mask.length; i++){
				switch(mask[i]){
					case "%j":
					case "%d": splt+="set[2]=temp["+i+"]||1;";
						break;
					case "%n":
					case "%m": splt+="set[1]=(temp["+i+"]||1)-1;";
						break;
					case "%y": splt+="set[0]=temp["+i+"]*1+(temp["+i+"]>50?1900:2000);";
						break;
					case "%g":
					case "%G":
					case "%h": 
					case "%H":
								splt+="set[3]=temp["+i+"]||0;";
						break;
					case "%i":
								splt+="set[4]=temp["+i+"]||0;";
						break;
					case "%Y": splt+="set[0]=temp["+i+"]||0;";
						break;
					case "%a":					
					case "%A": splt+="set[3]=set[3]%12+((temp["+i+"]||'').toLowerCase()=='am'?0:12);";
						break;					
					case "%s": splt+="set[5]=temp["+i+"]||0;";
						break;
					case "%M": splt+="set[1]=this.date.month_short[temp["+i+"]]||0;";
						break;
					case "%F": splt+="set[1]=this.date.month_full[temp["+i+"]]||0;";
						break;
					default:
						break;
				}
			}
			var code ="set[0],set[1],set[2],set[3],set[4],set[5]";
			if (utc) code =" Date.UTC("+code+")";
			var fun = new Function("date","var set=[0,0,1,0,0,0]; "+splt+" return new Date("+code+");");
			var self = this;
			return $.proxy(fun,self);
		},
		getISOWeek: function(ndate) {
			if(!ndate) return false;
			var nday = ndate.getDay();
			if (nday === 0) {
				nday = 7;
			}
			var first_thursday = new Date(ndate.valueOf());
			first_thursday.setDate(ndate.getDate() + (4 - nday));
			var year_number = first_thursday.getFullYear(); // year of the first Thursday
			var ordinal_date = Math.round( (first_thursday.getTime() - new Date(year_number, 0, 1).getTime()) / 86400000); //ordinal date of the first Thursday - 1 (so not really ordinal date)
			var week_number = 1 + Math.floor( ordinal_date / 7);
			return week_number;
		},
		getUTCISOWeek: function(ndate){
			return this.getISOWeek(this.convert_to_utc(ndate));
		},
		convert_to_utc: function(date) {
			return new Date(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds());
		}
		
	
	});
