// Copyright 2001-2005 Interakt Online. All rights reserved.

$SMD_MAIN_CLASSNAME = 'SmartDate';
$SMD_DIVPREFIX = 'smd_explanation_div_';
$SMDCAL_DIVPREFIX = 'smd_explanation_div_';

$SMD_GLOBALOBJECT = "SmartDates";
if (typeof window[$SMD_GLOBALOBJECT] == 'undefined') {
	window[$SMD_GLOBALOBJECT] = [];
}
$SMD_TICK_INCREMENT = [
	[0, 1, 60]
];

$SMD_VISUAL_ALERT_DIV_CLASSNAME = 'MXW_SMD_visual_alert_div';
$SMDCAL_VISUAL_ALERT_DIV_CLASSNAME = 'MXW_SMDCAL_visual_alert_div';
$SMD_VISUAL_ALERT_INPUT_CLASSNAME = 'MXW_SMD_visual_alert_input';
$SMDCAL_VISUAL_ALERT_INPUT_CLASSNAME = 'MXW_SMDCAL_visual_alert_input';

function SMD_date2regexp(txt, hold) {
	if (typeof hold == 'undefined') {
		hold = false;
	}
	txt = txt.replace(/[\/\-\.:]/g, 'DATESEPARATOR');
	txt = txt.replace(/([-\/\[\]()\*\+\.:])/g, '\\$1');
	if (hold) {
		txt = txt.replace(/DATESEPARATOR/g, '([\\/\\-\\.:])');
		txt = txt.replace(/(\\s)/g, '(\s)');
		txt = txt.replace(/ /g, '( )');
	} else {
		txt = txt.replace(/DATESEPARATOR/g, '[\\/\\-\\.:]');
		txt = txt.replace(/(\\s)/g, '\s');
	}
	txt = txt.replace(/yyyy/gi, '([0-9]{1,4})');
	txt = txt.replace(/yy/gi, '([0-9]{1,4})');
	txt = txt.replace(/y/gi, '([0-9]{1,4})');

	txt = txt.replace(/mm/ig, '([0-9]{1,2})');
	txt = txt.replace(/m/ig, '([0-9]{1,2})');

	txt = txt.replace(/dd/ig, '([0-9]{1,2})');
	txt = txt.replace(/d/ig, '([0-9]{1,2})');

	txt = txt.replace(/HH/ig, '([0-9]{1,2})');
	txt = txt.replace(/H/ig, '([0-9]{1,2})');

	txt = txt.replace(/hh/ig, '([0-9]{1,2})');
	txt = txt.replace(/h/ig, '([0-9]{1,2})');

	txt = txt.replace(/ii/ig, '([0-9]{1,2})');
	txt = txt.replace(/i/ig, '([0-9]{1,2})');

	txt = txt.replace(/ss/ig, '([0-9]{1,2})');
	txt = txt.replace(/s/ig, '([0-9]{1,2})');

	txt = txt.replace(/tt/ig, '(AM|PM|aM|Am|am|pM|Pm|pm)');
	txt = txt.replace(/t/ig, '(A|P|a|p)');

	var re = new RegExp('^' + txt + '$');
	return re;
}

