/* Malaysian time clock. By idea.org */
var desiredAccuracy = 200;
var normalSyncPeriod = 1800000; 
var syncPeriod = 5000; 
var maxSyncPeriod = 30000;
var syncTries = 3; 
var syncTryPeriod = 500; 
var url = "getTime.php";
var clockPeriod = 1000; 
var confidenceProbability = "0.80"; 
var syncSessionConfidenceCoeff = "0.3";
var tryRepeatLimit = 3;
var tryExpireTimeout = 10000;
var maxNextSyncTime = 600000;
var minNextSyncTime = 10000;
var initialSyncSessionsCount = 1;
var useIEControl = true; 
var lastSyncsCount = 30;
var maxDevianceError = 10000;
var clockMaxDevianceCoeff = 10;
var precisionCoeff = 50;
var lastSignificantSessionsCount = 5;
var repeatTime = 100;
var waitString = "Standby...";
var imagesWaitString = "Please, wait while skin images loading...";
var errorLoadingDigitImagesString = "There was an error while loading images for the digit skin. Switching to no skin mode.";
var reloadTimeConfirmationString = "Seems that your system time has been changed. Do you wich to reload the clock?";
var noReloadTimeAlertString = "Internal clock will be reloaded within next synchronization cycle anyway.";
var reloadTimezoneConfirmationString = "Seems that your system timezone has been changed. Do you wich to reload the clock?";
var noReloadTimezoneAlertString = "Clock will be reINITED within next synchronization cycle.";
var errorBrokenConnectionString = "Connection to the time server seems to be broken. Repeating...";
var errorConnectionTimedOutString = "Try timed out.";
var accuracyString = "Accuracy is ";
var errorRepeatingSessionString = "Repeating session due to errors...";
var monthFull = new Array("January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December");
var monthShort = new Array("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec");
var weekDayFull = new Array("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday");
var weekDayShort = new Array("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun");
var suffix = new Array("st", "nd", "rd", "th");
var dateFormat = "%l, %F %j %Y";
var backSkinsCount = 4;
var digitSkinsDir = "digits";
if(!selectedBackSkin) var selectedBackSkin = 3;
var selectedDigitSkin = "fdb";
var loadDigitImagesTryTime = 10000;
var loadDigitImagesMaxTries = 3;
var studentValues98 = new Array(0, 31.706, 6.965, 4.541, 3.747, 3.265, 3.143, 2.998, 2.896, 2.821, 2.764, 2.718, 2.681, 2.650, 2.624, 2.602, 2.583, 2.567, 2.552, 2.539, 2.528, 2.518, 2.508, 2.500, 2.492, 2.485, 2.479, 2.473, 2.467, 2.462, 2.457);
var studentValues95 = new Array(0, 12.706, 4.303, 3.182, 2.776, 2.571, 2.447, 2.365, 2.306, 2.262, 2.228, 2.201, 2.179, 2.160, 2.145, 2.131, 2.120, 2.110, 2.101, 2.093, 2.086, 2.080, 2.074, 2.069, 2.064, 2.060, 2.056, 2.052, 2.048, 2.045, 2.042);
var studentValues90 = new Array(0, 6.314, 2.920, 2.353, 2.132, 2.015, 1.943, 1.895, 1.860, 1.833, 1.812, 1.796, 1.782, 1.771, 1.761, 1.753, 1.746, 1.740, 1.734, 1.729, 1.725, 1.721, 1.717, 1.714, 1.711, 1.708, 1.706, 1.703, 1.701, 1.699, 1.697);
var studentValues80 = new Array(0, 3.078, 1.886, 1.638, 1.533, 1.476, 1.440, 1.415, 1.397, 1.383, 1.372, 1.363, 1.356, 1.350, 1.345, 1.341, 1.337, 1.333, 1.330, 1.328, 1.325, 1.323, 1.321, 1.319, 1.318, 1.316, 1.315, 1.314, 1.313, 1.311, 1.310);
var studentValues50 = new Array(0, 1.000, 0.816, 0.765, 0.741, 0.727, 0.718, 0.711, 0.706, 0.703, 0.700, 0.697, 0.695, 0.689, 0.692, 0.691, 0.690, 0.689, 0.688, 0.688, 0.687, 0.686, 0.686, 0.685, 0.685, 0.684, 0.684, 0.684, 0.683, 0.683, 0.683);
var studentValues = new Array();
studentValues["0.98"] = studentValues98;
studentValues["0.95"] = studentValues95;
studentValues["0.90"] = studentValues90;
studentValues["0.80"] = studentValues80;
studentValues["0.50"] = studentValues50;
var normalValues = new Array();
normalValues["0.98"] = 2,326;
normalValues["0.95"] = 1,960;
normalValues["0.90"] = 1,645;
normalValues["0.80"] = 1,282;
normalValues["0.50"] = 0,675;
function TimeLoader(url, targetFunc, caller) {
this.url=null;
this.targetFunc=null;
this.startTime=null;
this.endTime=null;
this.error=null;
this.load=function() {
this.startTime=this.getNowTime();
if (typeof(this.caller.builtInIELoader) != "undefined" && typeof(this.caller.builtInIELoader.startDownload) != "undefined") {
this.loadIE();
} else if (this.getHTTPObject(true)) {
this.loadXML();
} else if (navigator.javaEnabled()) {
this.loadJava();
} else {
this.loadFrame();
}
};
this.loadFrame=function() {
try {
var iframe = document.createElement("IFRAME");
iframe.style.border="none";
iframe.style.width="0px";
iframe.style.height="0px";
iframe.style.visibility="hidden";
document.body.appendChild(iframe);
iframe.src = this.url;
iframe.onload = function() {
var source=iframe.document.body.innerHTML;
document.body.removeChild(iframe);
loader.callTarget(source);
};
} catch(e) {
this.error="Seems that your browser does not compatible with frames: " + e + "\n";
this.callTarget(false);
}
};
this.loadJava=function() {
try {
var source = "";
var url = new java.net.URL(window.location.href + "/" + this.url);
var stream = new java.io.DataInputStream(url.openStream());
var line = "";
while ((line = stream.readLine()) != null) {
source += line + "\n";
}
stream.close();
this.callTarget(source);
} catch(e) {
this.error="Your browser does not support Java: " + e + "\n";
this.callTarget(false);
}
};
this.loadXML=function() {
try {
var req = this.getHTTPObject();
if (!req) return false;
req.onreadystatechange = function() {
if (req.readyState == 4) {
if (req.status == 200) {
if (loader && loader != undefined) loader.callTarget(req.responseText);
} else {
if (loader) loader.error="HTTP protocol return an error code. May be, problems on the server: " + req.status + "\n";
if (loader) loader.callTarget(false);
}
}
};
req.open("GET", this.url, true);
req.send(null);
} catch(e) {
this.error="Your browser does not support XMLHttpRequest: " + e + "\n";
this.callTarget(false);
}
};
this.loadIE=function() {
try {
this.caller.builtInIELoader.startDownload(this.url, this.outputIE);
} catch(e) {
this.error="Seems that your browser does not support needed component: " + e + "\n";
this.callTarget(false);
}
};
this.outputIE=function(answer) {
if (loader) loader.callTarget(answer); 
};
this.callTarget=function(answer) {
this.endTime=this.getNowTime();
answer=this.validateTime(answer);
targetFunc(answer, this);
};
this.getNowTime=function() {
return (new Date()).getTime();
};
this.getHTTPObject=function(check) {
var xmlhttp;
// IE
/*@cc_on
@if (@_jscript_version >= 5)
try {
xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
} catch (E) {
xmlhttp = false;
}
}
@else
xmlhttp = false;
@end @*/
if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
try {
xmlhttp = new XMLHttpRequest();
} catch (e) {
if (!check) {
this.error="Your browser does not support XMLHttpRequest: " + e + "\n";
}
return false;
}
}
return xmlhttp;
};
this.validateTime=function(time) {
var time=Number(time);
if (!time || !(new Date(time))) {
if (this.error != null) {
this.error+="Server returned unexpected time stamp: " + time + "\n";
} else {
this.error="Server returned unexpected time stamp: " + time + "\n";
}
return false;
} else {
return time;
}
};
this.getError=function() {
return this.error;
};
this.getStartTime=function() {
return this.startTime;
};
this.getEndTime=function() {
return this.endTime;
};
if (url && url.length > 0) {
this.url=url + "?" + this.getNowTime() + '&r=' + randomString();
} else {
this.error="Invalid server time URL specified: " + url;
return false;
}
if (typeof(targetFunc) == "function") {
this.targetFunc=targetFunc;
} else {
this.error="Invalid target function specified: " + targetFunc;
return false;
}
this.caller=caller;
this.load();
}
/**
* General Functions
*/
function randomString() {
var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz';
var string_length = 16;
var randomstring = '';
for(var i=0; i<string_length; i++) {
var rnum = Math.floor(Math.random() * chars.length);
randomstring += chars.substring(rnum, rnum + 1);
}
return randomstring;
}
function formatTime(dateObj) {
var hours = dateObj.getUTCHours();
var minutes = dateObj.getUTCMinutes();
var seconds = dateObj.getUTCSeconds();
var mseconds = dateObj.getUTCMilliseconds();
var amOrPm = "AM";
if (hours > 11) amOrPm = "PM";
if (hours > 12) hours = hours - 12;
if (hours == 0) hours = 12;
if (minutes <= 9) minutes = "0" + minutes;
if (seconds <= 9) seconds = "0" + seconds;
if (mseconds <= 99) mseconds = "0" + mseconds;
if (mseconds <= 9) mseconds = "00" + mseconds;
return hours + ":" + minutes + ":" + seconds + "." + mseconds + " " + amOrPm;
}
function formatTimeDiff(time) {
var ret = Math.round(Math.floor(Math.abs(time))/1000*10)/10;
return (ret == 0 ? 0.1 : ret) + ' s';
}
function formatDateOnly(dateObj) {
var dateStr=dateFormat;
var tmp=dateObj.getUTCDate();
if ((tmp + "").length < 2) tmp="0" + tmp;
dateStr=dateStr.replace(/%d/, tmp);
tmp=dateObj.getUTCDay();
tmp=weekDayShort[tmp];
dateStr=dateStr.replace(/%D/, tmp);
tmp=dateObj.getUTCDate();
dateStr=dateStr.replace(/%j/, tmp);
tmp=dateObj.getUTCDay();
tmp=weekDayShort[tmp];
dateStr=dateStr.replace(/%l/, tmp);
tmp=dateObj.getUTCDate();
var suff=suffix[3];
if (tmp == 1 || tmp == 21 || tmp == 31) {
suff=suffix[0];
} else if (tmp == 2 || tmp == 22) {
suff=suffix[1];
} else if (tmp == 3 || tmp == 23) {
suff=suffix[2];
}
dateStr=dateStr.replace(/%S/, suff);
tmp=dateObj.getUTCMonth();
tmp=monthShort[tmp];
dateStr=dateStr.replace(/%F/, tmp);
tmp=dateObj.getUTCMonth();
tmp+=1;
if ((tmp + "").length < 2) tmp="0" + tmp;
dateStr=dateStr.replace(/%m/, tmp);
tmp=dateObj.getUTCMonth();
tmp=monthShort[tmp];
dateStr=dateStr.replace(/%M/, tmp);
tmp=dateObj.getUTCMonth();
dateStr=dateStr.replace(/%n/, (tmp+1));
dateStr=dateStr.replace(/%Y/, dateObj.getUTCFullYear());
dateStr=dateStr.replace(/%y/, ("" + dateObj.getUTCFullYear()).substr(-2));
return dateStr;
}
function checkDST() {
var dst=false;
var gmt = new Date;
var lsm = new Date;
var lso = new Date;
lsm.setMonth(2); 
lsm.setDate(31);
var day = lsm.getDay();
lsm.setDate(31-day); 
lso.setMonth(9); 
lso.setDate(31);
day = lso.getDay();
lso.setDate(31-day);
if (gmt >= lsm || gmt < lso) dst = true;
return dst;
}
function getNowTime() {
return (new Date()).getTime();
}
function performTtest(arr) {
var studentCoeff=0;
if (arr.length > 30) studentCoeff=normalValues[confidenceProbability];
else studentCoeff=studentValues[confidenceProbability][arr.length-1];
var summ=0;
for(var i=0; i<arr.length; i++) {
summ+=arr[i];
}
var avg=summ/arr.length;
var sqrtSumm=0;
for(var i=0; i<arr.length; i++) {
sqrtSumm+=Math.pow((arr[i] - avg), 2);
}
var avgMistake=(Math.sqrt(sqrtSumm/(arr.length-1)))/Math.sqrt(arr.length);
var minLimit=avg-studentCoeff*avgMistake;
var maxLimit=avg+studentCoeff*avgMistake;
var testArr=new Array();
for(var i=0; i<arr.length; i++) {
if (arr[i] < minLimit || arr[i] > maxLimit) {
continue;
}
testArr[testArr.length]=arr[i];
}
return testArr;
}
function initClock() {
clearInterval(clockInterval);
clearTimeout(syncTimeout);
clearTimeout(tryWaitTimeout);
isWorking = false;
serverDate=new Date();
localDate=new Date();
localDate.setTime(getNowTime());
syncTriesInter=0;
differences=new Array();
delays=new Array();
sessionsDiff=new Array();
lastSyncsCountInternal=0;
startTryTime=0;
startSessionTime=0;
tryRepeatLimitInternal=0;
initialSyncSessionsCountInternal=0;
sessionsTimes=new Array();
devianceCoeff=0;
devianceMistakes=new Array();
nextPredictedDiff=0;
loader=null;
prevLocalTime=getNowTime();
prevTimezoneOffset=(new Date()).getTimezoneOffset();
clockInterval = setInterval('clock()', clockPeriod);
syncTimeout = setTimeout('syncTime()', 0);
}
function clock() {
if(window.name == 'small_clock' && window.opener && window.opener.closed == false) return;
correction = correctionTimeZone + correctionDaylight;
var localDate = new Date();
checkClockMaxDeviance(localDate);
checkTimezoneOffset(localDate);
if(initialSyncSessionsCountInternal >= initialSyncSessionsCount) {
var serverTime = localDate.getTime() + getAverage(sessionsDiff.slice(0-syncTries)) + (localDate.getTime() - sessionsTimes[sessionsTimes.length-1][1])*devianceCoeff + correction;
serverDate.setTime(serverTime);
displayTime(serverDate);
displayAccuracy(clockAccuracy);
} else {
displayTime(0);
}
if(diffTimeBox) diffTimeBox.innerHTML = formatTimeDiff(calculateDiff());
}
function checkClockMaxDeviance(nowDate) {
var nowLocalTime=nowDate.getTime();
if (Math.abs((nowLocalTime-prevLocalTime)) > (clockPeriod*clockMaxDevianceCoeff)) {
if (1 || confirm(reloadTimeConfirmationString)) {
window.location.reload();
} else {
alert(noReloadTimeAlertString);
prevLocalTime=nowLocalTime;
return false;
}
} else {
prevLocalTime=nowLocalTime;
return false;
}
}
function checkTimezoneOffset(nowDate) {
var nowTimezoneOffset=nowDate.getTimezoneOffset();
if (nowTimezoneOffset != prevTimezoneOffset) {
if (1 || confirm(reloadTimezoneConfirmationString)) {
window.location.reload();
} else {
alert(noReloadTimezoneAlertString);
prevTimezoneOffset=nowTimezoneOffset;
return false;
}
} else {
prevTimezoneOffset=nowTimezoneOffset;
return false;
}
}
function syncTime() {
if(window.name == 'small_clock' && window.opener && window.opener.closed == false) return;
if(syncTries <= syncTriesInter) { 
if(!validateSessionConfidence()) { repeatSession(); return; }
if(onEndSession()) return;
if(initialSyncSessionsCountInternal < initialSyncSessionsCount) {
initialSyncSessionsCountInternal++;
startSession(repeatTime);
} else {
startSession(getNextSyncTime());
}
} else { 
if(syncTriesInter == 0) onStartSession(); 
updateTimeState(); 
}
}
timeHandler=function(time, tloader) {
clearTimeout(tryWaitTimeout);
if (!time && tloader.getError()) {
reportError(tloader.getError());
onTryError(tloader);
return false;
}
delay=tloader.getEndTime() - tloader.getStartTime();
diff=(time * 1000) - tloader.getEndTime();
onTry(time, diff, delay);
isWorking = false;
tryRepeatLimitInternal=0;
}
function updateTimeState() {
loader=new TimeLoader(url, timeHandler, this);
tryWaitTimeout=setTimeout("tryWait()", tryExpireTimeout);
if (!loader || loader.getError()) {
reportError(loader.getError());
onTryError();
return false;
}
isWorking = true;
}
function displayTime(box, time) {
box.innerHTML = time;
}
function calculateDiff() {
diff=0;
len=0;
for(var i=0; i<differences.length; i++) {
len+=differences[i].length;
for(var j=0; j<differences[i].length; j++) {
diff+=differences[i][j] - Math.round(delays[i][j]/2);
}
}
return Math.round(diff/len);
}
function validateSessionConfidence() {
var tmpArr=differences[lastSyncsCountInternal];
var tmpArr=performTtest(tmpArr);
if (tmpArr.length == differences[lastSyncsCountInternal].length) return true;
else {
if (tmpArr.length/differences[lastSyncsCountInternal].length < syncSessionConfidenceCoeff) {
return false;
}
differences[lastSyncsCountInternal]=tmpArr;
return true;
}
return true;
}
function onStartSession() {
if (differences.length == lastSyncsCount) {
differences.shift();
delays.shift();
}
differences.push(new Array());
delays.push(new Array());
startSessionTime=getNowTime();
}
function startSession(afterPeriod) {
syncTriesInter=0;
clearTimeout(syncTimeout);
clearTimeout(tryWaitTimeout);
syncTimeout=setTimeout("syncTime()", afterPeriod);
}
function onEndSession() {
calculateSessionTime();
calculateSessionDiff();
if (calculateDiffPredictionMistake()) return true;
calculateDevianceCoeff();
calculatePredictedDiff();
avgDiff=getAverage(differences[lastSyncsCountInternal]);
avgDelay=getAverage(delays[lastSyncsCountInternal]);
if (lastSyncsCountInternal < (lastSyncsCount-1)) lastSyncsCountInternal++;
}
function startTry(afterPeriod) {
clearTimeout(syncTimeout);
syncTimeout=setTimeout("syncTime()", afterPeriod);
}
function onTry(time, diff, delay) {
timestamp = time * 1000;
serverDate.setTime(timestamp);
differences[lastSyncsCountInternal].push(diff);
delays[lastSyncsCountInternal].push(delay);
syncTriesInter++;
startTry(syncTryPeriod);
}
function repeatSession() {
differences.pop();
delays.pop();
startSession(repeatTime);
reportError(errorRepeatingSessionString);
}
function tryWait() {
var nowTime=getNowTime();
if (loader && (nowTime - loader.getStartTime()) > tryExpireTimeout && isWorking) {
clearTimeout(tryWaitTimeout);
onTryError();
} else {
reportError(errorConnectionTimedOutString);
}
}
function onTryError(tloader) {
var loaderError="";
if (tloader) {
((tloader.getError()) ? ": " + tloader.getError() : "")
}
loader=null;
isWorking = false;
clearTimeout(tryWaitTimeout);
if (tryRepeatLimitInternal >= (tryRepeatLimit - 1)) {
reportError(errorBrokenConnectionString);
tryRepeatLimitInternal=0;
repeatSession();
} else {
reportError(errorConnectionTimedOutString + loaderError);
tryRepeatLimitInternal++;
syncTriesInter++;
if (syncTries > syncTriesInter) startTry(repeatTime);
}
}
function calculateDevianceCoeff() {
if (sessionsDiff.length > 1) {
devianceCoeff=(sessionsDiff[sessionsDiff.length-1]-sessionsDiff[0]) / ((sessionsTimes[sessionsTimes.length-1][1]+sessionsTimes[sessionsTimes.length-1][0])/2 - (sessionsTimes[0][1]+sessionsTimes[0][0])/2);
devianceCoeff-=getAverage(devianceMistakes.slice(devianceMistakes.length -lastSignificantSessionsCount));
}
}
function calculateSessionTime() {
if (sessionsTimes.length >= lastSyncsCount) sessionsTimes.shift();
sessionsTimes.push(new Array(startSessionTime, getNowTime()));
}
function calculateSessionDiff() {
sdiff=0;
var lastSessionDiffs=differences[differences.length-1];
var lastSessionDelays=delays[delays.length-1];
for(var j=0; j<lastSessionDiffs.length; j++) {
sdiff+=lastSessionDiffs[j] - lastSessionDelays[j]/2;
}
if (sessionsDiff.length >= (lastSyncsCount-1)) sessionsDiff.shift();
sessionsDiff.push(Math.round(sdiff/lastSessionDiffs.length));
if(diffBox) displayBoxText(diffBox, formatTimeDiff(sessionsDiff[sessionsDiff.length-1]));
if(delayBox) displayBoxText(delayBox, formatTimeDiff(getAverage(lastSessionDelays)));
}
function calculatePredictedDiff() {
if (sessionsDiff.length > 1) {
var sessionAvgTime=0;
for(var i=0; i<sessionsTimes.length; i++) {
sessionAvgTime+=sessionsTimes[i][1]-sessionsTimes[i][0];
}
sessionAvgTime=sessionAvgTime/sessionsTimes.length;
var tmp=0;
nextPredictedDiff=sessionsDiff[sessionsDiff.length-1] + (sessionAvgTime + getNextSyncTime()) * devianceCoeff;
}
}
function calculateDiffPredictionMistake() {
if (nextPredictedDiff) {
var devianceErrorMS=nextPredictedDiff - sessionsDiff[sessionsDiff.length-1];
if (checkMaxDeviance(devianceErrorMS)) return true;
clockAccuracy=formatTimeDiff(devianceErrorMS);
var lastDevianceMistake=
(nextPredictedDiff - sessionsDiff[sessionsDiff.length-1]) /
(
(sessionsTimes[sessionsTimes.length-1][1]+sessionsTimes[sessionsTimes.length-1][0])
/2 -
(sessionsTimes[sessionsTimes.length-2][1]+sessionsTimes[sessionsTimes.length-2][0])
/2
);
devianceMistakes.push(lastDevianceMistake);
}
}
function getNextSyncTime() {
if(parseInt(clockAccuracy) <= desiredAccuracy && clockAccuracy.indexOf(' s')<0) 
{
if(nextSyncBox)displayBoxText(nextSyncBox, formatTimeDiff(normalSyncPeriod));
return normalSyncPeriod;
}
if (initialSyncSessionsCountInternal <= initialSyncSessionsCount) {
initialSyncSessionsCountInternal++;
return repeatTime;
}
if (devianceMistakes.length > 0) {
var nextSyncTime=Math.abs(Math.round(precisionCoeff/getAverage(devianceMistakes.slice(devianceMistakes.length -lastSignificantSessionsCount))));
nextSyncTime=Math.min(Math.max(Math.abs(nextSyncTime), minNextSyncTime), maxNextSyncTime);
if(nextSyncBox) displayBoxText(nextSyncBox, formatTimeDiff(nextSyncTime));
return nextSyncTime;
} else {
return repeatTime;
}
}
function getAverage(arr) {
if (arr.length > 0) {
var tmp=0;
for(var i=0; i<arr.length; i++) {
tmp+=arr[i];
}
return tmp/arr.length;
} else return 0;
}
function reportError(error) {
if(errorBox) displayBoxText(errorBox, error);
}
function applyTimeZoneCorrection(hours) {
correctionTimeZone=hours*3600000;
}
function applyDaylightCorrection(flag) {
correctionDaylight=(flag) ? 3600000 : 0;
}
function checkMaxDeviance(devianceErrorMS) {
if (Math.abs(devianceErrorMS) > maxDevianceError) {
initClock();
return true;
} else {
return false;
}
}
function displayBoxText(box, text) {
box.innerHTML = text;
}
function selectTimeZone(hours) {
var selectBox=document.getElementById("timezoneSelectBox");
if(!selectBox) return 
for(var i=0; i<selectBox.length; i++) {
if (Number(selectBox.options[i].value) == hours)
selectBox.options[i].selected=true;
}
}
function selectDST(isDST) {
if (isDST && document.getElementById("dstCheckBox")) document.getElementById("dstCheckBox").checked=true;
}
function showSkin(skinType) {
skinType=Number(skinType);
switch(skinType) {
case SKIN_BACK:
showBackSkin();
break;
case SKIN_DIGIT:
showDigitSkin();
break;
case SKIN_NO:
showNoSkin();
break;
default:
showNoSkin();
}
}
function showBackSkin(skinNumber) {
if (!skinNumber) {
digitSkin.style.display="none";
noSkin.style.display="none";
for (var i=0; i<backSkinsCount; i++) {
if(backSkins[i]) backSkins[i].style.display="none";
}
backSkins[selectedBackSkin].style.display="block";
skinType=SKIN_BACK;
if(digitSkinSelectDiv) digitSkinSelectDiv.style.display="none";
if(backSkinSelectDiv) backSkinSelectDiv.style.display="block";
if(changeAPDiv) changeAPDiv.style.display="none";
if(changeAPMCheckBox) changeAPMCheckBox.checked=false;
return;
}
if (skinType == SKIN_BACK) {
for (var i=0; i<backSkinsCount; i++) {
if ((i+1) == skinNumber) {
if(backSkins[i]) backSkins[i].style.display="block";
} else {
if(backSkins[i]) backSkins[i].style.display="none";
}
}
}
selectedBackSkin=skinNumber - 1;
selectedBackSkinTime=document.getElementById("backSkinTime" + (selectedBackSkin+1));
selectedBackSkinDate=document.getElementById("backSkinDate" + (selectedBackSkin+1));
selectedBackSkinAcc=document.getElementById("backSkinAcc" + (selectedBackSkin+1));
}
function showDigitSkin(skinName) {
digitSkinTime.style.visibility="hidden";
if (!skinName) {
noSkin.style.display="none";
for (var i=0; i<backSkinsCount; i++) {
if(backSkins[i]) backSkins[i].style.display="none";
}
digitSkin.style.display="block";
skinType=SKIN_DIGIT;
if(backSkinSelectDiv) backSkinSelectDiv.style.display="none";
if(digitSkinSelectDiv) digitSkinSelectDiv.style.display="block";
if(changeAPDiv) changeAPDiv.style.display="block";
return;
}
selectedDigitSkin=skinName;
loadDigitSkinImages();
}
function showNoSkin() {
for (var i=0; i<backSkinsCount; i++) {
if(backSkins[i]) backSkins[i].style.display="none";
}
digitSkin.style.display="none";
noSkin.style.display="block";
if(backSkinSelectDiv) backSkinSelectDiv.style.display="none";
if(digitSkinSelectDiv) digitSkinSelectDiv.style.display="none";
if(changeAPDiv) changeAPDiv.style.display="block";
skinType=SKIN_NO;
}
function loadDigitSkinImages() {
nowLoadingDigitImages;
var tmpImage;
for (var i=0; i<10; i++) {
tmpImage=new Image();
tmpImage.src=digitSkinsDir + "/" + selectedDigitSkin + "/" + i + ".gif";
selectedDigitSkinImages[i]=tmpImage;
}
tmpImage=new Image();
tmpImage.src=digitSkinsDir + "/" + selectedDigitSkin + "/a.gif";
selectedDigitSkinImages["a"]=tmpImage;
tmpImage=new Image();
tmpImage.src=digitSkinsDir + "/" + selectedDigitSkin + "/c.gif";
selectedDigitSkinImages["c"]=tmpImage;
tmpImage=new Image();
tmpImage.src=digitSkinsDir + "/" + selectedDigitSkin + "/p.gif";
selectedDigitSkinImages["p"]=tmpImage;
digitImagesLoaded=false;
nowLoadingDigitImages=true;
setTimeout("checkDigitImagesLoaded()", 0);
}
function checkDigitImagesLoaded() {
if (loadDigitImagesMaxTriesInter < loadDigitImagesMaxTries) {
loadDigitImagesMaxTriesInter++;
} else {
digitImagesLoaded=false;
nowLoadingDigitImages=false;
return;
}
for (var i=0; i<10; i++) {
if (!selectedDigitSkinImages[i].width || selectedDigitSkinImages[i].width <= 0) {
setTimeout("checkDigitImagesLoaded()", loadDigitImagesTryTime);
return;
}
}
if (!selectedDigitSkinImages["a"].width || selectedDigitSkinImages["a"].width <= 0) {
setTimeout("checkDigitImagesLoaded()", loadDigitImagesTryTime);
return;
}
if (!selectedDigitSkinImages["c"].width || selectedDigitSkinImages["c"].width <= 0) {
setTimeout("checkDigitImagesLoaded()", loadDigitImagesTryTime);
return;
}
if (!selectedDigitSkinImages["p"].width || selectedDigitSkinImages["p"].width <= 0) {
setTimeout("checkDigitImagesLoaded()", loadDigitImagesTryTime);
return;
}
loadDigitImagesMaxTriesInter=0;
digitImagesLoaded=true;
nowLoadingDigitImages=false;
}
function displayTime(dateObj) {
switch (skinType) {
case SKIN_BACK:
displayTimeBack(dateObj);
break;
case SKIN_DIGIT:
displayTimeDigit(dateObj);
break;
case SKIN_NO:
displayTimeNo(dateObj);
break;
default:
displayTimeNo(dateObj);
}
}
function displayTimeBack(dateObj) {
if(!dateObj && selectedBackSkinTime) {
if(!document.getElementById('standby_z'))
selectedBackSkinTime.innerHTML = '<div id="standby_z" style="position:relative;top:20px"><img src="standbyIcon.gif"></div>';
return;
}
if(selectedBackSkinTime)
selectedBackSkinTime.innerHTML = formatTimeOnly(dateObj);
if(selectedBackSkinDate)
selectedBackSkinDate.innerHTML = formatDateOnly(dateObj);
if(window.small_clock && window.small_clock.closed == false) {
if(selectedBackSkinTime)
window.small_clock.document.getElementById('backSkinTime3').innerHTML = formatTimeOnly(dateObj);
if(selectedBackSkinDate)
window.small_clock.document.getElementById('backSkinDate3').innerHTML = formatDateOnly(dateObj);
}
}
function displayTimeDigit(dateObj) {
if (nowLoadingDigitImages) {
digitSkinDate.innerHTML=imagesWaitString;
return;
} else {
if (!digitImagesLoaded) {
reportError(errorLoadingDigitImagesString);
showNoSkin();
return;
}
}
if (!dateObj && digitSkinDate) {
digitSkinDate.innerHTML=waitString;
return;
}
var timeStr=formatTimeOnly(dateObj);
var tmp=timeStr.substr(0, 1);
if (imageDigit1.src != selectedDigitSkinImages[tmp].src) imageDigit1.src=selectedDigitSkinImages[tmp].src;
tmp=timeStr.substr(1, 1);
if (imageDigit2.src != selectedDigitSkinImages[tmp].src) imageDigit2.src=selectedDigitSkinImages[tmp].src;
if (imageColon1.src != selectedDigitSkinImages["c"].src) imageColon1.src=selectedDigitSkinImages["c"].src;
tmp=timeStr.substr(3, 1);
if (imageDigit3.src != selectedDigitSkinImages[tmp].src) imageDigit3.src=selectedDigitSkinImages[tmp].src;
tmp=timeStr.substr(4, 1);
if (imageDigit4.src != selectedDigitSkinImages[tmp].src) imageDigit4.src=selectedDigitSkinImages[tmp].src;
if (imageColon2.src != selectedDigitSkinImages["c"].src) imageColon2.src=selectedDigitSkinImages["c"].src;
tmp=timeStr.substr(6, 1);
if (imageDigit5.src != selectedDigitSkinImages[tmp].src) imageDigit5.src=selectedDigitSkinImages[tmp].src;
tmp=timeStr.substr(7, 1);
if (imageDigit6.src != selectedDigitSkinImages[tmp].src) imageDigit6.src=selectedDigitSkinImages[tmp].src;
if (changeAPMCheckBox && changeAPMCheckBox.checked) {
tmp=timeStr.substr(9, 1);
if (tmp == "P" || tmp == "p") {
imageAPM.style.display="inline";
if (imageAPM.src != selectedDigitSkinImages["p"].src) imageAPM.src=selectedDigitSkinImages["p"].src;
} else if (tmp == "A" || tmp == "a") {
imageAPM.style.display="inline";
if (imageAPM.src != selectedDigitSkinImages["a"].src) imageAPM.src=selectedDigitSkinImages["a"].src;
} else {
imageAPM.style.display="none";
}
} else {
imageAPM.style.display="none";
}
digitSkinTime.style.visibility="visible";
if (digitSkinDate) {
digitSkinDate.innerHTML=formatDateOnly(dateObj);
}
}
function displayTimeNo(dateObj) {
if (!dateObj && noSkinTime) {
noSkinTime.innerHTML=waitString;
return;
}
if (noSkinTime) {
noSkinTime.innerHTML=formatTimeOnly(dateObj);
}
if (noSkinDate) {
noSkinDate.innerHTML=formatDateOnly(dateObj);
}
}
function formatTimeOnly(dateObj) {
var hours = dateObj.getUTCHours();
var minutes = dateObj.getUTCMinutes();
var seconds = dateObj.getUTCSeconds();
var amOrPm = 'AM';
if(changeAPMCheckBox && changeAPMCheckBox.checked) {
if(hours > 11) amOrPm = 'PM';
if(hours > 12) hours = hours - 12;
}
if(hours == 0) hours = 12;
if(hours <= 9) hours = '0' + hours;
if(minutes <= 9) minutes = '0' + minutes;
if(seconds <= 9) seconds = '0' + seconds;
return hours + ':' + minutes + ':' + seconds + ((changeAPMCheckBox && changeAPMCheckBox.checked) ? ' ' + amOrPm : '');
}
function displayAccuracy(accString) {
switch (skinType) {
case SKIN_BACK:
var strAccy = accString ? accuracyString + accString : 'Measuring accuracy...';
if(selectedBackSkinAcc)
selectedBackSkinAcc.innerHTML = strAccy;
if(window.small_clock && window.small_clock.closed == false)
window.small_clock.document.getElementById('backSkinAcc3').innerHTML = strAccy;
break;
case SKIN_DIGIT:
if(digitSkinAcc) digitSkinAcc.innerHTML = accuracyString + accString;
break;
default:
if(noSkinAcc) noSkinAcc.innerHTML = accuracyString + accString;
}
}
var correction=0;               
var correctionTimeZone=0;       
var correctionDaylight=0;
var isDST=checkDST();
selectDST(isDST);
applyDaylightCorrection(isDST);
var hoursOffset = serverTimezoneOffset - ((isDST) ? 1 : 0);
selectTimeZone(hoursOffset);
applyTimeZoneCorrection(hoursOffset); 
var isWorking;        
var serverDate;       
var syncTriesInter;   
var differences;      
var delays;           
var sessionsDiff;
var lastSyncsCountInternal;
var startTryTime;     
var startSessionTime;
var clockAccuracy;
	
