var focusInvalid = false;

function noTwice(o) {
	if (o.id && o.id.length) 
		setTimeout("top.content.gid('" + o.id + "').disabled = false", noTwice.arguments.length > 1 ? noTwice.arguments[1] : 7500);
	o.disabled = true;
}
	
function nextTabIndex(o, z) {
	var inputs = document.getElementsByTagName('input');
	for (i=0; i < inputs.length; i=i+1) if (inputs[i].tabIndex == o.tabIndex + z) {inputs[i].focus(); return false;}

	var textareas = document.getElementsByTagName('textarea');
	for (i=0; i < textareas.length; i=i+1) if (textareas[i].tabIndex == o.tabIndex + z) {textareas[i].focus(); return false;}

	var buttons = document.getElementsByTagName('button');
	for (i=0; i < buttons.length; i=i+1) if (buttons[i].tabIndex == o.tabIndex + z) {buttons[i].focus(); return false;}

	var selects = document.getElementsByTagName('select');
	for (i=0; i < selects.length; i=i+1) if (selects[i].tabIndex == o.tabIndex + z) {selects[i].focus(); return false;}
}

function upDown(o, keyCode) {
	if (keyCode == 38 && o.tabIndex > 2) {nextTabIndex(o, -2); event.cancelBubble = true; event.returnValue = false;}
	if (keyCode == 40) {nextTabIndex(o, 2); event.cancelBubble = true; event.returnValue = false;}
}

function operatorAll(o) {
	var oAll = new Array;
	oAll[0] = new Option(String.fromCharCode(61)); oAll[0].value = '='; 
	oAll[1] = new Option(String.fromCharCode(60)); oAll[1].value = '<'; 
	oAll[2] = new Option(String.fromCharCode(62)); oAll[2].value = '>'; 
	oAll[3] = new Option(String.fromCharCode(185)); oAll[3].value = '<>'; 
	oAll[4] = new Option(String.fromCharCode(163)); oAll[4].value = '<='; 
	oAll[5] = new Option(String.fromCharCode(179)); oAll[5].value = '>='; 
	oAll[6] = new Option(String.fromCharCode(171)); oAll[6].value = 'BETWEEN';
	oAll[7] = new Option(String.fromCharCode(206)); oAll[7].value = 'IS NULL';
	oAll[8] = new Option(String.fromCharCode(207)); oAll[8].value = 'IS NOT NULL';
	
	for (var i=o.length; i > 0; i--) o.options[i] = null;
	for (var i=0; i < 6; i++) o.options[i] = oAll[i];
}

function operatorNOT(o) {
	var oNOT = new Array();
	oNOT[0] = new Option(String.fromCharCode(61)); oNOT[0].value = 'BETWEEN'; 
	oNOT[1] = new Option(String.fromCharCode(185)); oNOT[1].value = 'NOT BETWEEN'; 
	
	for (var i=o.length; i > 0; i--) o.options[i] = null;
	for (var i=0; i < 2; i++) o.options[i] = oNOT[i];
}

function _CF_checkeurodate(object_value) {
    //Returns true if value is a eurodate format or is NULL
    //otherwise returns false	

    if (object_value.length == 0) return true;

    //Returns true if value is a date in the dd/mm/yy format
	var isplit = object_value.indexOf('/');

	if (isplit == -1) isplit = object_value.indexOf('.');
	if (isplit == -1 || isplit == object_value.length) return false;

    var sDay = object_value.substring(0, isplit);
	var monthSplit = isplit + 1;
	var isplit = object_value.indexOf('/', monthSplit);

	if (isplit == -1) isplit = object_value.indexOf('.', monthSplit);
	if (isplit == -1 || (isplit + 1) == object_value.length) return false;

    var sMonth = object_value.substring((sDay.length + 1), isplit);
	var sYear = object_value.substring(isplit + 1);

	if (!_CF_checkinteger(sMonth)) return false; //check month
	else if (!_CF_checkrange(sMonth, 1, 12)) return false; // check month
	else if (!_CF_checkinteger(sYear)) return false; //check year

	if (sYear.length != 2 && sYear.length != 4) return false; // check year is only 2 digits
	else if (!_CF_checkrange(sYear, 0, null)) return false; //check year
	else if (!_CF_checkinteger(sDay)) return false; //check day
	else if (!_CF_checkday(sYear, sMonth, sDay)) return false; //check day
	else return true;
}

