/**************
Author: Antonio Cisternino
modified by diepresse.com
**************/

var showAvailableChoices = false;
var solverRunning = false;
  var sudokuclick = 0;

function showsol(solu) { // zeigt bei aufruf die l�sung an
	var pars = parseLocation();
	RestoreState(pars.solu);
}

var selected = null;
function readCell(i, j) {
  var c = document.getElementById("cell"+ (j * 9 + i + 1));
  return c.innerHTML;
}


function isSchemaCell(i, j) {
  var c = document.getElementById("cell"+ (j * 9 + i + 1));
  return c.className == "schema";
}

function isFilledCell(i, j) {
  var c = readCell(i, j);
  return c.charAt(0) != "[" && c.charAt(0) != "&";
}

function drawCellBorder(i, j) {
  var c = document.getElementById("cell"+ (j * 9 + i + 1)).parentNode;
  c.style.background = "#ffffff";
  c.style.borderTop = (j % 3 == 0) ? "black 2px solid" : "black 1px solid";
  c.style.borderLeft = (i % 3 == 0) ? "black 2px solid" : "black 1px solid";
  c.style.borderRight = (i % 3 == 2) ? "black 2px solid" : "black 1px solid";
  c.style.borderBottom = (j % 3 == 2) ? "black 2px solid" : "black 1px solid";
  // c.style.borderWidth = "1px";
}

function setCell(cl, i, j, v) {
  var c = document.getElementById("cell"+ (j * 9 + i + 1));
  if (cl != null)
    c.className = cl;
  c.innerHTML = v;
}

function setCell2(cl, i, j, v) {
  var c = document.getElementById("cell"+ (j * 9 + i + 1));
  if (cl != null)
    c.className = cl;
  c.innerHTML = v;
}

function activate(o) {
  if (selected != null) {
	selected.style.background = '#ffffff';
  }
  if (o.innerHTML.indexOf("schema") != -1)
    selected = null;
  else {
    o.style.background = '#B1C0CB';
    selected = o;
  }
}

function drawBorders() {
  var i, j;
  for (i = 0; i < 9; i++)
    for (j = 0; j < 9; j++)
      drawCellBorder(i, j);
}

function fillSchema(s) {
  var i;
  for (i = 0; i < s.length; i++)
    if (s.charAt(i) != '0')
      setCell("schema", i % 9, Math.floor(i / 9), s.charAt(i));
}

function selectedID() {
  return parseInt(selected == null ? '0' : selected.firstChild.id.substr(4,6)) - 1;
}

function setMask(m, i, v) {
  if (v)
    m = m | (1 << i);
  else
    m = m & ~(1 << i);
  return m;
}

function readMask(m, i) {
  return (m & (1 << i)) != 0;
}

function availableInRow(i, j) {
  var k, m = 0, s;

  for (k = 0; k < 9; k++) {
    s = readCell(k, j);
    if (s.charAt(0) != '&' && s.charAt(0) != '{') {
      m = setMask(m, parseInt(s.charAt(0)), true);
    }
  }
  return m;
}

function availableInCol(i, j) {
  var k, m = 0, s;

  for (k = 0; k < 9; k++) {
    s = readCell(i, k);
    if (s.charAt(0) != '&' && s.charAt(0) != '{') {
      m = setMask(m, parseInt(s.charAt(0)), true);
    }
  }
  return m;
}

function availableInSqr(i, j) {
  var k, h, m = 0, s;

  var sx = Math.floor(i / 3) * 3;
  var sy = Math.floor(j / 3) * 3;

  for (k = 0; k < 3; k++)
    for (h = 0; h < 3; h++) {  
      s = readCell(k + sx, h + sy);
      if (s.charAt(0) != '&' && s.charAt(0) != '{') {
        m = setMask(m, parseInt(s.charAt(0)), true);
      }
    }
  return m;
}

function availableOptions(i, j) {
  if (isSchemaCell(i, j) || isFilledCell(i, j)) return "";

  var m = availableInRow(i, j), k;
  m = m | availableInCol(i, j);
  m = m | availableInSqr(i, j);

  var s = "";
  for (k = 1; k < 10; k++)
    if (!readMask(m, k))
      s += k;
  return s;
}

