var startClock = (function(){
    // Thanks to http://www.quirksmode.org/js/cookies.html for the following two functions
    function createCookie(name,value,days) {
    	if (days) {
    		var date = new Date();
    		date.setTime(date.getTime()+(days*24*60*60*1000));
    		var expires = "; expires="+date.toGMTString();
    	}
    	else var expires = "";
    	document.cookie = name+"="+value+expires+"; path=/";
    }

    function readCookie(name) {
    	var nameEQ = name + "=";
    	var ca = document.cookie.split(';');
    	for(var i=0;i < ca.length;i++) {
    		var c = ca[i];
    		while (c.charAt(0)==' ') c = c.substring(1,c.length);
    		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    	}
    	return null;
    }

    function zeropad(n, digits) {
         n = n.toString();
         while (digits > n.length) {
             n = '0' + n;
         }
         return n;
    }

    var timeDifference = null;
    
    function runClock(element) {
        var time = guessedServerTime();
        element.innerHTML = zeropad(time.getHours(), 2) + ':' + zeropad(time.getMinutes(), 2) + ':' + zeropad(time.getSeconds(), 2);
        function runClockAgain() {
            runClock(element);
        }
        setTimeout(runClockAgain, 1000);
    }

    function getServerTime(callback) {
        var req = window.XMLHttpRequest ?
              new XMLHttpRequest() : new ActiveXObject("MSXML2.XMLHTTP.3.0");
        req.open('GET', '/timejs.php?rand=' + Math.random(), true);
        req.onreadystatechange = function() {
            if (req.readyState == 4 && req.status == 200 && req.responseText) {
                callback(eval(req.responseText));
            }
        };
        req.send(null);
    }
    
    function guessedServerTime() {
        var result = new Date();
        result.setTime(result.getTime() - timeDifference);
        return result;
    }
    
    return function startClock(element) {
        var cookieTimeDifference = readCookie('ec2_timedifference');
        if (cookieTimeDifference !== null && Math.random() >= (1/50)) {
            timeDifference = parseInt(cookieTimeDifference);
            runClock(element);
        } else {
            getServerTime(function(serverTime) {
                timeDifference = new Date() - serverTime;
                createCookie('ec2_timedifference', timeDifference.toString(), 1/24);
                runClock(element); 
            });
        }
    };
})();