function _CF_checkday(checkYear, checkMonth, checkDay) {
	var maxDay = 31;

	if (checkMonth == 4 || checkMonth == 6 || checkMonth == 9 || checkMonth == 11) maxDay = 30;
	else
		if (checkMonth == 2) {
			if (checkYear % 4 > 0) maxDay =28;
			else if (checkYear % 100 == 0 && checkYear % 400 > 0) maxDay = 28;
			else maxDay = 29;
	}
	return _CF_checkrange(checkDay, 1, maxDay); //check day
}

function _CF_checkinteger(object_value) {
    //Returns true if value is a number or is NULL
    //otherwise returns false	

    if (object_value.length == 0) return true;

    //Returns true if value is an integer defined as
    //   having an optional leading + or -.
    //   otherwise containing only the characters 0-9.
	var decimal_format = ".";
	var check_char;

    //The first character can be + -  blank or a digit.
	check_char = object_value.indexOf(decimal_format)
    //Was it a decimal?
    if (check_char < 1) return _CF_checknumber(object_value);
    else return false;
}

function _CF_numberrange(object_value, min_value, max_value) {
    // check minimum
    if (min_value != null && object_value < min_value) return false;

    // check maximum
    if (max_value != null && object_value > max_value) return false;
	
    //All tests passed, so...
    return true;
}

function _CF_checknumber(object_value) {
    //Returns true if value is a number or is NULL
    //otherwise returns false	

    if (object_value.length == 0) return true;

    //Returns true if value is a number defined as
    //   having an optional leading + or -.
    //   having at most 1 decimal point.
    //   otherwise containing only the characters 0-9.
	var start_format = " .+-0123456789";
	var number_format = " .0123456789";
	var check_char;
	var decimal = false;
	var trailing_blank = false;
	var digits = false;

    //The first character can be + - .  blank or a digit.
	check_char = start_format.indexOf(object_value.charAt(0))
    //Was it a decimal?
	if (check_char == 1)
	    decimal = true;
	else if (check_char < 1)
		return false;
        
	//Remaining characters can be only . or a digit, but only one decimal.
	for (var i=1; i < object_value.length; i++) {
		check_char = number_format.indexOf(object_value.charAt(i))
		if (check_char < 0)
			return false;
		else if (check_char == 1) {
			if (decimal)		// Second decimal.
				return false;
			else
				decimal = true;
		}
		else if (check_char == 0) {
			if (decimal || digits) trailing_blank = true;
	        // ignore leading blanks
		}
	        else if (trailing_blank)
			return false;
		else
			digits = true;
	}	
    //All tests passed, so...
    return true
}

function _CF_checkrange(object_value, min_value, max_value) {
   //if value is in range then return true else return false
	if (object_value.length == 0) return true;

	if (!_CF_checknumber(object_value)) return false;
	else return (_CF_numberrange((eval(object_value)), min_value, max_value));
}

// RADAR routines from here on 
function nice(n) {
	n = n.replace(/_/g, ' ');
	if (n.indexOf('genVirtual') > -1) return n.substring(11); else return n;
}

function validateRequired(o) {
	if (!focusInvalid) 
		if (!o.value.length) { 
			alert(nice(o.name) + ': This field requires a value.');
			focusInvalid = true; if (o.type != 'hidden') {o.focus(); o.select();}
			return false;
		}
		else return true;
	else focusInvalid = false;
	return true;
}

function validateRequiredADO(o, name) {
	if (gid(o).recordset.recordCount == 0) { 
		alert(name + ' : This list needs a value.');
		return false;
	}
	return true;
}

