Add support for Fischer increment
[jschessclock.git] / script.js
index 3e524f4..840b6c1 100644 (file)
--- a/script.js
+++ b/script.js
@@ -6,16 +6,29 @@ function Timer(id) {
   var time = defaultTime;
   var intervalID;
   this.isTicking = false;
+  var increment = 0;
+  var defaultIncrement = 0;
+
   var outputTime = function() {
     document.getElementById(id).innerHTML = timeToTimeStr(time);
     var flagid = "flag-" + id.split('-')[1];
     var flagelem = document.getElementById(flagid);
     flagelem.style.visibility = time <= 0 ? "visible" : "hidden";
+    var incid = "increment-" + id.split('-')[1];
+    var incelem = document.getElementById(incid);
+    incelem.innerHTML = "+" + (increment / 1000).toString();
+    incelem.style.visibility = increment > 0 ? "visible" : "hidden";
   };
+
+  var startTickingUnixTime = null;
+  var remainingTimeAtTickingStart = null;
+
   var thisTimer = this; // workaround to use this in setInterval
   this.tick = function() {
-    time -= (precision <= time ? precision : time);
+    var currentPassedTime = new Date() - startTickingUnixTime;
+    time = remainingTimeAtTickingStart - currentPassedTime;
     if(time <= 0) {
+      time = 0;
       // time's up
       clearInterval(intervalID);
       thisTimer.isTicking = false;
@@ -23,16 +36,25 @@ function Timer(id) {
     outputTime();
   };
   this.start = function() {
+    startTickingUnixTime = new Date();
+    remainingTimeAtTickingStart = time;
     intervalID = setInterval(this.tick, precision);
     this.isTicking = true;
   };
-  this.stop = function() {
+  this.stop = function(toggle = false) {
     clearInterval(intervalID);
     this.isTicking = false;
+    if (toggle && this.getTime() > 0) {
+      this.setTime(this.getTime() + increment, increment, true);
+    }
   };
-  this.setTime = function(t) {
+  this.setTime = function(t, inc = 0, toggle = false) {
     time = t;
-    defaultTime = t;
+    increment = inc;
+    if (!toggle) {
+      defaultTime = t;
+      defaultIncrement = inc;
+    }
     outputTime();
   };
   this.getTime = function() {
@@ -42,7 +64,7 @@ function Timer(id) {
     if(this.isTicking) {
       this.stop();
     }
-    this.setTime(defaultTime);
+    this.setTime(defaultTime, defaultIncrement);
   };
   this.getDefaultTime = function() {
     return defaultTime;
@@ -60,7 +82,7 @@ var currentTimers = new (function() {
     this.passive   = this.active;
     this.active    = tmp;
     var icon       = document.getElementById("play");
-    icon.innerHTML = (icon.innerHTML == "â\97\80" ? "â\96¶" : "â\97\80");
+    icon.innerHTML = (icon.innerHTML == "â\8f´" ? "â\8fµ" : "â\8f´");
   };
   this.pause = function() {
     this.active.stop();
@@ -119,7 +141,7 @@ document.onkeydown = function(e) {
 
 function toggle() {
   if(!currentTimers.isPaused) {
-    currentTimers.active.stop();
+    currentTimers.active.stop(true);
     currentTimers.passive.start();
   }
   currentTimers.swap();
@@ -130,7 +152,7 @@ function toggle() {
   var rbt = document.getElementById('right-button-top');
   var rbt_d = rbt.getAttribute('d').split(' ');
   var rbb = document.getElementById('right-button-body');
-  
+
   var y_diff = 50 * (leftIsLong ? 1 : -1);
   var classes = ['button-short', 'button-long'];
 
@@ -150,7 +172,7 @@ function toggle() {
   rbb.setAttribute('class', classes[(leftIsLong + 1) % 2]);
   lbt.setAttribute('d', lbt_d.join(' '));
   rbt.setAttribute('d', rbt_d.join(' '));
-  
+
   lbt.setAttribute('onclick', leftIsLong ? '' : 'toggle()');
   lbb.setAttribute('onclick', leftIsLong ? '' : 'toggle()');
   lbt.setAttribute('cursor', leftIsLong ? 'default' : 'pointer');
@@ -172,23 +194,38 @@ function pauseResume() {
 function setTime() {
   var leftstart, rightstart;
   var def = timeToTimeStr(currentTimers.leftTimer.getDefaultTime());
-  var regex = /[0-9][0-9]:[0-5][0-9]/;
-  
-  leftstart = prompt("Time for LEFT player in MM:SS", def);
+  var regex = /[0-9][0-9]:[0-5][0-9](\+[0-9]+)?/;
+
+  leftstart = prompt("Time for LEFT player in MM:SS or MM:SS+S", def);
   if(leftstart === null) return; // Cancel
   while(!leftstart.match(regex)) {
-    leftstart = prompt("Invalid value\nTime for LEFT player in MM:SS", def);
+    leftstart = prompt("Invalid value\nTime for LEFT player in MM:SS or MM:SS+S", def);
     if(leftstart === null) return; // Cancel
   }
   def = leftstart;
-  rightstart = prompt("Time for RIGHT player in MM:SS", def);
+  rightstart = prompt("Time for RIGHT player in MM:SS or MM:SS+S", def);
   if(rightstart === null) return; // Cancel
   while(!rightstart.match(regex)) {
-    rightstart = prompt("Invalid value\nTime for RIGHT player in MM:SS", def);
+    rightstart = prompt("Invalid value\nTime for RIGHT player in MM:SS or MM:SS+S", def);
     if(rightstart === null) return; // Cancel
   }
-  currentTimers.leftTimer.setTime(timeStrToTime(leftstart));
-  currentTimers.rightTimer.setTime(timeStrToTime(rightstart));
+
+  if(leftstart.indexOf('+') > 0) {
+    var baseTime = leftstart.split('+')[0];
+    var inc = leftstart.split('+')[1];
+    currentTimers.leftTimer.setTime(timeStrToTime(baseTime), parseInt(inc) * 1000);
+  }
+  else {
+    currentTimers.leftTimer.setTime(timeStrToTime(leftstart));
+  }
+  if(rightstart.indexOf('+') > 0) {
+    var baseTime = rightstart.split('+')[0];
+    var inc = rightstart.split('+')[1];
+    currentTimers.rightTimer.setTime(timeStrToTime(baseTime), parseInt(inc) * 1000);
+  }
+  else {
+    currentTimers.rightTimer.setTime(timeStrToTime(leftstart));
+  }
 }
 
 function reset() {
@@ -199,7 +236,7 @@ function reset() {
 
 function init() {
   insertcss();
-  setTimeout(fitscreen, 5); // hack to allow DOM to be redrawn with new css
+  setTimeout(fitscreen, 2000); // hack to allow DOM to be redrawn with new css
 }
 
 function fitscreen() {
@@ -208,19 +245,14 @@ function fitscreen() {
    */
   var heightRatio =  window.innerHeight / document.body.scrollHeight;
   var widthRatio = window.innerWidth / document.body.scrollWidth;
-  var scaleRatio = Math.min(heightRatio, widthRatio);
+  var scaleRatio = Math.min(heightRatio, widthRatio, 1);
   document.body.style.transform = 'scale(' + scaleRatio + ')';
 }
 
 function insertcss() {
   /* fix positions for browsers that don't support flex */
-  var cssfile = document.createElement("link");
-  cssfile.setAttribute("rel", "stylesheet");
-  cssfile.setAttribute("type", "text/css");
-  if('align-items' in document.body.style) {
-    cssfile.setAttribute("href", "style.css");
-  } else {
+  var cssfile = document.getElementById("style");
+  if(!('align-items' in document.body.style)) {
     cssfile.setAttribute("href", "noflex.css");
   }
-  document.head.appendChild(cssfile);
 }