function markAvailable() {
  if (!showAvailableChoices) return;
  
  var i, j, c;
  for (i = 0; i < 9; i++)
    for (j = 0; j < 9; j++) {
      ch = readCell(i, j).charAt(0);
      if (ch == "[" || ch == "&")
        setCell("poss", i, j, "[" + availableOptions(i, j) + "]");
    }
}



function LeftCell(c) {
  var cn = parseInt(c.firstChild.id) - 1;
  if (cn % 9 == 0)
    return c;
  return document.getElementById("cell"+(cn)).parentNode;
}

function RightCell(c) {
  var cn = parseInt(c.firstChild.id) - 1;
  if (cn % 9 == 8)
    return c;
  return document.getElementById("cell"+(cn + 2)).parentNode;
}

function UpCell(c) {
  var cn = parseInt(c.firstChild.id) - 1;
  if (Math.floor(cn / 9) == 0)
    return c;
  return document.getElementById("cell"+(cn - 8)).parentNode;
}

function DownCell(c) {
  var cn = parseInt(c.firstChild.id) - 1;
  if (Math.floor(cn / 9) == 8)
    return c;
  return document.getElementById("cell"+(cn + 10)).parentNode;
}

function ResetCell(i, j) {
  var sp = document.getElementById("cell"+(j * 9) + i + 1);
  var c = sp.parentNode;
  if (selected == c)
    c.style.background = "#ffffff";
  else
    c.style.background = "#ffffff";
  sp.style.color = isSchemaCell(i, j) ? "#1D5492" : "";
}

function SignalCell(i, j) {
  var sp = document.getElementById("cell"+(j * 9) + i + 1);
  var c = sp.parentNode;
  c.style.background = "#ff0000";
  sp.style.color = "#ffffff";
  setTimeout("ResetCell(cell" + i + ", " + j + ")", 500);
}

function TestCell(i, j, v) {
  var h, k, ret = true, cv;
 /*  for (h = 0; h < 9; h++)
    if (h != i && (readCell(h, j) == v || availableOptions(h, j) == v)) {
      SignalCell(h, j);
      ret = false;
    }

  for (h = 0; h < 9; h++)
    if (h != j && (readCell(i, h) == v || availableOptions(i, h) == v)) {
      SignalCell(i, h);
      ret = false;
    } 
   
  var sx = Math.floor(i / 3) * 3;
  var sy = Math.floor(j / 3) * 3;
  
  for (h = 0; h < 3; h++)
    for (k = 0; k < 3; k++)
      if (sy+h != j && sx+k != i && (readCell(sx+k, sy+h) == v || availableOptions(sx+k, sy+h) == v)) {
        SignalCell(sx+k, sy+h);
        ret = false;
      }*/

  return ret;
}

function init() {
document.getElementById("watch").value = "00:00";
  document.onkeyup = function (e) {
    var kc = e ? e.keyCode : event.keyCode;
    if (selected != null) {
	  if (SpecialKeys[kc] == "Del") {
	    selected.firstChild.innerHTML = "&nbsp;";
	    markAvailable();
	  } else if (SpecialKeys[kc] == "Esc") {
  	    selected.style.background = '';
  	    selected = null;
	  } else if ((kc > 48 && kc < 58) || (kc > 96 && kc < 106)) {
	    if (TestCell(selectedID() % 9, Math.floor(selectedID() / 9), USKeyboard[kc][0])) {
	      setCell2("input", selectedID() % 9, Math.floor(selectedID() / 9), USKeyboard[kc][0]);
	      markAvailable();
	    }
	  } 
	}
  }
  drawBorders();
  var pars = parseLocation();
  fillSchema(pars.s);
  if (pars["ss"])
    RestoreState(pars.ss);
  else
    markAvailable();
}

