// (c)2008 Daniel M. Gattermann

var arrivalTime = new Date();
var initRan = false;
var updateInterval = 0;
var display24Hrs = true;
var displayLeftHrs = true;
var breakMode = true;
var workingTimeString = '';
var breakTimeString = '';


var DEFAULT_MAIL_TEXT_1	= 'It\'s ' + '@@n' + ' at the moment.\n'
						+ 'I came to work at ' + '@@a' + ' '
						+ 'and will work for ' + '@@w' + ' hours. '
						+ 'My break(s) will be ' + '@@b' + ' in total.\n'
						+ 'I plan to leave work at ' + '@@q' + '\n'
						+ '\n'
						+ 'Just now I\'m at work for ' + '@@e' + ' hours '
						+ 'and there are ' + '@@l' + ' hours left.'
						;

var DEFAULT_MAIL_TEXT_2	= 'Now                   ' + '@@n' + '\n'
						+ '\n'
						+ 'Arrival time          ' + '@@a' + '\n'
						+ 'Planned working hours ' + '@@w' + '\n'
						+ 'Planned quitting time ' + '@@q' + '\n'
						+ '\n'
						+ 'Actual time elapsed   ' + '@@e' + '\n'
						+ 'Break time            ' + '@@b' + '\n'
						+ 'Actual time left      ' + '@@l'
						;

var ARRIVAL_COOKIE = 'arrivalTimeCookie';
var WORKTIME_COOKIE = 'workingTimeCookie';
var BREAKTIME_COOKIE = 'breakTimeCookie';
var TEMPLATE_COOKIE = 'templateCookie';
var TIMEDISPLAY_COOKIE = 'timeDisplayTimeCookie';
var TIMEDISPLAYLEFT_COOKIE = 'timeDisplayLeftTimeCookie';
var BREAKMODE_COOKIE = 'breakModeCookie';

var AM = '<small>a.m.</small>';
var PM = '<small>p.m.</small>';

var currentTitle = '';


// window.onload = setTimeout(function() { window.scrollTo(0, 1); }, 100);

function init() {
	document.getElementById('edit').style.display = 'none';

	if (window.navigator.standalone) {
		// is fullscreen webapp
		initForFullscreenWebApp();
	}

	// time display mode
	var cookieDisplayMode = getCookie(this.TIMEDISPLAY_COOKIE);
	if (cookieDisplayMode) {
		this.display24Hrs = cookieDisplayMode == 'true' ? true : false;
	}

	// left time display mode
	var cookieDisplayLeftTimeMode = getCookie(this.TIMEDISPLAYLEFT_COOKIE);
	if (cookieDisplayLeftTimeMode) {
		this.displayLeftHrs = cookieDisplayLeftTimeMode == 'true' ? true : false;
	}
	
	// break mode
	var cookieBreakMode = getCookie(this.BREAKMODE_COOKIE);
	if (cookieBreakMode) {
		this.breakMode = cookieBreakMode == 'true' ? true : false;
	}
	updateBreakGUIElements(0);
	
	// arrival time
	var cookieArrivalTime = getCookie(this.ARRIVAL_COOKIE) * 1;
	if (cookieArrivalTime) {
		this.arrivalTime = new Date(cookieArrivalTime);
		document.getElementById('arrivalTimeValue').innerHTML = getTimeStringFromDate(this.arrivalTime, false, this.display24Hrs);
		correctArrivalTime24HoursPlus();
	} else {
		document.getElementById('arrivalTimeValue').innerHTML = 'stap to et';
	}

	// working time
	var cookieWorkingTime = getCookie(this.WORKTIME_COOKIE);
	if (cookieWorkingTime) {
		this.workingTimeString = cookieWorkingTime;
		var time = parseTimeString(this.workingTimeString);
		var date = new Date();
		date.setHours(time[0]);
		date.setMinutes(time[1]);
		date.setSeconds(0);
		document.getElementById('workingTimeValue').innerHTML = getTimeStringFromDate(date, false, true);
	} else {
		document.getElementById('workingTimeValue').innerHTML = 'tap to set';
	}

	// break time
	var cookieBreakTime = getCookie(this.BREAKTIME_COOKIE);
	var date = new Date();
	if (cookieBreakTime) {
		this.breakTimeString = cookieBreakTime;
		var time = parseTimeString(this.breakTimeString);
		date.setHours(time[0]);
		date.setMinutes(time[1]);
		date.setSeconds(0);
	} else {
		this.breakTimeString = '00:00';
		date.setHours(0);
		date.setMinutes(0);
		date.setSeconds(0);
	}
	document.getElementById('breakTimeValue').innerHTML = getTimeStringFromDate(date, false, true);

	updateAll();
	this.initRan = true;
	setInterval('updateAll()', 1000);

	// preload images
	var imageToggleOff = new Image(94, 27);
	imageToggleOff.src = "toggleOff.png"
}