// Bay format Area-Bay-Shelf-biN converts A(B)BS(N) to A-BB-0S-N. Only allows for 10 (1 to 0) Shelves. Default biN 1.
function validateBay(o) {
	// C15   = C-01-05-1
	// C015  = C-01-05-1
	// C155  = C-15-05-1
	// C0155 = C-01-05-5	So you must use 4 digits to specify the bin.
	
	if (!focusInvalid) {
		if (o.value.length) {
			o.value = o.value.replace(/_/g, '');
		}

		var sAlpha = /[ABCDEFKNPQRSW]/;
		var sDigit = /[0-9]/;
		o.value = o.value.toUpperCase();

		if ((o.value.substr(0, 1).search(sAlpha) == -1
			|| o.value.substr(1, 2).search(sDigit) == -1
			|| o.value.substr(3, 1).search(sDigit) == -1)
			&& o.value.length) {
			focusInvalid = true; if (confirm(nice(o.name) + ': This field requires Bay syntax ABBS)! eg. C019 = C-01-9, C190 = C-19-10') && o.type != 'hidden') {o.focus(); o.select();}
			return false;
		}
		return true;
	}
	else focusInvalid = false;
	return true;
}

// Return the first selected select in a multiselect
function selectedSelectValue(o) {
	for (var i=0; i < o.options.length; i++)
		if (o.options[i].selected) return i;
	return -1;
}

// Return the selected values in a multiselect
function selectedSelectValues(o) {
	var aSelected = new Array();
	for (var i=0; i < o.options.length; i++)
		if (o.options[i].selected) aSelected[aSelected.length] = i;
	return aSelected;
}

// Return the first checked checkbox in a set
function checkedCheckboxValue(o) {
	if (o.length > 0) {
		for (var i=0; i < o.length; i++)
			if (o[i].checked) return i;
	}
	else if (o.checked) return 0;
	return -1;
}

// Return a list of checked values for multiple checkboxes, overload with form
function checkedCheckBoxValues(o) {
	var x = '0';
	var inputs = document.getElementsByTagName('INPUT');
	for (var i=0; i < inputs.length; i++) {
		if (inputs[i].name.indexOf(o) > -1 && inputs[i].checked && inputs[i].value != 'on' && inputs[i].value.length
			&& (checkedCheckBoxValues.arguments.length == 1 || inputs[i].form == checkedCheckBoxValues.arguments[1]))
			x = (inputs[i].value + ',') + x;
	}
	return x;
}

function validateSelectRequired(o) {
	if (!o.options) {alert(o.name + ' does not contain options. Notify IT. Line 263 validation.js'); return true;}
	if (!focusInvalid) {
		for (var i=0; i < o.options.length; i++)
			if (o.options[i].selected) return true;

		alert(nice(o.name) + ': This field requires a value.');
		focusInvalid = true; 
		if (o.type != 'hidden') o.focus(); 
		return false;
	}
	else focusInvalid = false;
	return true;
}

function validateInteger(o) {
	if (!focusInvalid) {
		if (o.value.indexOf('.') != -1) o.value = o.value.substring(0, o.value.indexOf('.'));

		o.value = o.value.replace(/[^0-9]/g, '');
	
		if (!_CF_checknumber(o.value) || o.value.indexOf('.') != -1) {
			alert(nice(o.name) + ': Please enter a number with no fraction. (eg. 5)');
			focusInvalid = true; if (o.type != 'hidden') {o.focus(); o.select();}
			return false;
		}
		else return true;
	}
	else focusInvalid = false;
	return true;
}

function validateRange(o, minvalue, maxvalue) {
	if (!focusInvalid) 
		if (!_CF_checkrange(o.value, minvalue, maxvalue)) {
			alert(nice(o.name) + ': Please enter a number between (including) ' + minvalue + ' and ' + maxvalue + '.');
			focusInvalid = true; if (o.type != 'hidden') {o.focus(); o.select();}
			return false;
		}
		else return true;
	else focusInvalid = false;
	return true;
}

