var script_url = '/cgi-bin/lookup.pl';

var can_quit = true; // if user is allowed to close window

org.cote.js.xml.setCacheEnabled(false); // disable libXmlRequest cache feature

var logobj, cmdobj, qobj;

var queue_dom = org.cote.js.xml.newXmlDocument('queue');

var rqid = 0; // unique request id 
var outmode = '';

var running_threads = 0; // are any XmlHttp requests in progress?
var queue_processing = false; // is queue processing performed now?

var edit_mode = false; // are we inside some edit field?
var query_focused = false; // are we inside query edit field?

var last_command = ''; // remember last command entered

var isIE = (navigator.userAgent.toLowerCase().indexOf("msie") > -1);

//------------------------------------------------------------------------
function htmlResponse(id, title, body) {
//------------------------------------------------------------------------
  return '<div class="response">' +
      '<h1>' +
         title +
      '</h1>' +
      '<div id="rq' + id + '">' +
         body +
      '</div>' +
    '</div>';
}

//------------------------------------------------------------------------
function insertResponse(id, s, title) {
//------------------------------------------------------------------------
  var rqobj = document.getElementById("rq" + id);
  
  if (!rqobj) {
    logobj.insertAdjacentHTML('afterBegin', htmlResponse(id, title, ''));
    rqobj = document.getElementById("rq" + id);
  }
  
  if (rqobj) {
    org.cote.js.xml.removeChildren(rqobj); // clear the 'Wait...' message
    rqobj.insertAdjacentHTML('beforeEnd', s); // insert html
    cmdobj.scrollIntoView(false);
  } else {
    alert("Container div with id [" + id + '] not found.');
  }
}

//------------------------------------------------------------------------
function insertErrorResponse(id, s, title) {
//------------------------------------------------------------------------
  insertResponse(id, '<div class="error">' + xmlEncode(s) + '</div>', title);
}