function initForFullscreenWebApp() {
	// instantly remove fullscreen link if already in fullscreen mode
	document.getElementById('fullscreenLine').style.display = 'none';
}


function getElementsByClass(searchClass, node, tag) {
	var classElements = new Array();
	if (node == null) { node = document; }
	if (tag == null) { tag = '*'; }
	
	var els = node.getElementsByTagName(tag);
	var elsLen = els.length;
	var pattern = new RegExp("(^|\\\\s)"+searchClass+"(\\\\s|$)");
	for (i = 0, j = 0; i < elsLen; i++) {
		if ( pattern.test(els[i].className) ) {
			classElements[j] = els[i];
			j++;
		}
	}
	return classElements;
}


/* cookie tools */

function setCookie(name, value) {
	var expires = new Date( (new Date()).getTime() + (365 * 24 * 60 * 60 * 1000) );
	document.cookie = name + '=' + escape(value) + '; expires=' + expires.toGMTString() + '; path=/';
}

function getCookie(name) {
	var results = document.cookie.match ( '(^|;) ?' + name + '=([^;]*)(;|$)' );
	return results ? unescape(results[2]) : null;
}

function eraseCookie(name) {
	document.cookie = name + '=; expires=-1; path=/';
}


/* time string tools */

function parseTimeString(string) {
	var res = ( new RegExp(/(\d\d|\d)([^\d]+(\d{1,2})|(\d\d))/) ).exec(string);
	if (res) {
		var hours = res[1] * 1;
		var mins = res[3] ? res[3] * 1 : (res[4] ? res[4] * 1 : 0);
		if (hours >= 0 && hours <= 24 && mins >= 0 && mins <= 60) {
			return new Array(hours, mins, ((hours * 60 * 60 * 1000) + (mins * 60 * 1000)) );
		}
	}
	
	// if no aray returned by now try to get only numbers as minutes
	var res2 = ( new RegExp(/(\d+)/) ).exec(string);
	if (res2) {
		var mins2 = res2[1] * 1;
		return new Array( ((mins2 - (mins2 % 60)) / 60), mins2 % 60, (mins2 * 60 * 1000) );
	}

}

function getTimeStringFromDate(date, returnSeconds, display24Hrs) {
	var AMPM = '';
	var sec = date.getSeconds();
	var min = date.getMinutes();
	var hr = date.getHours();

	if (!display24Hrs) {
		if (hr == 12) {
			AMPM = ' ' + this.PM;
		} else if (hr > 12) {
			hr -= 12;
			AMPM = ' ' + this.PM;
		} else {
			AMPM = ' ' + this.AM;
			hr = hr == 0 ? 12 : hr;
		}
	}
	return (hr < 10 ? '0' + hr : hr) + ':' + (min < 10 ? '0' + min : min) +  (returnSeconds ? ':' + (sec < 10 ? '0' + sec : sec) : '') + AMPM;
}


function getTimeStringFromMs(ms, returnSeconds, display24Hrs) {
	var AMPM = '';
	var sec = Math.floor(ms/1000);
	var min = Math.floor(sec/60);
	var hr = Math.floor(min/60);
	sec = sec % 60;
	min = min % 60;
	hr = hr % 60;

	if (!display24Hrs) {
		if (hr == 12) {
			AMPM = ' ' + this.PM;
		} else if (hr > 12) {
			hr -= 12;
			AMPM = ' ' + this.PM;
		} else {
			AMPM = ' ' + this.AM;
			hr = hr == 0 ? 12 : hr;
		}
	}
	return (hr < 10 ? '0' + hr : hr) + ':' + (min < 10 ? '0' + min : min) +  (returnSeconds ? ':' + (sec < 10 ? '0' + sec : sec) : '') + AMPM;
}


function setArrivalTimeString(string) {
	var time = parseTimeString(string);
	if (time) {
		var date = new Date();
		date.setHours(time[0]);
		date.setMinutes(time[1]);
		date.setSeconds(0);
		setArrivalTimeDate(date);
	}
}

function setArrivalTimeDate(date) {
		this.arrivalTime = date;
		setCookie(this.ARRIVAL_COOKIE, this.arrivalTime.getTime());
		updateAll();
}