function validateSafeRange(o, minvalue, maxvalue) {
	if (!focusInvalid) 
		if (!_CF_checkrange(o.value, minvalue, maxvalue)) {
			if (confirm(nice(o.name) + ': Please enter a number between (including) ' + minvalue + ' and ' + maxvalue + '.')) {
				if (o.type != 'hidden') {o.focus(); o.select();}
			}
			focusInvalid = true; 
			return false;
		}
		else return true;
	else focusInvalid = false;
	return true;
}

function validateXltY(o, x, y, message) {
	if (!focusInvalid) 
		if (x > y) { 
			alert(message);
			focusInvalid = true; if (o.type != 'hidden') {o.focus(); o.select();}
			return false;
		}
		else return true;
	else focusInvalid = false;
	return true;
}

// Forces D[D]/M[M][/YY[YY]]
function validateDate(o) {
	if (!focusInvalid) {
		// Append current year for dd/mm entries
		if (o.value.length > 1 && o.value.length < 6) {
			var sYear = new Date().getYear().toString(); 
			sYear = sYear.substring(sYear.length - 2, sYear.length); 
			o.value += '/' + sYear;
		} 
	
		if (!_CF_checkeurodate(o.value)) { 
			alert(nice(o.name) + ': Please enter a valid date in DD/MM[/YY[YY]] format.'); 
			focusInvalid = true; if (o.type != 'hidden') {o.focus(); o.select();}
			return false;
		}
		else {
			if (o.value.length) {
				var tDate = o.value.split('/');
				if (tDate.length < 3) tDate = o.value.split('.');
				if (tDate[0].length < 2) tDate[0] = '0' + tDate[0]; // Two digit Day
				if (tDate[1].length < 2) tDate[1] = '0' + tDate[1]; // Two digit Month
				if (tDate[2].length < 4) tDate[2] = ((tDate[2] < 20) ? '20' : '19') + tDate[2]; // Four digit Year
				o.value = tDate[0] + '/' + tDate[1] + '/' + tDate[2];
			}
			return true;
		}
	}
	else focusInvalid = false;
	return true;
}

// Forces d[d]/m[m][/yy[yy]][ hh:mm[:ss]]
function validateTime(o) {
	if (!focusInvalid) {
		// Missing the time. Presume 00:00[:00]
		if (o.value.length && o.value.indexOf(':') == -1) o.value += ' 00:00';
		
		var v = o.value;
		var f = v.indexOf(':');
		var l = v.lastIndexOf(':');
	
		// Forces HH:MM or HH:MM:SS input 
		if ( (v.length > 0) &&
				(	!_CF_checkrange(v.substring(f - 2, f), 0, 23)
					|| !_CF_checkrange(v.substring(f + 1, f + 3), 0, 59)
					|| !_CF_checkrange(v.substring(l + 1), 0, 59)
					|| (l != v.length - 3)
				) 
		) { 
			alert(nice(o.name) + ': Please enter a time stamp in DD/MM[/YY[YY]][ HH:MM[:SS]] format. [optional]');
			focusInvalid = true; if (o.type != 'hidden') {o.focus(); o.select();}
			return false;
		}
		else 
		// Now check the date
		{	if (v.length > 0) {
				var tTime = o.value.substring(f - 2);
				o.value = o.value.substring(0, f - 3);
				if (!validateDate(o)) {
					o.value = o.value + ' ' + tTime;
					return false;
				}
				o.value = o.value + ' ' + tTime;
			}
			return true;
		}
	}
	else focusInvalid = false;
	return true;	
}
	
