/*
 * (C) 2010 Базовая разработка - Т. Кудо, модификации - Ф.Аминов
*/

onload = function () {
  document.form.cn.focus();
  var zhwr = new ZHWR();
}

function zhwrShow() {
    var zhwr_table = document.getElementById("zhwr-table");
    if(zhwr_table.style.display == 'block') {
        zhwr_table.style.display = 'none';
    }
    else {
        zhwr_table.style.display = 'block';
    }
}

function getPosition(evt) {
  evt = (evt) ?  evt : ((event) ? event : null);
  var left = 0;
  var top = 0;

  if (evt.pageX) {
    // left = evt.pageX;
    // top  = evt.pageY;

    var parentLeft = document.getElementById("zhwr-table").offsetLeft;
    var parentTop = document.getElementById("zhwr-table").offsetTop;
    left = evt.pageX - parentLeft;
    top = evt.pageY - parentTop;

  } else {
    // left = evt.clientX + document.documentElement.scrollLeft;
    // top  = evt.clientY + document.documentElement.scrollTop;

    var parLeft = document.getElementById("zhwr-table").offsetLeft;
    var parTop = document.getElementById("zhwr-table").offsetTop;
    left = evt.clientX - parLeft;
    top = evt.clientY - parTop;

  }

  return {x : left, y : top};
}

function createXmlHttp () {
  xmlhttp = false;

  try {
    xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");
  } catch (e) {
    try {
      xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    } catch (E) {
      xmlhttp = false;
    }
  }
  if (!xmlhttp && typeof XMLHttpRequest != 'undefined') {
    xmlhttp = new XMLHttpRequest();
  }

  return xmlhttp;
}

function ZHWR() {
  var canvas = document.getElementById("zhwr-canvas");
  canvas.className = "zhwr-canvas";
  this.canvas = canvas;

  var self = this;
  canvas.onmouseup   = function(event) {self.mouseup(event);}
  canvas.onmousedown = function(event) {self.mousedown(event);}
  canvas.onmousemove = function(event) {self.mousemove(event);}

  var clear_button = document.getElementById("zhwr-clear-button");
  clear_button.onclick = function(event) {self.clearAll();}

  this.resultArea = document.getElementById("zhwr-result");
  this.resultArea.className = "zhwr-result";

  this.textInput =  document.getElementById("cn");
  //this.textInput.className = "search-field";

  var left = 0;
  var top = 0;
  for (var o = canvas; o ; o = o.offsetParent) {
    left += (o.offsetLeft - o.scrollLeft);
    top  += (o.offsetTop - o.scrollTop);
  }

  this.offsetLeft = left;
  this.offsetTop  = top;

  this.clearAll();

  //  this.read(input);
  //  this.getExample();
}

ZHWR.prototype.checkXmlHttp = function() {
  if (! this.xmlhttp) this.xmlhttp = createXmlHttp();
  if (! this.xmlhttp || this.xmlhttp.readyState == 1 ||
      this.xmlhttp.readyState == 2 || this.xmlhttp.readyState == 3){
    //return false;
    document.getElementById("zhwr-result").setAttribute("class", "zhwr-result loading");
    // прерываем запрос, если появляются новые черты иероглифа
    this.xmlhttp.abort();
  }
  return true;
}

ZHWR.prototype.readExample = function(s) {
  this.clearAll();
  var lines = s.split('\n');
  if (lines.length <= 3) return;

  this.exampleId = lines[0];
  this.resultChar = lines[1];
  var results = lines[2].match(/:(\d+)/);
  if (results == null) return;
  var stroke_num = results[1];

  for (var i = 0; i < stroke_num; ++i) {
    var t = lines[i+3].replace(/[\)\(]/g, "").split(' ');
    //alert(t);
    var stroke_num = t[0];
    if (2 * stroke_num + 1 != t.length) return;
    for (var j = 0; j < stroke_num; ++j) {
      var x = parseInt(t[2*j + 1]) + this.offsetLeft;
      var y = parseInt(t[2*j + 2]) + this.offsetTop;
      this.addPoint(x, y);
    }
    this.finishStroke();
  }
}

ZHWR.prototype.clearAll = function() {
  this.clear();
  // this.textInput.value = "";
}