function setWorkingTimeString(string) {
	var time = parseTimeString(string);
	if (time) {
		var timeString = (time[0] < 10 ? '0' + time[0] : time[0]) + ':' + (time[1] < 10 ? '0' + time[1] : time[1]);
		this.workingTimeString = timeString;
		setCookie(this.WORKTIME_COOKIE, timeString);
		updateAll();
	}
}

function setBreakTimeString(string) {
	var time = parseTimeString(string);
	if (time) {
		var timeString = (time[0] < 10 ? '0' + time[0] : time[0]) + ':' + (time[1] < 10 ? '0' + time[1] : time[1]);
		this.breakTimeString = timeString;
		setCookie(this.BREAKTIME_COOKIE, timeString);
		updateAll();
	}
}

/* update function */

function updateAll() {
	var now = new Date();
	correctArrivalTime24HoursPlus();
	updateCurrentTime(now);
	if (this.workingTimeString) {
		updateLeftTime(now);
		updateTimeMode();
		updateTimeLeftMode();
		updateQuittingTime();
		updateMailLink();
	}
}

function updateCurrentTime(now) {
	document.getElementById('currTimeValue').innerHTML = getTimeStringFromDate(now, true, this.display24Hrs);
}

function getLeftTimeMs(now) {
	var workTimeMils = parseTimeString(this.workingTimeString)[2];
	var breakTimeMils = this.breakMode ? parseTimeString(this.breakTimeString)[2] : 0;
	return ( (new Date(this.arrivalTime.getTime() + workTimeMils + breakTimeMils).getTime()) - now.getTime() );
}

function getPassedTimeMs(now) {
	return ( now.getTime() - this.arrivalTime.getTime() );
}

function updateLeftTime(now) {
	var guiElem = document.getElementById('leftWorkTimeValue');
	var icon = '&nbsp;';
	var negTime = false;

	var displayTime;

	if (this.displayLeftHrs) {
		var leftTime = getLeftTimeMs(now);
		if (leftTime < 0) {
			negTime = true;
			leftTime *= -1;
		} else {
			leftTime += 1000;
		}
		displayTime = leftTime;

	} else {
		var passedTime = getPassedTimeMs(now);
		if (passedTime < 0) {
			passedTime *= -1;
			negTime = true;
		}
		displayTime = passedTime;
	}

	if (negTime) {
		guiElem.style.color = '#8eb89d';
		icon = '<img src="drink.gif" alt="drink icon" />' + icon;
	} else {
		guiElem.style.color = '#b88e9d';
		icon = '<img src="cog.gif" alt="cog icon" />' + icon;
	}

	if (!this.displayLeftHrs) {
		guiElem.style.color = '#6d84a2';
	}
	
	guiElem.innerHTML = icon + (negTime ? '-' : '') + getTimeStringFromMs(displayTime, true, true);
}

function updateQuittingTime() {
	if (this.arrivalTime * 1 && this.workingTimeString) {
		var breakTimeMils = this.breakMode ? parseTimeString(this.breakTimeString)[2] : 0;
		var quit = new Date( this.arrivalTime.getTime() + parseTimeString(this.workingTimeString)[2] + breakTimeMils );
		document.getElementById('quittingTimeValue').innerHTML = getTimeStringFromDate(quit, false, this.display24Hrs);
	}
}

function correctArrivalTime24HoursPlus() {
	var now = new Date().getTime();
	var t = this.arrivalTime.getTime();

	if (now - t > (24 * 60 * 60 * 1000)) {
		this.arrivalTime = new Date( now - ((now - t) % (24 * 60 * 60 * 1000)) );
		setCookie(this.ARRIVAL_COOKIE, this.arrivalTime.getTime());
	}
	
	if (document.getElementById('arrivalTimeValue')) {
		document.getElementById('arrivalTimeValue').innerHTML = getTimeStringFromDate(this.arrivalTime, false, this.display24Hrs);
	}
}


function toggleTimeMode() {
	this.display24Hrs = !this.display24Hrs;
	setCookie(this.TIMEDISPLAY_COOKIE, this.display24Hrs);
	updateAll();
}

function updateTimeMode() {
	var mode = '';
	
	if (this.display24Hrs) {
		mode = '(&rarr; 12h)';
	} else {
		mode = '(&rarr; 24h)';
	}

	document.getElementById('timeDisplayModeButtonLegend').innerHTML = mode;
}

function toggleTimeLeftMode() {
	this.displayLeftHrs = !this.displayLeftHrs;
	setCookie(this.TIMEDISPLAYLEFT_COOKIE, this.displayLeftHrs);
	updateAll();
}