function CurrentState() {
  var i, j, ch, ret = "";
  for (j = 0; j < 9; j++)
    for (i = 0; i < 9; i++) {
      ch = readCell(i, j).charAt(0);
      if (isSchemaCell(i, j) || ch == "&" || ch == "[")
        ret += "0";
      else
        ret += ch;
    }
  return ret;
}

function Stack() {
  this.length = 0;
  this.push = function(o) {
    this[this.length++] = o;
  }
  this.pop = function() {
    if (this.length == 0) throw "Stack is empty!";
    return this[--this.length];
  }
}

var SavedStates = new Stack();
var savedornot = 0;

function SaveState() {
  savedornot = 1;
  SavedStates.push(CurrentState());
}

function RestoreLastState() {
  if (savedornot <= 0) {
     alert("Kein Spielstand gespeichert!");
  } else {
  RestoreState(SavedStates.pop());
  }
}

function RestoreState(s) {
  var i;
 
  for (i = 0; i < s.length; i++)
    if (s.charAt(i) != "0") {
      setCell("input", i % 9, Math.floor(i / 9), s.charAt(i));
    } else if (!isSchemaCell(i % 9, Math.floor(i / 9))) {
      setCell("input", i % 9, Math.floor(i / 9), "&nbsp;");
    }
	
  markAvailable();
}

function MakeBookmarkable() {
  if (location.search) {
    var l = "" + location;
    var s = l.substring(0, l.indexOf("?") + 1);
    var pars = parseLocation(), v;
    pars.ss = CurrentState();
    for (v in pars) {
      if (s.charAt(s.length - 1) != "?") s += "&";
      s += v + "=" + pars[v];
    }
    location = s;
  }
  alert("" + location);
}

function clearAvailable() {
  var i, j;
  for (i = 0; i < 9; i++)
    for (j = 0; j < 9; j++)
      if (!isFilledCell(i, j)) setCell("input", i, j, "&nbsp;");
}

function showAvailable() {
  showAvailableChoices = !showAvailableChoices;
  if (showAvailableChoices)
    markAvailable();
  else
    clearAvailable();
}

function SetVal(i, j, v) {
  activate(document.getElementById("cell" + (j * 9 + i + 1)).parentNode);
  document.onkeyup({keyCode: 48 + v });
  setTimeout("if (solverRunning) Solve()", 500);
  return true;
}

function SolveSingleton() {
  var i, j;
  for (i = 0; i < 9; i++)
    for (j = 0; j < 9; j++)
      if (readCell(i, j).length == 3) {
        SetVal(i, j, parseInt(readCell(i, j).charAt(1)));
        return true;
      }
}

function SolveRow(j) {
  var nums = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0), i, k, s;
  for (i = 0; i < 9; i++) {
    s = readCell(i, j);
    if (!isFilledCell(i, j))
      for (k = 1; k < s.length - 1; k++)
        nums[parseInt(s.charAt(k))]++;
  }
  for (k = 1; k < 10; k++)
    if (nums[k] == 1)
      for (i = 0; i < 9; i++)
        if (!isFilledCell(i, j) && readCell(i, j).indexOf(""+k) != -1) {
          SetVal(i, j, k);
          return true;
        }
  return false;
}

function SolveCol(i) {
  var nums = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0), j, k, s;
  for (j = 0; j < 9; j++) {
    s = readCell(i, j);
    if (!isFilledCell(i, j))
      for (k = 1; k < s.length - 1; k++)
        nums[parseInt(s.charAt(k))]++;
  }
  for (k = 1; k < 10; k++)
    if (nums[k] == 1)
      for (j = 0; j < 9; j++)
        if (!isFilledCell(i, j) && readCell(i, j).indexOf(""+k) != -1) {
          SetVal(i, j, k);
          return true;
        }
  return false;
}