var diffTimeBox=document.getElementById("diffTimeContainer");
var diffBox=document.getElementById("diffContainer");
var delayBox=document.getElementById("delayContainer");
var nextSyncBox=document.getElementById("nextSyncContainer");
var errorBox=document.getElementById("errorContainer");
document.getElementById("clockFace").style.display="block";
var clockInterval;
var syncTimeout;
var tryWaitTimeout;
var tryRepeatLimitInternal;
var initialSyncSessionsCountInternal;
var sessionsTimes;
var devianceCoeff;
var devianceMistakes;
var nextPredictedDiff;
var loader;
var prevLocalTime;
var prevTimezoneOffset;
var backSkins=new Array();
for(var i=0; i<backSkinsCount; i++) {
backSkins[i]=document.getElementById("backSkin" + (i+1));
}
var backSkinSelectDiv=document.getElementById("backSkinSelectDiv");
var digitSkinSelectDiv=document.getElementById("digitSkinSelectDiv");
var digitSkin=document.getElementById("digitSkin");
var noSkin=document.getElementById("noSkin");
var selectedBackSkinTime=document.getElementById("backSkinTime" + (selectedBackSkin+1));
var selectedBackSkinDate=document.getElementById("backSkinDate" + (selectedBackSkin+1));
var selectedBackSkinAcc=document.getElementById("backSkinAcc" + (selectedBackSkin+1));
var noSkinTime=document.getElementById("noSkinTime");
var noSkinDate=document.getElementById("noSkinDate");
var noSkinAcc=document.getElementById("noSkinAcc");
var imageDigit1=document.getElementById("imageDigit1"); 
var imageDigit2=document.getElementById("imageDigit2");
var imageDigit3=document.getElementById("imageDigit3");
var imageDigit4=document.getElementById("imageDigit4");
var imageDigit5=document.getElementById("imageDigit5");
var imageDigit6=document.getElementById("imageDigit6");
var imageColon1=document.getElementById("imageColon1");
var imageColon2=document.getElementById("imageColon2");
var imageAPM=document.getElementById("imageApm");
var digitSkinTime=document.getElementById("digitSkinTime");
var digitSkinDate=document.getElementById("digitSkinDate");
var digitSkinAcc=document.getElementById("digitSkinAcc");
var changeAPDiv=document.getElementById("changeAPDiv");
var changeAPMCheckBox=document.getElementById("changeAPMCheckBox");
var SKIN_BACK=1;
var SKIN_DIGIT=2;
var SKIN_NO=3;
var skinType=0;
var nowLoadingDigitImages=false;
var digitImagesLoaded=false; 
var loadDigitImagesMaxTriesInter=0;
var selectedDigitSkinImages=new Array();
showBackSkin();
initClock();