function validateEmail(o) {
	if (!focusInvalid) {
		var addrs = new Array(1);
		addrs = o.value.split(',');
		
		for (var a=0; a < addrs.length; a++) {
			// Smallest example: z@z.jp (012345) length 6
			var At = addrs[a].indexOf('@');
			var space = addrs[a].indexOf(' '); // No spaces
			var lineBreak = addrs[a].indexOf(String.fromCharCode(13, 10)); // No line breaks
			var Dot = addrs[a].lastIndexOf('.'); // Not perfect. Allows fred@this..net
		
			if ( (addrs[a].length > 0) && ( (lineBreak > -1) || (space > -1) || (At < 1) || (Dot < At + 2) || (Dot > addrs[a].length - 2) ) ) { 
				alert(nice(o.name) + ': Please enter an email address in name@domain.com format. No spaces. No line breaks. Seperate addresses with a comma.'); 
				focusInvalid = true; if (o.type != 'hidden') {o.focus(); o.select();}
				return false;
			}
		}
		return true;
	}
	else focusInvalid = false;
	return true;
}
	
function validateMoney(o) {
	if (!focusInvalid) {
		if (o.value.indexOf('.') == 0) o.value = '0' + o.value;

		var stripAll = /[^0-9\+\-\.]/g;
		o.value = o.value.replace(stripAll, "");

		if (!_CF_checknumber(o.value)) { 
			alert(nice(o.name) + ': Please enter a numeric value. (eg. 123.45)');
			focusInvalid = true; if (o.type != 'hidden') {o.focus(); o.select();}
			return false;
		}
		else return true;
	}
	else focusInvalid = false;
	return true;	
}

function validatePercentage(o) {
	if (!focusInvalid) {
		var stripAll = /[^0-9\+\-\.]/g;
		o.value = o.value.replace(stripAll, "");

		if (!_CF_checknumber(o.value)) { 
			alert(nice(o.name) + ': Please enter a numeric value. (eg. 123.45)');
			focusInvalid = true; if (o.type != 'hidden') {o.focus(); o.select();}
			return false;
		}
		else if (!_CF_checkrange(o.value, -100, 100)) { 
			alert(nice(o.name) + ': Please enter a number from -100 to 100. (eg. 75.25)');
			focusInvalid = true; if (o.type != 'hidden') {o.focus(); o.select();}
			return false;
		}
		else return true;
	}
	else focusInvalid = false;
	return true;	
}

// Optional 3rd element indicates 2nd element is min length
function validateLength(o, l) {
	tal = o;

	if (validateLength.arguments.length == 3 
		&& (o.value.length < validateLength.arguments[2] || o.value.length >= validateLength.arguments[3])) {
		if (!focusInvalid) {
			focusInvalid = true; if (o.type != 'hidden') {o.focus(); o.select();}
			alert(nice(o.name) + ': Must be between ' + validateLength.arguments[2] + ' and ' + validateLength.arguments[2] + ' characters.');
		}
		else focusInvalid = false;
		return false;
	}
	
	if (o.value.length > l) {
		o.style.background = 'red'; 
		setTimeout('tal.style.background = \'white\';', 1000); 
		o.value = o.value.substring(0, l - 1); 
	}
}

function trim(v) {
	var stripSpace = / */;
	return v.replace(stripSpace, "");
}

// No week ends - Makes Saturday Friday and Sunday Monday
function validateWeekDay(o) {
	var tempDate = new Date();
	
	if (dateFromEuro(o.value).getDay() == 6) {
		tempDate.setTime(dateFromEuro(o.value).getTime() - oneDay);
		o.value = dateToEuro(tempDate);
	}
	
	if (dateFromEuro(o.value).getDay() == 0) {
		tempDate.setTime(dateFromEuro(o.value).getTime() + oneDay);
		o.value = dateToEuro(tempDate);
	}	
}

