/**
 * 倒计时类 v1.1
 * @author 李伟
 * @date 2010-07-27
 * @example 
 * 			PS:
 *				setPad()填充数值(8=>08)
 *				setImage(sImageSrc; sImageExt) sImageExt不传形参是默认为'.gif'
 * 				setImageIdExt(sImageIdTensExt; sImageIdUnitsExt) sImageIdTensExt传入十位的图片ID,sImageIdUnitsExt传入个位的图片ID.不传形参sImageIdTensExt = '_tens',sImageIdUnitsExt = '_units',例如HourID = 'hour',合并扩展后为 十位的:'hour_tens',个位的:'hour_units'
 *				setDayId();setHourId();setMinId();setSecId() 设置HTML控件的ID名称
 *				setTime(mEndTime; mCurTime) mEndTime 为结束时间;mCurTime 当前时间; mEndTime和mCurTime以数字形式传入是认为时间戳;以字符串日期形式传入可以参考PHP的strtotime()方法的参数输入
 *				setHideId() 参数=布尔型->直接控制隐藏、显示;字符串型->需要隐藏对象的ID并设置隐藏
 * 			1.直接获取 Object oTime = {iDay;iHour;iMin;iSec};
 * 				var oTime = countDown.setTime('2010-07-16 00:00:00').setPad().get();
 * 			2.文字运行
 * 				countDown().setTime('2010-07-16 00:00:00').setPad().setDayId('Day').setHourId('Hour').setMinId('Min').setSecId('Sec').run();
 * 			3.图片运行
 * 				countDown().setTime('2010-07-16 00:00:00').setPad().setDayId('Day').setHourId('Hour').setMinId('Min').setSecId('Sec').setImage('ImageSrc').run();
 * 				countDown().setTime('2010-07-16 00:00:00').setPad().setDayId('Day').setHourId('Hour').setMinId('Min').setSecId('Sec').setImage('ImageSrc';'.jpg').setImageIdExt('_tens','_units').run();
 *          4.多倒计时使用
 *              其他使用方法不变,就是先new后生成一个独立对象,再使用setObjectName()方法将对象名传入(字符串形式)
 *              var oCD1 = new ountDown();
 *              oCD1.setObjectName('oCD1').setTime('2010-07-16 00:00:00').setPad().setDayId('Day1').setHourId('Hour1').setMinId('Min1').setSecId('Sec1').setImage('ImageSrc1').run();
 */