function updateTimeLeftMode() {
	var mode = '';
	var legend = '';
	var icon = '';
	
	if (this.displayLeftHrs) {
		mode = 'Left';
		legend = '(&rarr; elapsed)';
		icon = '<img src="hourglass.gif" alt="left time icon" />';
	} else {
		mode = 'Elapsed';
		legend = '(&rarr; left)';
		icon = '<img src="clock.gif" alt="left time icon" />';
	}

	document.getElementById('timeLeftIcon').innerHTML = icon;
	document.getElementById('timeDisplayLeftTitle').innerHTML = mode;
	document.getElementById('timeDisplayLeftLegend').innerHTML = legend;
}


function toggleBreakMode() {
	this.breakMode = !this.breakMode;
	setCookie(this.BREAKMODE_COOKIE, this.breakMode);
	updateBreakGUIElements(1);
	updateAll();
}

function updateBreakGUIElements(duration) {
	document.getElementById('breakToggle').className = this.breakMode ? 'toggleOn' : 'toggleOff';

	document.getElementById('breakTimeLine').style.webkitTransitionDuration = duration + 's';
	document.getElementById('breakTimeLine').style.opacity = this.breakMode ? '1' : '0';
	document.getElementById('breakTimeLine').style.height = this.breakMode ? '43px' : '0px';
}


/* UI tools */

function inputSetArrivalTimeToNow() {
	if (!this.initRan) return false;
	
	if (window.confirm('Set arrival time to now?')) {
		setArrivalTimeDate(new Date());
		document.getElementById('arrivalTimeValue').innerHTML = getTimeStringFromDate(this.arrivalTime, false, this.display24Hrs);
	}
}

function inputArrivalTime() {
	if (!this.initRan) return false;
	
	document.getElementById('arrivalTimeLine').className = 'timeLineHighlighted';
	document.getElementById('arrivalTimeContainer').innerHTML = (this.display24Hrs ? '' : '<span id="timeDisplayModeInfo">24h input</span> ')
		+ '<input id="arrivalTimeInput" name="zip" size="5" maxlength="5" type="text" value="' + getTimeStringFromDate(this.arrivalTime, false, true) + '" onblur="javascript:saveArrivalTime();" autocorrect = "off" />';
	document.getElementById('arrivalTimeInput').focus();
}

function saveArrivalTime() {
	document.getElementById('arrivalTimeLine').className = 'timeLine';
	setArrivalTimeString(document.getElementById('arrivalTimeInput').value);
	document.getElementById('arrivalTimeContainer').innerHTML = '<span id="arrivalTimeValue" class="timeValue">' + getTimeStringFromDate(this.arrivalTime, false, this.display24Hrs) + '</span>';

	if (window.navigator.standalone) {
		window.scrollTo(0, 1);
	}
}

function inputWorkingTime() {
	if (!this.initRan) return false;
	
	document.getElementById('workingTimeLine').className = 'timeLineHighlighted';
	document.getElementById('workingTimeContainer').innerHTML = '<input id="workingTimeInput" name="zip" size="5" maxlength="5" type="text" value="' + this.workingTimeString + '" onblur="javascript:saveWorkingTime();" autocorrect = "off" />';
	document.getElementById('workingTimeInput').focus();
}

function saveWorkingTime() {
	document.getElementById('workingTimeLine').className = 'timeLine';
	setWorkingTimeString(document.getElementById('workingTimeInput').value);
	var string = this.workingTimeString ? this.workingTimeString : 'tap to set';
	document.getElementById('workingTimeContainer').innerHTML = '<span id="workingTimeValue" class="timeValue">' + string + '</span>';

	if (window.navigator.standalone) {
		window.scrollTo(0, 1);
	}
}


function inputBreakTime() {
	if (!this.initRan) return false;
	
	document.getElementById('breakTimeLine').className = 'timeLineHighlighted';
	document.getElementById('breakTimeContainer').innerHTML = '<input id="breakTimeInput" name="zip" size="5" maxlength="5" type="text" value="' + this.breakTimeString + '" onblur="javascript:saveBreakTime();" autocorrect = "off" />';
	document.getElementById('breakTimeInput').focus();
}

function saveBreakTime() {
	document.getElementById('breakTimeLine').className = 'timeLine';
	setBreakTimeString(document.getElementById('breakTimeInput').value);
	var string = this.breakTimeString ? this.breakTimeString : 'tap to set';
	document.getElementById('breakTimeContainer').innerHTML = '<span id="breakTimeValue" class="timeValue">' + string + '</span>';

	if (window.navigator.standalone) {
		window.scrollTo(0, 1);
	}
}