// Specify a as a numeric date value as day + month * 31 + year * 365.
function validateDateAfter(o, a) {
    //Returns true if value is a date in the dd/mm/yy format
	var isplit = o.value.indexOf('/');

	if (isplit == -1) isplit = o.value.indexOf('.');
	if (isplit == -1 || isplit == o.value.length) return false;

    var sDay = o.value.substring(0, isplit);
	var monthSplit = isplit + 1;
	isplit = o.value.indexOf('/', monthSplit);

	if (isplit == -1) isplit = o.value.indexOf('.', monthSplit);
	if (isplit == -1 || (isplit + 1) == o.value.length) return false;

    var sMonth = o.value.substring((sDay.length + 1), isplit);
	var sYear = o.value.substring(isplit + 1);
	
	if (sYear.length < 3) sYear += 2000;

	if (Number(sDay) + Number(sMonth) * 31 + Number(sYear) * 365 < a) {
		alert(nice(o.name) + ': Must be in the future.'); 
		focusInvalid = true; 
		if (o.type != 'hidden' && !focusInvalid) {
			o.focus();
			o.select();
		}
		return false;
	} else {
		focusInvalid = false;
		return true;
	}
}

// "Date Abilities" - Allow relative modification of dates with + and -, (d)ay [default], (w)eek, (m)onth and (y)ear for keys 1 to [1]0.
var timeMod = 0;
var now = new Date().getTime();
var oneDay = 1000 * 60 * 60 * 24;
var tempDate = new Date();
var days = new Array('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');

function dateFromEuro(e) {
	if (e.indexOf(' ') > -1) e = e.substr(0, e.indexOf(' '));
	return new Date((e.substring(6) <= 20) ? '20' + e.substring(6) : e.substring(6), e.substr(3, 2) - 1, e.substr(0, 2));
}

function dateToEuro(d) {
	var td = (d.getDate() < 10) ? ('0' + d.getDate()) : d.getDate();
	td += '/' + String((d.getMonth() < 9) ? ('0' + (d.getMonth() + 1)) : (d.getMonth() + 1));
	return td + '/' + d.getFullYear();
}

function showDay(o) {
	if (o.value.length > 0) {
		o.nextSibling.innerText = days[dateFromEuro(o.value).getDay()];
		o.nextSibling.style.color = (dateFromEuro(o.value).getTime() > now) ? 'black' : '#8DB548';
	}
}