//------------------------------------------------------------------------
function urlEncode(s) {
//------------------------------------------------------------------------
  return escape(s).replace(/\+/g, '%2B').replace(/\"/g,'%22').replace(/\'/g, '%27');
}

//------------------------------------------------------------------------
function xmlEncode(s) {
//------------------------------------------------------------------------
  return s.replace(/\&/g, '&amp;').replace(/\</g, '&lt;').replace(/\>/g, '&gt;').replace(/\"/g, '&quot;');
}

//------------------------------------------------------------------------
function trim(s) {
//------------------------------------------------------------------------
  return s.replace(/[ \t]{2,}/g, ' ').replace(/^\s*|\s*$/g, '');
}

//------------------------------------------------------------------------
function doLoad() {
//------------------------------------------------------------------------
  qobj = document.getElementById('q');
  cmdobj = document.getElementById('cmdline');
  logobj = document.getElementById('log');

  loadSettingFromCookie("fav");
  loadSettingFromCookie("all");
  
  focusCommandLine();
  //execCmd('hello', true);

  // if a query is passed via ?xxxx , take it and execute

  var a = window.location.href.split("?");
  if (a.length > 1) {
    execCmd(unescape(a[1]), true);
  }
}

//------------------------------------------------------------------------
function editFocus() {
//------------------------------------------------------------------------
  edit_mode = true;
}

//------------------------------------------------------------------------
function editBlur() {
//------------------------------------------------------------------------
  edit_mode = false;
}

//------------------------------------------------------------------------
function focusCommandLine(force) {
//------------------------------------------------------------------------
  if (cmdobj && qobj) {
    cmdobj.scrollIntoView(false);
    qobj.focus();
  }
}

//------------------------------------------------------------------------
function doFocus() {
//------------------------------------------------------------------------
  if (qobj) {
    var l = qobj.value.length;
    if (isIE) {
      var range = qobj.createTextRange(); 
      range.moveStart("character", l); 
      range.moveEnd("character", 0); 
      range.select();
    } else {
      qobj.setSelectionRange(l, l);
    }
  }
  query_focused = true;
}

//------------------------------------------------------------------------
function doBlur() {
//------------------------------------------------------------------------
  query_focused = false;
}

//------------------------------------------------------------------------
function doKeypress(e) {
//------------------------------------------------------------------------
  var k = e.keyCode ? e.keyCode : e.charCode ? e.charCode : e.which ? e.which : void 0;
  
  if ((k == 13) && (qobj.value != '')) { // submit the query
    submitCmd();
    return false;
  }
  
  if ((k == 32) && (qobj.value == '')) { // is spacebar pressed, and field is empty
    qobj.value = last_command;
    return false;
  }
  
  return true;
}

//------------------------------------------------------------------------
function submitCmd() {
//------------------------------------------------------------------------
  var line = trim(qobj.value);
  if (line != '') {
    execCmd(line);
  }
  qobj.value = '';
}

//------------------------------------------------------------------------
function addCmdToQueue(id, cmd, title, silent) {
//------------------------------------------------------------------------
  var x = queue_dom.createElement('item');
  queue_dom.getElementsByTagName('queue')[0].appendChild(x);
  var t = queue_dom.createTextNode(cmd);
  x.appendChild(t);
  x.setAttribute('id', id);
  x.setAttribute('title', title);
  x.setAttribute('silent', silent ? 1 : 0);
  
  insertResponse(id,
      '<span class="wait">Ваш запрос очереди.</span>', title);

  focusCommandLine();
}

//------------------------------------------------------------------------
function processQueue() {
//------------------------------------------------------------------------
  if (queue_processing) {
    return;
  }

  queue_processing = true;
  
  var items = queue_dom.getElementsByTagName('queue')[0].getElementsByTagName('item');
  
  while (items.length > 0) {
    var q = items[0];
    var query = q.childNodes[0].nodeValue;
    var id = q.getAttribute('id');
    var title = q.getAttribute('title');
    
    insertResponse(id, '<span class="wait">Подождите, идет проверка...</span>', title);
    
    var ok = org.cote.js.xml.getXml(script_url + '?id=' + id + '&q=' + urlEncode(query), loadHandler, 1, id);
    if (!ok) { // max pool size reached?
      break; 
    }
    running_threads++;

    q.parentNode.removeChild(q); 
    items = queue_dom.getElementsByTagName('queue')[0].getElementsByTagName('item');
  }

  queue_processing = false;
}

//------------------------------------------------------------------------
function loadHandler(s, v) {
//------------------------------------------------------------------------
  if (typeof v == "object") {
    if (typeof v.xdom == "object" && v.xdom != null && v.xdom.documentElement != null) {
      var response = v.xdom.getElementsByTagName('response')[0];
      var text = "";
      for (var i = 0; i < response.childNodes.length; i++) {
        text = text + response.childNodes[i].nodeValue;
      }
      insertResponse(v.id, text, '&lt;unknown originating command&gt;');
    } else {
      insertErrorResponse(v.id, "Invalid xml document received", '&lt;unknown originating command&gt;');
    }
  } else {
    insertErrorResponse(v.id, "Invalid response object", '&lt;unknown originating command&gt;');
  }

  running_threads--;
  processQueue();
}

//------------------------------------------------------------------------
function execCmd(text, silent) {
//------------------------------------------------------------------------
  rqid++;
  
  last_command = text;

  text = trim(text); // precaution
  text = text.replace(/^www\./, ""); // remove www. prefix

  var a = text.split(".");
  var name = a.shift();
  name = name.replace(/^\-+/, ""); // remove leading dashes
  name = name.replace(/\-+$/, ""); // remove trailing dashes
  tld = a.join(".");
  if (tld == "*") {
    tld = parseSetting("all");
  } else if (tld == "") {
    tld = parseSetting("fav");
  }
  var query = name + "+" + tld; 
  var title = name + " (" + humanReadableSettingText(tld) + ")"; 

  addCmdToQueue(rqid, query, title, silent); // adding command and it's id to queue
  if (running_threads == 0) {
    processQueue();
  }
}

//------------------------------------------------------------------------
function toggle(id) {
//------------------------------------------------------------------------
  var obj = document.getElementById(id);
  if (obj) {
    obj.style.display = (obj.style.display == "block") ? "none" : "block";
  }
}

//------------------------------------------------------------------------
function toggleHelp() {
//------------------------------------------------------------------------
  toggle('help');
  //focusCommandLine(); // this pops keyboard on iPhone which is undesired
}

//------------------------------------------------------------------------
function setPermanentCookie(name, value) {
//------------------------------------------------------------------------
  document.cookie = name + "=" + escape(value) +
    "; path=/; expires=Mon, 01-Jan-2029 00:00:00 GMT";
}

//------------------------------------------------------------------------
function getCookie(name) {
//------------------------------------------------------------------------
  var prefix = name + "=";
  var cookieStartIndex = document.cookie.indexOf(prefix);
  if (cookieStartIndex == -1) return null;

  var cookieEndIndex = document.cookie.indexOf(";", cookieStartIndex + prefix.length);

  if (cookieEndIndex == -1) cookieEndIndex = document.cookie.length;
  return unescape(document.cookie.substring(cookieStartIndex + prefix.length, cookieEndIndex));
}

//------------------------------------------------------------------------
function parseSetting(id, isdefault) {
//------------------------------------------------------------------------
  var obj = document.getElementById(id);

  if (obj) {
    var text = obj.value.toLowerCase();

    text = text.replace(/[^\w\s\.]+/g, " "); // remove whitespace and separators
    text = text.replace(/\s\./g, " "); // remove dots going after whitespace
    text = text.replace(/\s{2,}/g, " "); // remove double spaces
    text = text.replace(/^[\s\.]+/g, ""); // trim left (including leading dot)
    text = text.replace(/\s+$/g, ""); // trim right
    text = text.replace(/\s/g, "+"); // URL-escape spaces

    if ((text == "") && (!isdefault)) {
      obj.value = obj.getAttribute("default");
      return parseSetting(id, true);
    }

    return text;
  } else {
    return "";
  }
}

//------------------------------------------------------------------------
function humanReadableSettingText(text) {
//------------------------------------------------------------------------
  text = text.replace(/\+/g, ", ."); // restore proper delimiting
  if (text != "") text = '.' + text;
  return text;
}

//------------------------------------------------------------------------
function checkSetting(id) {
//------------------------------------------------------------------------
  var obj = document.getElementById(id);
  if (obj) {
    var text = parseSetting(id);
    obj.value = humanReadableSettingText(text);
    setPermanentCookie(id, text);
  }
}

//------------------------------------------------------------------------
function loadSettingFromCookie(id) {
//------------------------------------------------------------------------
  var obj = document.getElementById(id);
  if (obj) {
    var text = getCookie(id);
    if (text) {
      obj.value = text;
      checkSetting(id); // validate
    }
  }
}
