var timers = {
	winningTimes: {
		step: winningTimeStep,
		onload: 1
	}
};

var isIE = (window.navigator.userAgent.indexOf("MSIE") > 0);
var isIEMac = isIE && (window.navigator.userAgent.indexOf("Mac_") > 0);
var supportedBrowser = 	!isIEMac && document.getElementById && document.createElement;
var hasLoaded = 0;

function didLoad() {
	if (origOnload) origOnload();
	clientPageLoadTime = new Date().getTime();
	if (supportedBrowser) {
		
		for (var timerName in timers) {
			if (timers[timerName].onload) {
				startTimer(timerName);
			}
		}  
	}  
	hasLoaded = 1;
}

function minPositive() {
	var min = 0;
	for (var i = 0; i < arguments.length; i++) {
		if (arguments[i] > 0 &&
			(min > arguments[i] || min == 0)) {
			min = arguments[i];
		}
	}
	return min;
}

function getDescendantWithName(ancestor, name) {
	var descendant;
	for (var i = ancestor.childNodes.length - 1; i >= 0; i--) {
		var child = ancestor.childNodes[i];
		if (child.getAttribute && (child.getAttribute("name") == name)) {
			descendant = child;
		} else if (child.hasChildNodes) {
			descendant = getDescendantWithName(child, name);
		}
		if (descendant) {
			break;
		}
	}

	return descendant;
}

function replaceSubText(node, newText) {
	var textNode = node.childNodes[0];
	var oldText = textNode.data;
	textNode.replaceData(0, textNode.data.length, newText);
	return oldText;
}

function replaceSubHTML(node, newHTML) {
	node.innerHTML = newHTML;
}

function isFrenzy() {
	return (structure.isFrenzy &&
		structure.winners.length >= 2 &&
		structure.winners[2].age < (30 * 60));
}

function startTimer(timerName) {
	if (!supportedBrowser)
	{
		return;
	}
	var struct = timers[timerName];
	if (struct.timeout) {
		clearTimeout(struct.timeout);
		struct.timeout = null;
	}
	doStep(timerName);
}

function doStep(timerName) {
	var struct = timers[timerName];	
	var sleep = struct.step();
	if (sleep) {
		var string = 'doStep("' + timerName + '")';
		struct.timeout = setTimeout(string, sleep);
	}
}


function winningTimeStep() {
	var sleep = updateWinningTimes();
	return sleep;
}

function updateWinningTimes() {
	
	var currentTime = new Date().getTime();
	var sinceLoadMillis = currentTime - clientPageLoadTime;
	var secondsSinceLoad = Math.floor(sinceLoadMillis / 1000);
	var timeout = 0;
	var now = new Date();

	var scrollingDiv = document.getElementById("winnerScrollingRegion");

	var height = 0;
	
	for (var i = 0; i < structure.winners.length; i++) {
		var winnerDivID = 'winner' + (i + 1);
		var winnerDiv = document.getElementById(winnerDivID);

		if (!winnerDiv) {
			break; // structure has more winners than the html
		}

		var winner = structure.winners[i];
		
		var age = winner.age + secondsSinceLoad;
		timeout = minPositive(timeout, getWinningStepTimeout(age));

		if (scrollingDiv) {
			var visTop = scrollingDiv.scrollTop;
			var visBottom = visTop + scrollingDiv.offsetHeight;

			if (height > visBottom) {
				break;
			}

			height += winnerDiv.offsetHeight;

			if (height < visTop) {
				continue;
			}
		}

		var timeString = getTimeString(now, age);
		var timeSpan = getDescendantWithName(winnerDiv, "time");
		var textNode = timeSpan.childNodes[0];

		if (textNode.data != timeString) {
			replaceSubText(timeSpan, timeString);
		}

		var timeLabelString = getTimeLabelString(now, age);
		var timeLabelSpan = getDescendantWithName(winnerDiv, "timeLabel");
		textNode = timeLabelSpan.childNodes[0];
		if (textNode.data != timeLabelString) {
			replaceSubText(timeLabelSpan, timeLabelString);
		}
	}

	return timeout;
}

function getWinningStepTimeout(secondsAgo) {
	if (secondsAgo < 60 * 60) {
		return 200;
	} else if (secondsAgo < 24 * 60 * 60) {
		return 1000 * 60 * 5;
	} else {
		return 0;
	}
}

function getTimeString(nowObject, secondsAgo) {
	var string;

	if (secondsAgo < 60) {
		string = Math.max(1, secondsAgo);

	} else if (secondsAgo < 60 * 60) {
		var minutes = Math.floor(secondsAgo / 60);
		var seconds = Math.floor(secondsAgo % 60);
		if (minutes <= 0 && seconds <= 0) {
			minutes = 0;
			seconds = 1;
		}
		string = minutes + ':' + (seconds < 10 ? ('0' + seconds) : seconds);

	} else if (secondsAgo < 24 * 60 * 60) {
		var hours = Math.floor(secondsAgo / (60 * 60));
		string = hours;

	} else {
		var days = Math.floor(secondsAgo / (24 * 60 * 60));
		string = days;
        }

	return string;
}

function getTimeLabelString(nowObject, secondsAgo) {
	var string;

	if (secondsAgo <= 1) {
		string = 'second ago';
	} else if (secondsAgo < 60) {
		string = 'seconds ago';

	} else if (secondsAgo >= 60 && secondsAgo < 120) {
		string = 'minute ago';

	} else if (secondsAgo < 60 * 60) {
		string = 'minutes ago';

	} else if (secondsAgo < 24 * 60 * 60) {
		var hours = Math.floor(secondsAgo / (60 * 60));
		string = (hours == 1) ? "hour ago" : "hours ago";

	} else {
		var days = Math.floor(secondsAgo / (24 * 60 * 60));
		string = (days == 1) ? "day ago" : "days ago";
	}

	return string;
}

var clientPageLoadTime;
var origOnload = window.onload;
window.onload = didLoad;