function dateAbilities(o, e) {
	var tempDate = new Date();
	var apply = false;
	
	if (window.event) e = window.event; else {
		// x-browser compatibility
		if (o.value.toLowerCase() == 't') {
			o.value = dateToEuro(tempDate);
			if (dateAbilities.arguments.length == 1) showDay(o);
			returnValue = false;
			cancelBubble = true;
			return false;
		}
		return true;
	}
	
	// (C)alendar
	if (event.keyCode == 67) {
		var x = gid(o.id + '_datePicker').onclick;
		returnValue = false;
		event.cancelBubble = true;
		x();
		return false;
	}
	// (T)oday
	else if (event.keyCode == 84) {
		o.value = dateToEuro(tempDate);
		timeMod = 0;
		apply = true;
	}
	// Alt Up = -year. Ctrl Up = -month. Up = -day. 
	else if (event.keyCode == 38) {
		if (event.altKey) {tv = dateFromEuro(o.value); o.value = dateToEuro(new Date(tv.getFullYear() - 1, tv.getMonth(), tv.getDate()));}
		else if (event.ctrlKey) {
			var tv = dateFromEuro(o.value);
			o.value = dateToEuro(new Date((tv.getMonth() == 0) ? tv.getFullYear() - 1 : tv.getFullYear(), (11 - ((11 - tv.getMonth()) + 1) % 12), tv.getDate()));
		}
		else {tempDate.setTime(dateFromEuro(o.value).getTime() - oneDay); o.value = dateToEuro(tempDate);}
	}
	// Alt Down = year. Ctrl Down = month. Down = day. 
	else if (event.keyCode == 40) {
		if (event.altKey) {tv = dateFromEuro(o.value); o.value = dateToEuro(new Date(tv.getFullYear() + 1, tv.getMonth(), tv.getDate()));}
		else if (event.ctrlKey) {
			var tv = dateFromEuro(o.value);
			o.value = dateToEuro(new Date((tv.getMonth() == 11) ? tv.getFullYear() + 1 : tv.getFullYear(), (tv.getMonth() + 1) % 12, tv.getDate()));
		}
		else {tempDate.setTime(dateFromEuro(o.value).getTime() + oneDay); o.value = dateToEuro(tempDate);}
	}	
	// We are currently modifying ... look for numbers or d, w, m, y.
	else if (timeMod != 0) {
		// Second Plus (apply existing modifier) or changing to plus (set default).
		if (event.keyCode == 107 || event.keyCode == 187) 
			if (timeMod > 0) apply = true; else timeMod = oneDay;
		// Second Minus (apply existing modifier) or changing to minus (set default).
		else if (event.keyCode == 109 || event.keyCode == 189) 
			if (timeMod < 0) apply = true; else timeMod = -oneDay;
		// Top numbers 1-[1]0. Set multiplicant and apply modifier.
		else if (event.keyCode >= 48 && event.keyCode <= 57) {
			timeMod *= (event.keyCode == 48) ? 10 : (event.keyCode - 48);
			apply = true;
		}
		//  Numpad 0-9. Set multiplicant and apply modifier.
		else if (event.keyCode >= 96 && event.keyCode <= 105) {
			timeMod *= (event.keyCode == 96) ? 10 : (event.keyCode - 96);
			apply = true;
		}
		// (D)ay - dd is one day [Just for completeness]
		else if (event.keyCode == 68) 
			if (Math.abs(timeMod) == oneDay + 1) apply = true; else timeMod = (timeMod / Math.abs(timeMod)) * oneDay + 1;
		// (W)eek - ww is one week
		else if (event.keyCode == 87) 
			if (Math.abs(timeMod) == oneDay * 7) apply = true; else timeMod = (timeMod / Math.abs(timeMod)) * oneDay * 7;
		// (M)onth - mm is one month
		else if (event.keyCode == 77) 
			if (Math.abs(timeMod) == oneDay * 31) apply = true; else timeMod = (timeMod / Math.abs(timeMod)) * oneDay * 31;
		// (Y)eek - yy is one year.
		else if (event.keyCode == 89) 
			if (Math.abs(timeMod) == oneDay * 365.25) apply = true; else timeMod = (timeMod / Math.abs(timeMod)) * oneDay * 365.25;
		// Anything else stops the modifying and is accepted as typed
		else {
			timeMod = 0;
			o.style.background = 'white';
			return true;
		}
	}
	// Initial Plus (+). Set to default "+ 1 day" and continue.
	else if (event.keyCode == 107 || event.keyCode == 187)
		timeMod = oneDay;
	// Initial Minus (-). Set to default "- 1 day" and continue.
	else if (event.keyCode == 109 || event.keyCode == 189) 
		timeMod = -oneDay;
	// Initial (D)ay. Set to default "+ 1 day" + 1ms to differenciate from Initial (+). Awaits #, w or +.
	else if (event.keyCode == 68) 
		timeMod = oneDay + 1;			
	// Initial (W)eek. Set to default "+ 1 week". Awaits #, w or +.
	else if (event.keyCode == 87) 
		timeMod = oneDay * 7;
	// Initial (M)onth. Set to default "+ 1 month". Awaits #, m or +.
	else if (event.keyCode == 77) 
		timeMod = oneDay * 31;
	// Initial (Y)eek. Set to default "+ 1 year". Awaits #, y or +.
	else if (event.keyCode == 89) 
		timeMod = oneDay * 365.25;
	// Anything else is accepted as typed
	else return true;

	o.style.background = 'lime';
	// Apply time modifier and reset
	if (apply) {
		tempDate.setTime(dateFromEuro(o.value).getTime() + timeMod);
		o.value = dateToEuro(tempDate); 
		timeMod = 0;
		o.style.background = 'white';
	}

	if (dateAbilities.arguments.length == 1) showDay(o);
	returnValue = false;
	event.cancelBubble = true;
	return false;
}