function SolveSqr(q) {
  var nums = new Array(0, 0, 0, 0, 0, 0, 0, 0, 0, 0), j, i, k, s;
  
  var sx = (q % 3) * 3;
  var sy = Math.floor(q / 3) * 3;

  for (i = sx; i < sx + 3; i++)
    for (j = sy; j < sy + 3; j++) {
      s = readCell(i, j);
      if (!isFilledCell(i, j))
        for (k = 1; k < s.length - 1; k++)
          nums[parseInt(s.charAt(k))]++;
    }
  for (k = 1; k < 10; k++)
    if (nums[k] == 1)
      for (i = sx; i < sx + 3; i++)
        for (j = sy; j < sy + 3; j++)
          if (!isFilledCell(i, j) && readCell(i, j).indexOf(""+k) != -1) {
            SetVal(i, j, k);
            return true;
          }
  return false;
}

function Solve() {
  var k;
  solverRunning = true;
  if (SolveSingleton()) return;
  for (k = 0; k < 9; k++) {
    if (SolveRow(k)) return;
    if (SolveCol(k)) return;
    if (SolveSqr(k)) return;
  }
  StopSolver();
}

function SolvePuzzle() {
  solverRunning = true;
  Solve();
}

function StopSolver() {
  solverRunning = false;
}

var SpecialKeys = {
  27: 'Esc',
  112: 'F1',
  113: 'F2',
  114: 'F3',
  115: 'F4',
  116: 'F5',
  117: 'F6',
  118: 'F7',
  119: 'F8',
  120: 'F9',
  121: 'F10',
  122: 'F11',
  123: 'F12',
  46:  'Del',
  35:  'End',
  34:  'Pgdn',
  33:  'Pgup',
  36:  'Home',
  45:  'Insert',
  19:  'Pause',
  144: 'NumLock',
  93:  'Menu',
  91:  'Win',
  13:  'Enter',
  37:  'Left',
  38:  'Up',
  39:  'Right',
  40:  'Down',
  17:  'Ctrl',
  18:  'Alt',
  20:  'CapsLock',
  8:   'BckSpc',
  16:  'Shift'
};

var USKeyboard = {
  192: { 0: '`', 1: '~' },
  49:  { 0: '1', 1: '!' },
  50:  { 0: '2', 1: '@' },
  51:  { 0: '3', 1: '#' },
  52:  { 0: '4', 1: '$' },
  53:  { 0: '5', 1: '%' },
  54:  { 0: '6', 1: '^' },
  55:  { 0: '7', 1: '&' },
  56:  { 0: '8', 1: '*' },
  57:  { 0: '9', 1: '(' },
  48:  { 0: '0', 1: ')' },
  189: { 0: '-', 1: '_' },
  187: { 0: '=', 1: '+' },
  81:  { 0: 'q', 1: 'Q' },
  87:  { 0: 'w', 1: 'W' },
  69:  { 0: 'e', 1: 'E' },
  82:  { 0: 'r', 1: 'R' },
  84:  { 0: 't', 1: 'T' },
  89:  { 0: 'y', 1: 'Y' },
  85:  { 0: 'u', 1: 'U' },
  73:  { 0: 'i', 1: 'I' },
  79:  { 0: 'o', 1: 'O' },
  80:  { 0: 'p', 1: 'P' },
  219: { 0: '[', 1: '{' },
  221: { 0: ']', 1: '}' },
  220: { 0: '\\', 1: '|' },
  65:  { 0: 'a', 1: 'A' },
  83:  { 0: 's', 1: 'S' },
  68:  { 0: 'd', 1: 'D' },
  70:  { 0: 'f', 1: 'F' },
  71:  { 0: 'g', 1: 'G' },
  72:  { 0: 'h', 1: 'H' },
  74:  { 0: 'j', 1: 'J' },
  75:  { 0: 'k', 1: 'K' },
  76:  { 0: 'l', 1: 'L' },
  186: { 0: ';', 1: ':' },
  222: { 0: '\'', 1: '"' },
  90:  { 0: 'z', 1: 'Z' },
  88:  { 0: 'x', 1: 'X' },
  67:  { 0: 'c', 1: 'C' },
  86:  { 0: 'v', 1: 'V' },
  66:  { 0: 'b', 1: 'B' },
  78:  { 0: 'n', 1: 'N' },
  77:  { 0: 'm', 1: 'M' },
  188: { 0: ',', 1: '<' },
  190: { 0: '.', 1: '>' },
  191: { 0: '/', 1: '?' },
  32:  { 0: ' ', 1: ' ' },
  96:  { 0: '0', 1: ' ' },
  97:  { 0: '1', 1: ' ' },
  98:  { 0: '2', 1: ' ' },
  99:  { 0: '3', 1: ' ' },
  100:  { 0: '4', 1: ' ' },
  101:  { 0: '5', 1: ' ' },
  102:  { 0: '6', 1: ' ' },
  103:  { 0: '7', 1: ' ' },
  104:  { 0: '8', 1: ' ' },
  105:  { 0: '9', 1: ' ' }
}

  
function count() {

  var NewPix = document.createElement("img");
  NewPix.setAttribute("SRC","http://diepress.oewabox.at/cgi-bin/ivw/CP/UnterhaltungGames/Games/Strategie/spiele/raetsel/sudoku?r=&d="+(new Date()).getTime()+"", "false");
  NewPix.setAttribute("width","1", "false");
  NewPix.setAttribute("height","1", "false");
  document.getElementById("zaehlen").appendChild(NewPix);
  sudokuclick = sudokuclick+1;
  if(sudokuclick==1) {
	  StartTimer();
  }
}