/* mailing */

function getMailText() {
	var mailText = this.DEFAULT_MAIL_TEXT_1;
	var cookieTemplate = getCookie(this.TEMPLATE_COOKIE);
	if (cookieTemplate) {
		mailText = cookieTemplate;
	}
	return mailText;
}

function setMailText(text) {
	setCookie(this.TEMPLATE_COOKIE, text);
}


function editTemplateShow() {
	document.getElementById('lines').style.display = 'none';
	document.getElementById('edit').style.display = 'block';
	document.getElementById('buttonSave').style.display = 'inline';
	document.getElementById('ads2').innerHTML = document.getElementById('ads').innerHTML;
	this.currentTitle = document.getElementById('titleText').innerHTML;
	document.getElementById('titleText').innerHTML = '<h1>Edit Mail Template</h1>';

	document.getElementById('textarea').value = getMailText();

	window.scrollTo(0, 1);
}

function editTemplateSave() {
	document.getElementById('edit').style.display = 'none';
	document.getElementById('buttonSave').style.display = 'none';
	document.getElementById('lines').style.display = 'block';
	document.getElementById('ads').innerHTML = document.getElementById('ads2').innerHTML;
	document.getElementById('titleText').innerHTML = this.currentTitle;

	setMailText(document.getElementById('textarea').value);

	window.scrollTo(0, 1);
}

function restoreTemplateText(tempText) {
	document.getElementById('textarea').value = tempText;
}


function textareaBlur() {
	window.scrollTo(0, 1);
}

function updateMailLink() {
	var mailText = getMailText();
	
	var arrive = document.getElementById('arrivalTimeValue');
	var work = document.getElementById('workingTimeValue');
	var quit = document.getElementById('quittingTimeValue');
	var now = document.getElementById('currTimeValue');
	var breaktime = document.getElementById('breakTimeValue');

	if (!arrive || !work || !quit || !breaktime) return true;

	arrive = arrive.innerHTML;
	work = work.innerHTML;
	quit = quit.innerHTML;
	now = now.innerHTML;
	breaktime = breaktime.innerHTML;
	var date = new Date();
	var elapsed = (getPassedTimeMs(date) < 0 ? '-' : '') + getTimeStringFromMs( (getPassedTimeMs(date) < 0 ? getPassedTimeMs(date) * -1 : getPassedTimeMs(date) ), false, true);
	var left = (getLeftTimeMs(date) < 0 ? '-' : '') + getTimeStringFromMs( (getLeftTimeMs(date) < 0 ? getLeftTimeMs(date) * -1 : getLeftTimeMs(date) ), false, true);
	
	// delete possible tags from string
	mailText = mailText.replace(/<.*?>/g, '');
	mailText = mailText.replace(/@@a/g, arrive);
	mailText = mailText.replace(/@@w/g, work);
	mailText = mailText.replace(/@@q/g, quit);
	mailText = mailText.replace(/@@n/g, now);
	mailText = mailText.replace(/@@e/g, elapsed);
	mailText = mailText.replace(/@@b/g, this.breakMode ? breaktime : "mode disabled");
	mailText = mailText.replace(/@@l/g, left);

	document.getElementById('mailLink').href = 'mailto:?subject=Attendance time&body=' + urlencode(mailText);
}


function urlencode(str) {
    // http://kevin.vanzonneveld.net
	// [snip]
    var histogram = {}, histogram_r = {}, code = 0, tmp_arr = [];
    var ret = str.toString();

    var replacer = function(search, replace, str) {
        var tmp_arr = [];
        tmp_arr = str.split(search);
        return tmp_arr.join(replace);
    };

    // The histogram is identical to the one in urldecode.
    histogram['!']   = '%21';
    histogram['%20'] = '+';

    // Begin with encodeURIComponent, which most resembles PHP's encoding functions
    ret = encodeURIComponent(ret);

    for (search in histogram) {
        replace = histogram[search];
        ret = replacer(search, replace, ret) // Custom replace. No regexing
    }

    // Uppercase for full PHP compatibility
    ret = ret.replace(/(\%([a-z0-9]{2}))/g, function(full, m1, m2) {
        return "%"+m2.toUpperCase();
    });

	ret = ret.replace(/\+/g, '%20'); // DG: added for Mobile Mail on iPhone/iPod touch to prevent + signs instead of blanks (%20)
	return ret;
}