ZHWR.prototype.clear = function() {
  this.xmlhttp = null;
  this.active = false;
  this.sequence = [];
  this.point_num = 0;
  this.stroke_num = 0;
  this.prev_x = -1;
  this.prev_y = -1;
  this.resultArea.innerHTML = "";
  // this.resultArea.style.display = "none";
  this.resultArea.setAttribute("class", "zhwr-result empty");
  this.resultNum = 0;
  this.resultChar = "";
  this.exampleId = 0;

  var o = this.canvas;
  while (o.firstChild) {
    o.removeChild(o.firstChild);
  }
}

ZHWR.prototype.showResult = function() {
  this.resultArea.style.display = "block";
  this.resultArea.innerHTML = "";
  this.resultArea.setAttribute("class", "zhwr-result");
  this.resultNum = 0;
}

ZHWR.prototype.addResult = function(c, p) {
  var div = document.createElement("div");
  var txt = document.createTextNode(c);
  var span = document.createElement("span");
  span.className = "zhwr-char";

  // Показать пиньинь для результатов системы распознавания
  span.onmouseover = function() {this.nextSibling.style.display='block';}
  span.onmouseout = function() {this.nextSibling.style.display='none';}

  span.appendChild(txt);

  var txt2 = document.createTextNode(p);
  var span2 = document.createElement("span");
  span2.appendChild(txt2);
  span2.className = "zhwr-prob";

  div.appendChild(span);
  div.appendChild(span2);

  var self = this;
  var idx = this.resultNum;
  div.onmouseover = function(event) {self.highlight(idx);}
  div.onclick = function(event) {
    self.sendTraindata(c);
    self.textInput.value += c;
    self.clear();
  }

  this.resultNum++;
  this.resultArea.appendChild(div);
}

ZHWR.prototype.highlight = function(idx) {
  var divs = this.resultArea.getElementsByTagName('div');
  for (i = 0; i < divs.length; i++) {
    if (i == idx) {
      divs[i].className = 'zhwr-container-current';
      //divs[i].onmouseover = divs[i].getChildNodes().item(2).style.display = 'block';
    } else {
      divs[i].className = 'zhwr-container';
    }
  }
}

ZHWR.prototype.createButton = function(label) {
  var b = document.createElement("input");
  b.className = "zhwr-button";
  b.value = label;
  b.type  = "button";
  return b;
}

ZHWR.prototype.getExample = function(c) {
  this.xmlhttp.open("POST", "/hw/", true);

  var self = this;
  this.xmlhttp.onreadystatechange = function() {
    //    var r = self.xmlhttp.responseText;
    //    if (r == "") {
    //      alert("...");
    //      return;
    //    }

    self.readExample(input);
    //    self.read(r);
    self.showResult();
    self.addResult(self.resultChar, "1.0");

    var ok = self.createButton("очистить");
    ok.onclick = function() {
      //      self.sendFeedback2(self.resultChar + " # correct");
      self.clearAll();
      self.getExample();
    }
    self.resultArea.appendChild(ok);

    var progress = self.createButton("фидбек");
    progress.onclick = function() {
      //      self.sendFeedback2(self.resultChar + " # in_stroke");
      self.clearAll();
      self.getExample();
    }
    self.resultArea.appendChild(progress);

    var pending = self.createButton("保留");
    pending.onclick = function() {
      //      self.sendFeedback2(self.resultChar + " # pending");
      self.clearAll();
      self.getExample();
    }
    self.resultArea.appendChild(pending);
  };
  this.xmlhttp.send("");
}

ZHWR.prototype.sendFeedback = function(c) {
//  this.xmlhttp.open("POST", "zhwrajaxlog.cgi", true);
//  r = this.makeMessage(c);
//  this.xmlhttp.onreadystatechange = function() {};
//  this.xmlhttp.send(r);
    return;
}