function toggleHelp() {

		var x = document.getElementById("helpcontent");
		var y = document.getElementById("help");

		if (x.style.display != "block") {
		x.style.display = "block";
		y.innerHTML = "Hilfetext zuklappen"; }
		else  {
		x.style.display = "none";
		y.innerHTML = "Funktionen erkl�ren"; }
}

/************ Stoppuhr *****************/

var dStartTime;       // Startzeit
var bRunning = false; // wird true, wenn Stoppuhr gestartet wird

// Start/StopTimer - startet bzw. haelt die Stoppuhr an
function StartTimer() {
  bRunning = true;          // merken, dass Stoppuhr laeuft
  dStartTime = new Date();  // Startzeit merken
  ShowTime();               // Startzeit anzeigen (0:00:00)
}

function StopTimer() {
  bRunning = false;         // Stoppuhr als angehalten merken
}

// ShowTime() zeigt die aktuelle Zeit der Stoppuhr an und veranlasst,
// dass diese Routine automatisch nach Ablauf von 1 Sekunde wieder
// aufgerufen wird - au�er die Stoppuhr wurde zwischenzeitlich 
// angehalten

function ShowTime() {
  if( !bRunning ) // Stoppuhr angehalten?
  return;
  var dDeltaTime = new Date();  // Variable dDeltaTime als Datumsvariable deklarieren
  dDeltaTime.setTime( new Date() - dStartTime ); // Differenz: Aktuelle Zeit und Startzeit
  var sMin = dDeltaTime.getMinutes(); // Minutenanteil der Differenz
  var sSec = dDeltaTime.getSeconds(); // Sekundenanteil der Differenz

  // Die Stunden werden als ganze Zahl der Differenz dividiert durch Sekunden
  // pro Stunde ausgerechnet. Dabei kann es natuerlich auch zu Werten groesser
  // als 24 fuehren, das ist so beabsichtigt.
  var sHours = Math.floor( dDeltaTime / 3600000 );

  // Bei der Umwandlung in eine ansprechende Darstellung der Stoppuhrzeit
  // sollen immer zwei Ziffern fuer die Sekunden und Minuten angezeigt
  // werden, sind es weniger als 10 Minuten bzw. Sekunden, wird eine Null
  // vor die Ausgabe eingefuegt.
  sMin = ( sMin < 10 ) ? "0" + sMin : sMin;
  sSec = ( sSec < 10 ) ? "0" + sSec : sSec;

  // Die Anzeige der Uhrzeit wird direkt als Wert des Texteingabefeldes sTime
  // eingetragen
  document.getElementById("watch").value = sMin + ":" + sSec;

  // Aufruf der Systemroutine setTimeout: nach 1000 Millisekunden (= 1 Sekunde)
  // soll wieder die Funktion ShowTime() aufgerufen werden.
  setTimeout('ShowTime()', 1000);
  }
