/*
 * jQuery imclock plugin with serwer time synchronization
 * Go to http://imlog.pl/2010/01/23/imclock-server-synchronized.html
 * for more info and docummentation.
 *
 * Copyright (c) 2010 Ignacy Moryc  <imoryc@gmail.com>
 * Licensed under the MIT License:
 *   http://www.opensource.org/licenses/mit-license.php
 */
 
// mins only
var clockShowsSeconds = false;
var clockIncrementMillis = 60000;

//show seconds
//var clockShowsSeconds = true; 
//var clockIncrementMillis = 1000;

var localTime;
var clockOffset;
var clockExpirationLocal;
var clockTimerID = null;	

(function($) {


	$.fn.imclock = function(options) {
	   
     var settings = jQuery.extend({
                                    name: "defaultName",
                                    size: 5
                                  }, options);
     var version = '1.4.0';
     return $.fn.imclock.start($(this));
	};

	$.fn.imclock.start = function(element) {
	   
	var clockLocalStartTime = new Date();	 
	var clockServerStartTime  = $.fn.imclock.getServerTime(element);
	
	$.fn.imclock.clockInit(clockLocalStartTime, clockServerStartTime);
	
	$(window).unload(function() {
  $.fn.imclock.clockOnUnload();
});

	$.fn.imclock.clockOnLoad(clockLocalStartTime, clockServerStartTime, element);

   };



$.fn.imclock.clockInit = function(localDateObject, serverDateObject) {

    var origRemoteClock = parseInt($.fn.imclock.clockGetCookieData("remoteClock"));
    var origLocalClock = parseInt($.fn.imclock.clockGetCookieData("localClock"));
    var newRemoteClock = serverDateObject.getTime();
    // May be stale (WinIE); will check against cookie later
    // Can't use the millisec. ctor here because of client inconsistencies.
    var newLocalClock = localDateObject.getTime();
  //  var maxClockAge = 60 * 60 * 1000;   // get new time from server every 1hr
var maxClockAge = 10 * 60 * 1000;   // get new time from server every 10mins

    if (newRemoteClock != origRemoteClock) {
        // new clocks are up-to-date (newer than any cookies)
        document.cookie = "remoteClock=" + newRemoteClock;
        document.cookie = "localClock=" + newLocalClock;
        clockOffset = newRemoteClock - newLocalClock;
        clockExpirationLocal = newLocalClock + maxClockAge;
        localTime = newLocalClock;  // to keep clockUpdate() happy
    }
    else if (origLocalClock != origLocalClock) {
        // error; localClock cookie is invalid (parsed as NaN)
        clockOffset = null;
        clockExpirationLocal = null;
    }
    else {
        // fall back to clocks in cookies
        clockOffset = origRemoteClock - origLocalClock;
        clockExpirationLocal = origLocalClock + maxClockAge;
        localTime = origLocalClock;
        // so clockUpdate() will reload if newLocalClock
        // is earlier (clock was reset)
    }
    /* Reload page at server midnight to display the new date,
       by expiring the clock then */
    var nextDayLocal = (new Date(serverDateObject.getFullYear(),
            serverDateObject.getMonth(),
            serverDateObject.getDate() + 1)).getTime() - clockOffset;
    if (nextDayLocal < clockExpirationLocal) {
        clockExpirationLocal = nextDayLocal;
    }
}





$.fn.imclock.clockOnLoad = function(clockLocalStartTime, clockServerStartTime, element) {   
	$.fn.imclock.clockUpdate(clockLocalStartTime, clockServerStartTime, element);
   // clockUpdate(element);
}

$.fn.imclock.clockOnUnload = function() { 
    if (clockTimerID) {
        clearTimeout(clockTimerID);
        clockTimerID = null;
    }
}

$.fn.imclock.clockTimeString = function(inHours, inMinutes, inSeconds) {
    return inHours == null ? "-:--" : ((inHours == 0
                   ? "12" : (inHours <= 12 ? inHours : inHours - 12))
                + (inMinutes < 10 ? "<span class='blink'>:</span>0" : "<span class='blink'>:</span>") + inMinutes
                + (clockShowsSeconds
                   ? ((inSeconds < 10 ? ":0" : ":") + inSeconds) : "")
                + (inHours < 12 ? " AM" : " PM"));
}


$.fn.imclock.clockDisplayTime = function(inYear, inMonth, inDay, inHours, inMinutes, inSeconds, element) {
	var m_names = new Array("Jan", "Feb", "Ma", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
	element.html($.fn.imclock.clockTimeString(inHours, inMinutes, inSeconds)+' '+inDay+'-'+m_names[inMonth]+'-'+inYear);
	$('#mlwclock .blink').blink({delay:500}); 
}


$.fn.imclock.clockGetCookieData = function(label) {
    /* find the value of the specified cookie in the document's
    semicolon-delimited collection. For IE Win98 compatibility, search
    from the end of the string (to find most specific host/path) and
    don't require "=" between cookie name & empty cookie values. Returns
    null if cookie not found. One remaining problem: Under IE 5 [Win98],
    setting a cookie with no equals sign creates a cookie with no name,
    just data, which is indistinguishable from a cookie with that name
    but no data but can't be overwritten by any cookie with an equals
    sign. */
    var c = document.cookie;
    if (c) {
        var labelLen = label.length, cEnd = c.length;
        while (cEnd > 0) {
            var cStart = c.lastIndexOf(';',cEnd-1) + 1;
            /* bug fix to Danny Goodman's code: calculate cEnd, to
            prevent walking the string char-by-char & finding cookie
            labels that contained the desired label as suffixes */
            // skip leading spaces
            while (cStart < cEnd && c.charAt(cStart)==" ") cStart++;
            if (cStart + labelLen <= cEnd && c.substr(cStart,labelLen) == label) {
                if (cStart + labelLen == cEnd) {                
                    return ""; // empty cookie value, no "="
                }
                else if (c.charAt(cStart+labelLen) == "=") {
                    // has "=" after label
                    return unescape(c.substring(cStart + labelLen + 1,cEnd));
                }
            }
            cEnd = cStart - 1;  // skip semicolon
        }
    }
    return null;
}



/* Called regularly to update the clock display as well as onLoad (user
   may have clicked the Back button to arrive here, so the clock would need
   an immediate update) */ 
$.fn.imclock.clockUpdate = function(clockLocalStartTime, clockServerStartTime, element) {   

    var lastLocalTime = localTime;
    localTime = (new Date()).getTime();

    /* Sanity-check the diff. in local time between successive calls;
       reload if user has reset system clock */
    if (clockOffset == null) {
        $.fn.imclock.clockDisplayTime(null, null, null, null, null, null, element);
    }
    else if (localTime < lastLocalTime || clockExpirationLocal < localTime) {
        /* Clock expired, or time appeared to go backward (user reset
           the clock). Reset cookies to prevent infinite reload loop if
           server doesn't give a new time. */
        document.cookie = 'remoteClock=-';
        document.cookie = 'localClock=-';
      //  location.reload();      // will refresh time values in cookies
		// !!!!!!!!!!!!!!!!!!!! replace with init call???
		
		//alert(clockLocalStartTime);
	$.fn.imclock.start(element);

//$.fn.imclock.clockInit(clockLocalStartTime, clockServerStartTime);
//$.fn.imclock.clockOnLoad(clockLocalStartTime, clockServerStartTime, element);
		
		
    }
    else {
        // Compute what time would be on server 
        var serverTime = new Date(localTime + clockOffset);
        $.fn.imclock.clockDisplayTime(serverTime.getYear(), serverTime.getMonth(), serverTime.getDate(), serverTime.getHours(), serverTime.getMinutes(), serverTime.getSeconds(), element); 
        // Reschedule this func to run on next even clockIncrementMillis boundary
		clockTimerID = setTimeout(function(){$.fn.imclock.clockUpdate(clockLocalStartTime, clockServerStartTime, element)}, clockIncrementMillis - (serverTime.getTime() % clockIncrementMillis));	
    }
}




   // This is the function that gets the actual time from the server
   // time is expected to be returned as JSON data in field named "time" in millisecs since 1970....
   // For example the request could look like this:
   // {
   //  "time" : 2010-12-12T12:23
   // }
   $.fn.imclock.getServerTime = function(element) {
     var time = null;

	   $.ajax({
			async:false,
			url: 'http://www.mlwff.co.uk/time?dummy='+Math.floor(Math.random()*100000000),
			dataType: 'json',
			success: function(data) {
                   if (data){ 
                   time = new Date(data.time);            
                   }
                 }				 
		}); 
		

     if (time == null) {
       time = new Date();
     }
	 

     return time;
   };
   
   

 })(jQuery);
 