function MXW_SmartDate(input, hasCalendar) {
	if (is.safari && is.version < 1.4) {
		return;
	}
	if (typeof hasCalendar == 'undefined') {
		this.hasCalendar = false;
	} else {
		this.hasCalendar = true;
	}
	var originalElement = document.getElementById(input);
	if (typeof(originalElement.kt_uni_attached) == 'undefined') {
		originalElement.kt_uni_attached = true;
	} else if (!this.hasCalendar){
		return;
	}

	this.name = input;
	this.input = originalElement;
	this.input.widget_id = this.name;
	this.input.widget_type = $SMD_GLOBALOBJECT;

	this.savedCSSStyle = this.input.style.cssText;
	if(this.savedCSSStyle == "{}") {
		//IEMac5.2 bug
		this.savedCSSStyle = "";
	}

	this.input.disableAutocomplete = true;
	this.input.setAttribute('disableAutocomplete', true);
	this.input.autocomplete = "off";
	this.input.setAttribute('autocomplete', 'off');
	
	this.inputRange = is.ie&&is.windows?this.input.createTextRange():(is.mozilla?null:null);
	this.defaultNow = (WDG_getAttributeNS(this.input, 'defaultnow')+'').toLowerCase()=="yes";
	this.restricttomask = (WDG_getAttributeNS(this.input, 'restricttomask')+'').toLowerCase()=="yes";
	this.curGroup = "d";
	var mask = WDG_getAttributeNS(this.input, 'mask');
	if (/H/.test(mask)) {
		mask = mask.replace(/\s*t/gi,"");
	}
	
	this.mask = MXW_SmartDate_normalizemask(mask);
	this.input.value = MXW_SmartDate_normalizevalue(this.mask, this.input.value);
	this.strikes = 0;
	this.input.maskDirty = false;

	var div = utility.dom.createElement('div', {
		'id': $SMD_DIVPREFIX+(this.hasCalendar?'CAL':'') + input, 
		'style': 'position: absolute; display: none; ', 
		'className': (this.hasCalendar?$SMD_VISUAL_ALERT_DIV_CLASSNAME:$SMDCAL_VISUAL_ALERT_DIV_CLASSNAME)
	});
	div.innerHTML = WDG_Messages["the_date_format_is"] + '&nbsp;' + this.mask;
	this.div = document.body.appendChild(div);
	this.div.style.display = 'none';
	this.div.style.position = 'absolute';
	
	this.spinner = (WDG_getAttributeNS(this.input, 'spinner')+'').toLowerCase()=="yes";

	var obj = this;
	this.readonly = (WDG_getAttributeNS(this.input, 'readonly')+'') == 'true';
	if (!this.readonly) {
		utility.dom.attachEvent(obj.input, (is.mozilla || is.opera)?"keypress":"keydown", function (e){return MXW_SmartDate_keydownhandler(obj, e);}, 1, false, false);
		utility.dom.attachEvent(obj.input, "keyup", function (e){return MXW_SmartDate_keyhandler(obj, e);}, 1, false, false);
	}
	utility.dom.attachEvent(obj.input, "blur", function (e){return MXW_SmartDate_blurhandler(obj, e);}, 1, false, false);
	utility.dom.attachEvent(obj.input, "focus", function (e){return MXW_SmartDate_focushandler(obj);}, 1, false, false);
	utility.dom.attachEvent(obj.input, "mouseup", function (e){
		obj.detectGroup(e);	
	}, 1, false, false);

	this.spinner = new MXW_Spin(this, $SMD_TICK_INCREMENT, this.spinner);

	window[$SMD_GLOBALOBJECT][input] = this;

	if (this.input.value != '') {
		try {
			var re = utility.date.date2regexp(this.mask);
			var arr = re.exec(this.input.value);
			var o = utility.date.parse_date(arr, this.mask);
			var newDate = new Date(o['year'], o['month']-1, o['day'], o['hour'], o['minutes'], o['seconds']);
		} catch(e) { newDate = false; }
		if (newDate) {
			this.dateToMask(newDate);
		}
	}

	if (this.defaultNow && this.input.value == "") {
		this.setNow();
	}

	this.setEnabled(!this.input.disabled);
	try {Kore.addUnloadListener(this.dispose, this);}catch(err){}
	return this;
}
MXW_SmartDate_dispose = function() {
	try {Kore.removeUnloadListener(this.dispose, this);} catch(err) {}
	try {this.div.parentNode.removeChild(this.div);}catch(err) {}
	try{delete window[$SMD_GLOBALOBJECT][this.name];}catch(err){}
}
MXW_SmartDate.prototype.dispose = MXW_SmartDate_dispose;

function MXW_SmartDate_setEnabled(state) {
	this.input.disabled = !state;
	this.spinner.setEnabled(state);

	if(typeof window[$CAL_GLOBALOBJECT] != undefined && typeof window[$CAL_GLOBALOBJECT][this.name] != 'undefined') {
		window[$CAL_GLOBALOBJECT][this.name].setEnabled(state);
	}

}
MXW_SmartDate.prototype.setEnabled = MXW_SmartDate_setEnabled;