var countDown = function() {
	this.bPad = false,
	this.bHide = false,
	this.bImageIdExt = false,
	this.iEndTime = 0,
	this.iCurTime = 0,
	this.sHideId = '',
	this.sDayId = '',
	this.sHourId = '',
	this.sMinId = '',
	this.sSecId = '',
	this.sImageIdTensExt = '',
	this.sImageIdUnitsExt = '',
	this.sImageSrc = '',
	this.sImagsExt = '',
    this.sObjectName = '',
	this.oTime = new Object(),
	this.oCountDown = null;
	
    this.setObjectName = function(sObjectName) {
        if(typeof(sObjectName) != 'undefined')
            this.sObjectName = sObjectName;
        return this;
    }
    
	this.setTime = function(mEndTime,mCurTime) {
		if(typeof(mEndTime) == 'number') {
			this.iEndTime = mEndTime;
		} else {
			this.iEndTime = this.strtotime(mEndTime);
		}
		
		if(typeof(mCurTime) == 'undefined') {
			this.setCurTime('now');
		} else {
			this.setCurTime(mCurTime);
		}
		
		return this;
	}
	
	this.setCurTime = function(mCurTime) {
		if(typeof(mCurTime) == 'number') {
			this.iCurTime = mCurTime;
		} else {
			this.iCurTime = this.strtotime(mCurTime);
		}
		
		return this;
	}
	
	this.setPad = function(bPad) {
		if(typeof(bPad) == 'undefined') {
			this.bPad = true;
		} else {
			this.bPad = bPad;
		}
		
		return this;
	}
	
	this.setImage = function(sImageSrc, sImagsExt) {
		this.sImageSrc = sImageSrc;
		if(typeof(sImagsExt) == 'undefined') this.sImagsExt = '.gif';
		else this.sImagsExt = sImagsExt;
		return this;
	}
	
	this.setImageIdExt = function(sImageIdTensExt, sImageIdUnitsExt) {
		if(typeof(sImageIdTensExt) == 'undefined') this.sImageIdTensExt = '_tens';
		else this.sImageIdTensExt = sImageIdTensExt;
		
		if(typeof(sImageIdUnitsExt) == 'undefined') this.sImageIdUnitsExt = '_units';
		else this.sImageIdUnitsExt = sImageIdUnitsExt;
		
		return this;
	}
	
	this.setHideId = function(sHideId) {
		if(typeof(sHideId) == 'boolean') {
			this.bHide = sHideId;
		} else {
			if(sHideId) {
				this.bHide = true;
				this.sHideId = sHideId;
			}
		}
		
		return this;
	}
	
	this.setDayId = function(sDayId) {
		this.sDayId = sDayId;
		return this;
	}
	
	this.setHourId = function(sHourId) {
		this.sHourId = sHourId;
		return this;
	}
	
	this.setMinId = function(sMinId) {
		this.sMinId = sMinId;
		return this;
	}
	
	this.setSecId = function(sSecId) {
		this.sSecId = sSecId;
		return this;
	}
	
	this.cal = function() {
		this.oTime.result = false;
		
		if((iResult = this.iEndTime - this.iCurTime++) <= 0) {
			this.oTime.iDay = 0;
			this.oTime.iHour = 0;
			this.oTime.iMin = 0;
			this.oTime.iSec = 0;
		} else {
			this.oTime.result = true;
			this.oTime.iDay = Math.floor(iResult / (3600*24));
			this.oTime.iHour = Math.floor(iResult / 3600)%24;
			this.oTime.iMin = Math.floor(iResult / 60) % 60;
			this.oTime.iSec = Math.floor(iResult % 60);
		}
		
		this.oTime.iDay = this.oTime.iDay.toString();
		this.oTime.iHour = this.oTime.iHour.toString();
		this.oTime.iMin = this.oTime.iMin.toString();
		this.oTime.iSec = this.oTime.iSec.toString();
		
		if(this.bPad) {
			this.bImageIdBothShow = true;
			if(this.oTime.iDay.length < 2) this.oTime.iDay = "0" + this.oTime.iDay;
			if(this.oTime.iHour.length < 2) this.oTime.iHour = "0" + this.oTime.iHour;
			if(this.oTime.iMin.length < 2) this.oTime.iMin = "0" + this.oTime.iMin;
			if(this.oTime.iSec.length < 2) this.oTime.iSec = "0" + this.oTime.iSec;
		}
		
		return this;
	}
	
	this.get = function() {
		this.cal();
		return this.oTime;
	}
	
	this.run = function() {
		this.cal();
		
		if(this.sImageSrc) {
			if(!this.bImageIdExt) this.setImageIdExt();
			
			if(this.sDayId) {
				if(this.oTime.iDay.length >=2) {
					if(document.getElementById(this.sDayId+this.sImageIdTensExt).style.display == 'none')
						document.getElementById(this.sDayId+this.sImageIdTensExt).style.display = 'block';
					document.getElementById(this.sDayId+this.sImageIdTensExt).src = this.sImageSrc+this.oTime.iDay.substr(0,1)+this.sImagsExt;
					document.getElementById(this.sDayId+this.sImageIdUnitsExt).src = this.sImageSrc+this.oTime.iDay.substr(1,1)+this.sImagsExt;
				} else {
					if(document.getElementById(this.sDayId+this.sImageIdTensExt).style.display != 'none')
						document.getElementById(this.sDayId+this.sImageIdTensExt).style.display = 'none';
					document.getElementById(this.sDayId+this.sImageIdUnitsExt).src = this.sImageSrc+this.oTime.iDay+this.sImagsExt;
				}
			}
			if(this.sHourId) {
				if(this.oTime.iHour.length >=2) {
					if(document.getElementById(this.sHourId+this.sImageIdTensExt).style.display == 'none')
						document.getElementById(this.sHourId+this.sImageIdTensExt).style.display = 'block';
					document.getElementById(this.sHourId+this.sImageIdTensExt).src = this.sImageSrc+this.oTime.iHour.substr(0,1)+this.sImagsExt;
					document.getElementById(this.sHourId+this.sImageIdUnitsExt).src = this.sImageSrc+this.oTime.iHour.substr(1,1)+this.sImagsExt;
				} else {
					if(document.getElementById(this.sHourId+this.sImageIdTensExt).style.display != 'none')
						document.getElementById(this.sHourId+this.sImageIdTensExt).style.display = 'none';
					document.getElementById(this.sHourId+this.sImageIdUnitsExt).src = this.sImageSrc+this.oTime.iHour+this.sImagsExt;
				}
			}
			if(this.sMinId) {
				if(this.oTime.iMin.length >=2) {
					if(document.getElementById(this.sMinId+this.sImageIdTensExt).style.display == 'none')
						document.getElementById(this.sMinId+this.sImageIdTensExt).style.display = 'block';
					document.getElementById(this.sMinId+this.sImageIdTensExt).src = this.sImageSrc+this.oTime.iMin.substr(0,1)+this.sImagsExt;
					document.getElementById(this.sMinId+this.sImageIdUnitsExt).src = this.sImageSrc+this.oTime.iMin.substr(1,1)+this.sImagsExt;
				} else {
					if(document.getElementById(this.sMinId+this.sImageIdTensExt).style.display != 'none')
						document.getElementById(this.sMinId+this.sImageIdTensExt).style.display = 'none';
					document.getElementById(this.sMinId+this.sImageIdUnitsExt).src = this.sImageSrc+this.oTime.iMin+this.sImagsExt;
				}
			}
			if(this.sSecId) {
				if(this.oTime.iSec.length >=2) {
					if(document.getElementById(this.sSecId+this.sImageIdTensExt).style.display == 'none')
						document.getElementById(this.sSecId+this.sImageIdTensExt).style.display = 'block';
					document.getElementById(this.sSecId+this.sImageIdTensExt).src = this.sImageSrc+this.oTime.iSec.substr(0,1)+this.sImagsExt;
					document.getElementById(this.sSecId+this.sImageIdUnitsExt).src = this.sImageSrc+this.oTime.iSec.substr(1,1)+this.sImagsExt;
				} else {
					if(document.getElementById(this.sSecId+this.sImageIdTensExt).style.display != 'none')
						document.getElementById(this.sSecId+this.sImageIdTensExt).style.display = 'none';
					document.getElementById(this.sSecId+this.sImageIdUnitsExt).src = this.sImageSrc+this.oTime.iSec+this.sImagsExt;
				}
			}
		} else {
			if(this.sDayId) {
				document.getElementById(this.sDayId).innerHTML = this.oTime.iDay;
			}
			if(this.sHourId) {
				document.getElementById(this.sHourId).innerHTML = this.oTime.iHour;
			}
			if(this.sMinId) {
				document.getElementById(this.sMinId).innerHTML = this.oTime.iMin;
			}
			if(this.sSecId) {
				document.getElementById(this.sSecId).innerHTML = this.oTime.iSec;
			}
		}
		
		if(!this.oCountDown) this.oCountDown = window.setInterval(this.sObjectName!='' ? this.sObjectName+'.run()' : 'this.run()',1000);
		
		if(!this.oTime.result) {
			this.stop();
			return;
		}
	}
	
	this.stop = function() {
		if(this.oCountDown) window.clearInterval(this.oCountDown);
		
		if(this.bHide && this.sHideId) {
			document.getElementById(this.sHideId).style.display = 'none';
		}
	}
	
	this.strtotime = function (str, now) {
		// Convert string representation of date and time to a timestamp  
		// %        note 1: Examples all have a fixed timestamp to prevent tests to fail because of variable time(zones)
		// *     example 1: strtotime('+1 day', 1129633200);
		// *     returns 1: 1129719600
		// *     example 2: strtotime('+1 week 2 days 4 hours 2 seconds', 1129633200);
		// *     returns 2: 1130425202
		// *     example 3: strtotime('last month', 1129633200);
		// *     returns 3: 1127041200
		// *     example 4: strtotime('2009-05-04 08:30:00');
		// *     returns 4: 1241418600
	 
		var i, match, s, strTmp = '', parse = '';
	 
		strTmp = str;
		strTmp = strTmp.replace(/\s{2,}|^\s|\s$/g, ' '); // unecessary spaces
		strTmp = strTmp.replace(/[\t\r\n]/g, ''); // unecessary chars
	 
		if (strTmp == 'now') {
			return (new Date()).getTime()/1000; // Return seconds, not milli-seconds
		} else if (!isNaN(parse = Date.parse(strTmp))) {
			return (parse/1000);
		} else if (now) {
			now = new Date(now*1000); // Accept PHP-style seconds
		} else {
			now = new Date();
		}
	 
		strTmp = strTmp.toLowerCase();
	 
		var __is =
		{
			day:
			{
				'sun': 0,
				'mon': 1,
				'tue': 2,
				'wed': 3,
				'thu': 4,
				'fri': 5,
				'sat': 6
			},
			mon:
			{
				'jan': 0,
				'feb': 1,
				'mar': 2,
				'apr': 3,
				'may': 4,
				'jun': 5,
				'jul': 6,
				'aug': 7,
				'sep': 8,
				'oct': 9,
				'nov': 10,
				'dec': 11
			}
		};
	 
		var process = function (m) {
			var ago = (m[2] && m[2] == 'ago');
			var num = (num = m[0] == 'last' ? -1 : 1) * (ago ? -1 : 1);
	 
			switch (m[0]) {
				case 'last':
				case 'next':
					switch (m[1].substring(0, 3)) {
						case 'yea':
							now.setFullYear(now.getFullYear() + num);
							break;
						case 'mon':
							now.setMonth(now.getMonth() + num);
							break;
						case 'wee':
							now.setDate(now.getDate() + (num * 7));
							break;
						case 'day':
							now.setDate(now.getDate() + num);
							break;
						case 'hou':
							now.setHours(now.getHours() + num);
							break;
						case 'min':
							now.setMinutes(now.getMinutes() + num);
							break;
						case 'sec':
							now.setSeconds(now.getSeconds() + num);
							break;
						default:
							var day;
							if (typeof (day = __is.day[m[1].substring(0, 3)]) != 'undefined') {
								var diff = day - now.getDay();
								if (diff == 0) {
									diff = 7 * num;
								} else if (diff > 0) {
									if (m[0] == 'last') {diff -= 7;}
								} else {
									if (m[0] == 'next') {diff += 7;}
								}
								now.setDate(now.getDate() + diff);
							}
					}
					break;
	 
				default:
					if (/\d+/.test(m[0])) {
						num *= parseInt(m[0], 10);
	 
						switch (m[1].substring(0, 3)) {
							case 'yea':
								now.setFullYear(now.getFullYear() + num);
								break;
							case 'mon':
								now.setMonth(now.getMonth() + num);
								break;
							case 'wee':
								now.setDate(now.getDate() + (num * 7));
								break;
							case 'day':
								now.setDate(now.getDate() + num);
								break;
							case 'hou':
								now.setHours(now.getHours() + num);
								break;
							case 'min':
								now.setMinutes(now.getMinutes() + num);
								break;
							case 'sec':
								now.setSeconds(now.getSeconds() + num);
								break;
						}
					} else {
						return false;
					}
					break;
			}
			return true;
		};
	 
		match = strTmp.match(/^(\d{2,4}-\d{2}-\d{2})(?:\s(\d{1,2}:\d{2}(:\d{2})?)?(?:\.(\d+))?)?$/);
		if (match != null) {
			if (!match[2]) {
				match[2] = '00:00:00';
			} else if (!match[3]) {
				match[2] += ':00';
			}
	 
			s = match[1].split(/-/g);
	 
			for (i in __is.mon) {
				if (__is.mon[i] == s[1] - 1) {
					s[1] = i;
				}
			}
			s[0] = parseInt(s[0], 10);
	 
			s[0] = (s[0] >= 0 && s[0] <= 69) ? '20'+(s[0] < 10 ? '0'+s[0] : s[0]+'') : (s[0] >= 70 && s[0] <= 99) ? '19'+s[0] : s[0]+'';
			return parseInt(this.strtotime(s[2] + ' ' + s[1] + ' ' + s[0] + ' ' + match[2])+(match[4] ? match[4]/1000 : ''), 10);
		}
	 
		var regex = '([+-]?\\d+\\s'+
			'(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?'+
			'|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday'+
			'|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday)'+
			'|(last|next)\\s'+
			'(years?|months?|weeks?|days?|hours?|min|minutes?|sec|seconds?'+
			'|sun\\.?|sunday|mon\\.?|monday|tue\\.?|tuesday|wed\\.?|wednesday'+
			'|thu\\.?|thursday|fri\\.?|friday|sat\\.?|saturday))'+
			'(\\sago)?';
	 
		match = strTmp.match(new RegExp(regex, 'gi')); // Brett: seems should be case insensitive per docs, so added 'i'
		if (match == null) {
			return false;
		}
	 
		for (i = 0; i < match.length; i++) {
			if (!process(match[i].split(' '))) {
				return false;
			}
		}
	 
		return (now.getTime()/1000);
	}
	
	return this;
}