ZHWR.prototype.sendStroke = function() {
  var r = this.makeMessage('_');
//  console.log(r);

  if (! this.checkXmlHttp()) return;

  this.xmlhttp.open("POST", "/hw/", true);

//if (xmlhttp.status == 200) {
//    alert(xmlhttp.responseText);
//}
//alert(this.xmlhttp.status);

  var self = this;
  this.xmlhttp.onreadystatechange = function() {
    if (self.xmlhttp.readyState == 4 && self.xmlhttp.status == 200) {
      self.showResult();
      var cand = self.xmlhttp.responseText.split('\n');
      for (var i = 0; i < cand.length; i++) {
	if (cand[i] == "") break;
	var l = cand[i].split('\t');
	self.addResult(l[0], l[1]);
      }

      var undo = self.createButton("очистить");
      undo.onclick = function() {self.clear();}
      self.resultArea.appendChild(undo);
/*
      var learn = self.createButton("training");
      learn.onclick = function() {
	var n = prompt("some training data", "");
	if (n) {
	 self.sendFeedback(n);
	 self.textInput.value += n;
 	 self.clear();
	}
      }
      self.resultArea.appendChild(learn);
*/
    }
  }
  this.xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  this.xmlhttp.send(r);
}

ZHWR.prototype.mouseup = function(event) {
  this.trace(event);
  this.finishStroke();
  this.sendStroke();
}

ZHWR.prototype.mousemove = function(event) {
  this.trace(event);
}

ZHWR.prototype.mousedown = function(event) {
  this.active = true;
  this.trace(event);
}

ZHWR.prototype.finishStroke = function() {
  this.active = false;
  this.point_num = 0;
  this.stroke_num++;
  this.prev_x = -1;
  this.prev_y = -1;
}

ZHWR.prototype.addPoint = function(x, y) {
  var x2 = x - this.offsetLeft;
  var y2 = y - this.offsetTop;

  if (this.point_num == 0)
  this.sequence[this.stroke_num] = new Array;

  this.sequence[this.stroke_num][this.point_num] = {x:x2, y:y2};
  ++this.point_num;

  if (this.prev_x != -1) {
    this.drawLine(this.prev_x, this.prev_y, x, y);
  } else {
    this.drawDot(x, y);
  }

  this.prev_x = x;
  this.prev_y = y;
}

ZHWR.prototype.trace = function (event) {
  if (! this.active) return;
  var pos = getPosition(event);
  this.addPoint(pos.x, pos.y);
}

ZHWR.prototype.drawDot = function(x,y) {
  var dot = document.createElement("span");
  dot.style.left = x  + "px";
  dot.style.top =  y  + "px";
  dot.className = "zhwr-dot";
  this.canvas.appendChild(dot);
}

ZHWR.prototype.drawLine = function(x1,y1,x2,y2) {
  if (x1 == x2 && y1 == y2) return;

  var x_move = x2 - x1;
  var y_move = y2 - y1;
  var x_diff = x_move < 0 ? 1 : -1;
  var y_diff = y_move < 0 ? 1 : -1;

  if (Math.abs(x_move) >= Math.abs(y_move)){
    for (var i = x_move; i != 0; i += x_diff) {
      this.drawDot(x2 - i, y2 - Math.round(y_move * i / x_move));
    }
  } else {
    for (var i = y_move; i != 0; i += y_diff) {
      this.drawDot(x2 - Math.round(x_move * i / y_move), y2 - i);
    }
  }
}

ZHWR.prototype.makeMessage = function (c) {
  var q = "";
  for (var i = 0; i < this.sequence.length; ++i) {
    // r += "q=";
    for (var j = 0; j < this.sequence[i].length; ++j) {
      q += (this.sequence[i][j].x + "a" + this.sequence[i][j].y + "a" );
    }
    q += "a";
  }
 var r = "a=recognize&q=" + q;
 return r;
}

ZHWR.prototype.makeTraindataMessage = function (c)
{
  var q = "";
  for (var i = 0; i < this.sequence.length; ++i) {
    q += "(";
    for (var j = 0; j < this.sequence[i].length; ++j) {
      q += ("(" + this.sequence[i][j].x + " " + this.sequence[i][j].y + ")" );
    }
    q += ")";
  }
  var r = "a=traindata&q=(character value( " + c + ")(width 220)(height 220)(strokes " + q + "))";
  return r;
}

ZHWR.prototype.sendTraindata = function(c) {
  this.xmlhttp.open("POST", "/hw/", true);
  r = this.makeTraindataMessage(c);
  this.xmlhttp.onreadystatechange = function() {};

  this.xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  this.xmlhttp.send(r);

  return;
}