function MXW_SmartDate_normalizemask(mask) {
	toret = '';

	var date = mask.split(/[\-\/\[\]()\*\+\\\.]/g);
	var sep = '', c = '', dt = '', tm = '';
	var c = '';
	sep = /([\-\/\[\]()\*\+\\\.])/.exec(mask)[0];
	Array_each(date, function(c, i) {
		c = c.toUpperCase();
		switch (c) {
			case 'D' : 
				date[i] = 'dd';
				break;
			case 'M' : 
				date[i] = 'mm';
				break;
			case 'Y' : 
				date[i] = 'yy';
				break;
		}
	});
	dt = date.join(sep);//.toUpperCase();
	if (mask.indexOf(' ') >= 0) {
		//TIME
		maskarr = mask.split(' ');
		
		var tmp = mask.substring(mask.indexOf(' ')+1, mask.length).replace(/m/ig, 'i');
		
		var time = tmp.split(/ /g);
		if (typeof time[1] != 'undefined') {
			var trailing = ' '  + time[1];
		} else {
			var trailing = '';
		}
		time = time[0].split(':');
		
		
		Array_each(time, function(c, i) {
			switch (c) {
				case 'H' : 
				case 'HH' : 
					time[i] = 'HH';
					break;
				case 'h' : 
				case 'hh' : 
					time[i] = 'hh';
					break;
				case 'i' : 
				case 'ii' :
				case 'I' : 
				case 'II':
					time[i] = 'ii';
					break;
				case 's' : 
				case 'ss' :
				case 'S' : 
				case 'SS':
					time[i] = 'ss';
					break;
			}
		});
		tm = time.join(':') + trailing;
		dt = dt.split(' ')[0] + ' ' + tm;
	}
	return dt;
}

function MXW_SmartDate_normalizevalue(mask, value) {
	var re = SMD_date2regexp(mask, true);
	var arr = re.exec(value);
	if (arr) {
		var toret = '';
		Array_shift(arr);
		Array_each(arr, function(el, i) {
			if (el.match(/^[0-9]*$/)) {
				if (parseInt(el, 10) < 10 && !el.match(/^0*$/)) {
					arr[i] = '0' + parseInt(el, 10);
				}
			}
			toret += arr[i];
		});
		return toret;
	} else {
		return value;
	}
}

function MXW_SmartDate_toregexp(txt) {
	txt = txt.replace(/([\-\/\[\]()\*\+\\\.])/g, '\\$1');
	txt = txt.replace(/d/g, '||');
	txt = txt.replace(/D/g, '||');
	txt = txt.replace(/M/g, '\\d');
	txt = txt.replace(/m/g, '\\d');
	txt = txt.replace(/Y/g, '\\d');
	txt = txt.replace(/y/g, '\\d');
	txt = txt.replace(/H/ig, '\\d');
	txt = txt.replace(/I/ig, '\\d');
	txt = txt.replace(/S/ig, '\\d');
	txt = txt.replace(/tt/g, '(AM|PM|aM|Am|am|pM|Pm|pm)');
	txt = txt.replace(/t/g, '(A|P|a|p)');
	txt = txt.replace(/\?/g, '.');
	txt = txt.replace(/\./g, '\.');
	txt = txt.replace(/\|\|/g, '\\d')
	return txt;
}

function MXW_SmartDate_dateToMask(date) {
	var y = date.getFullYear();
	var m = date.getMonth()+1;
	var d = date.getDate();
	var h = date.getHours();
	var i = date.getMinutes();
	var s = date.getSeconds();

	if (m < 10) m = "0" + m;
	if (d < 10) d = "0" + d;
	
	if (i < 10) i = "0" + i;
	if (s < 10) s = "0" + s;
	if (/yyyy/i.test(this.mask)) {
		while (y.length < 4) {
			y = "0" + y;
		}
	} else if(/yy/i.test(this.mask)) {
		y +="";
		y = y.replace(/(.*)(\d\d)$/, "$2");

		while (y.length < 2) {
			y = "0" + y;
		}
	} else if(/y/i.test(this.mask)) {
		y +="";
		y = y.replace(/(.*)(\d)$/, "$2");
		while (y.length < 1) {
			y = "0" + y;
		}
	}

	var tmp = this.mask;
	tmp = tmp.replace(/D+/i, d);
	tmp = tmp.replace(/M+/i, m);
	tmp = tmp.replace(/Y+/i, y);
	tmp = tmp.replace(/I+/i, i);
	tmp = tmp.replace(/S+/i, s);

	if (this.mask.toLowerCase().indexOf('t') >= 0) {
		if (this.mask.toLowerCase().indexOf('tt') >= 0) {
			var toadd = ['AM', 'PM'];
		} else {
			var toadd = ['A', 'P'];
		}

		var t = "";
		if(/HH|H/.test(this.mask)) {
			//24-hour clock
			t = "";
		} else if(/hh|h/.test(this.mask)) {
			//12-hour clock	
			if(h==0) {
				h = 12;
				t = toadd[0];
			} else if (h>=13 && h<=23){
				h = h - 12;
				t = toadd[1];
			} else if (h >= 1 && h <12) {
				t = toadd[0];
			} else if (h == 12) {
				h = 12;
				t = toadd[1];
			}
		}
		tmp = tmp.replace(/t+/i, t);
	}
	if (h < 10 && /hh/i.test(this.mask)){
		h = "0" + h;
	}
	tmp = tmp.replace(/H+/i, h);

	if (this.input.value != tmp) {
		this.input.maskDirty = true;
		this.input.value = tmp;
	}
	return tmp;
}
MXW_SmartDate.prototype.dateToMask = MXW_SmartDate_dateToMask;

function MXW_SmartDate_validate() {
	var mask = this.mask;
	var size = this.input.value.length;
	if (size > mask.length) {
		size = mask.length;
	}
	// validate the input value with the masks' regexp
	var re = new RegExp('^' + MXW_SmartDate_toregexp(mask.substr(0, size)) + '$');
	return this.input.value.match(re);
}
MXW_SmartDate.prototype.validate = MXW_SmartDate_validate;

function MXW_SmartDate_blurhandler(obj, evt) {
	if (obj.mousedown) {
		return true;
	}
	MXW_visualAlert(obj, 0, 'SMD'+(obj.hasCalendar?'CAL':''));
	obj.strikes = 0;
	
	obj.kt_focused = false;

	if (!obj.validate()) { 
		if (obj.input.lastGoodMatched) {
			obj.input.value = obj.input.lastGoodMatched;
		} else {
			obj.input.value = '';
		}
	} else {
		obj.input.lastGoodMatched = obj.input.value;
	}
	/*
	if(obj.input.value !="" && obj.input.value.length != obj.mask.length) {
		obj.setNow();
		return true;
	}
	*/
	// re-get the text size
	size = obj.input.value.length;

	//if we have entered 10 chars that means we have entered a potential date
	//check this date and convert it eventually to a valid date
	if (size == obj.mask.length) {
		var tmp = obj.getInputDate();
		if (tmp) {
			obj.dateToMask(tmp);
		}
	}

	if (obj.input.maskDirty) {
		obj.input.maskDirty = false;
		if (obj.input.fireEvent) {
			obj.input.fireEvent("onchange");
		} else if(document.createEvent){
			var me = document.createEvent("Events");
			me.initEvent('change', 0, 0);
			obj.input.dispatchEvent(me);
		}
	}

	return true;
}

function MXW_SmartDate_formhandler(input, evt) {
	var obj = window[$SMD_GLOBALOBJECT][input];
	//if there is no 
	if (obj.defaultNow && obj.input.value == '') {
		obj.setNow();
		return true;
	} else {
		var test_value = obj.input.value;
		if (/ tt/.test(obj.mask)) {
			test_value = test_value.replace(/ A$/i, ' AM');
			test_value = test_value.replace(/ P$/i, ' PM');
		}

		var re_full = new RegExp('^' + MXW_SmartDate_toregexp(obj.mask) + '$');
		var re_piece = new RegExp('^' + MXW_SmartDate_toregexp(obj.mask.substring(0, obj.input.value.length)) + '$');

		if (obj.restricttomask) {
			if (obj.input.value == '') {
				return true;
			}
			if (!obj.input.value.match(re_full)) {
				obj.strikes = 3;
				MXW_visualAlert(obj, 1, 'SMD'+(obj.hasCalendar?'CAL':''));
				utility.dom.stopEvent(evt);
				try {
					obj.input.focus();
				} catch(e) { }
				return false;
			} else {
				var olddate = obj.getInputDate();
				if (olddate) {
					MXW_visualAlert(obj, 0, 'SMD'+(obj.hasCalendar?'CAL':''));
					var date = olddate;
					date = obj.dateToMask(date);
					return true;
				} else {
					MXW_visualAlert(obj, 1, 'SMD'+(obj.hasCalendar?'CAL':''));
					try {
						obj.input.focus();
					} catch(e) { }
					utility.dom.stopEvent(evt);
					return false;
				}
			}
		} else {
			if (obj.input.value == '') {
				return true;
			}
			if (test_value.match(re_piece)) {
				return true;
			} else {
				obj.strikes = 3;
				MXW_visualAlert(obj, 1, 'SMD'+(obj.hasCalendar?'CAL':''));
				