/*
 * Various utility services.
 */
var ArrowBwd;
var ArrowFwd;
var ChangeCallback = doNothing;
var DataCallback = dataAsIs;
var DataFetchObj;
var DataFetchTimeout;
var InfoBlock;
var InfoTitle;
var InitCallback = doNothing;
var NoteBlock;
var NoteBox;
var NoteTitle;
var OpenWinOpts = 'status=1,resize=1,toolbar=1,scrollbars=1,location=1,resizable=1,menubar=1';
var QueryURL;
var TitleCallback = dataAsIs;
var TimeOut = 5000;
var URLhistory = new Array();
var URLix = -1;
var URLstack = new Array();
var URLvisits = new Array();

function $_(id) {
	return document.getElementById(id);
}

function abortFetch() {
  var d = DataFetchObj;
  if (!d) return false;
  DataFetchObj = null;
  d.abort();
  if (DataFetchTimeout) {
    clearTimeout(DataFetchTimeout);
    DataFetchTimeout = false;
  }
  return true;
}

function addQueryURL(obj, name) {
  if (!QueryURL) return;
  var p = obj.page;
  if (!p || !obj.title) return;
  var ix;
  for (ix = 0; ix < URLhistory.length; ix++) {
    if (URLhistory[ix].indexOf("'" + p + "'") > 0)
      break;
  }
  if (ix == URLhistory.length) {
    if (!name) name = obj.callback.name;
    p = '<a class="history" id="hist-' + ix + '" onclick="doFetch('
      + "'" + p + "'" + ')">' + obj.title + '</a>';
    URLhistory[ix] = p;
  }
  p = '';
  var thisix = 0;
  var iy = URLhistory.length;
  while (--iy >= 0) {
    var h = URLhistory[iy];
    if (iy == ix) {
      h = h.replace(/"history"/, '"history current"');
      thisix = iy;
    }
    p = p + h;
  }
  QueryURL.innerHTML = p;
  $_('hist-' + thisix).scrollIntoView(false);
}

function addEvent(obj, evType, fn) {
  if (obj.addEventListener) {
    obj.addEventListener(evType, fn, false);
    return true;
  }
  if (obj.attachEvent) {
    return obj.attachEvent('on' + evType, fn);
  }
  return false;
}

function createURL(str) {
  str = str.split('/');
  for (ix = 0; ix < str.length; ix++) {
    str[ix] = str[ix].split('_').join(' ');
  }
  return iCaps(str);
}

function dataAsIs(a) { return a; }
function doNothing() { return; }

function doFetch(which, fn, adj, refresh) {
  if (which && (URLstack.length > 0)) {    // See if we already have this page cached
    var page = iCaps(which);
    var ix;
    for (ix = 0; ix < URLstack.length; ix++) {
      if (URLstack[ix].page == page) {     // We do already have this page cached
        which = null;
        URLix = ix;
        break;
      }
    }
    if (ix == URLstack.length) {           // Didn't find it yet; look in back stock
      for (ix = 0; ix < URLvisits.length; ix++) {
        if (URLvisits[ix].page == page) {  // Found it. Let's use it.
          URLix = URLstack.length;
          URLstack[URLix] = URLvisits[ix];
          which = null;
          break;
        }
      }
    }
  }
  if (!which && refresh) {
    which = URLstack[URLix].page;
    fn = URLstack[URLix].callback;
  }
  if (!which && (URLix >= 0)) {
    which = URLstack[URLix].args;
    fn = URLstack[URLix].callback;
    if (URLstack[URLix].title && URLstack[URLix].data) {
      // We don't need to call anything; we have data
      ChangeCallback();
      addQueryURL(URLstack[URLix], fn.name);
      var ti = TitleCallback(URLstack[URLix].title, URLix, URLstack.length - 1);
      fn(ti, URLstack[URLix].data);
      return;
    }
  }
  var path = getQblLink(which);
  if (path) {
    InitCallback();
    var xo = getXmlHttpObject();
    if (xo) {
      abortFetch();
      if (adj) {
        URLix += adj;
        URLstack.length = URLix;
      }
      if (URLix > URLstack.length)
         URLix = URLstack.length;
      if (URLix == URLstack.length) {
        URLstack[URLix] = {args:which, callback:fn, page:iCaps(which)};
      }
      DataFetchObj = xo;
      xo.onreadystatechange = fn;
      DataFetchTimeout = setTimeout(abortFetch, TimeOut);
      xo._timeout = DataFetchTimeout;
      xo.open("GET", path, true);
      xo.send(null);
    }
    else {
      ChangeCallback();
      alert('Failed to request this page.');
    }
  }
  return;
}

function getQblLink(which) {
  if (!InfoPath || !Lang) {
    alert('Variable ' + (InfoPath ? 'Lang' : 'InfoPath') + ' is not set. Cannot fetch pages.');
    return false;
  }
  return InfoPath + '/' + Lang + '/' + iCaps(which);
}

function getWindowSize() {
  var o = { width:0, height:0 };
  if (window && (o.width = window.innerWidth)) {
    o.height = window.innerHeight;
  }
  else if (document.documentElement) {
    o.width = document.documentElement.offsetWidth;
    o.height = document.documentElement.offsetHeight;
  }
  else {
    o.width = document.body.offsetWidth;
    o.height = document.body.offsetHeight;
  }
  return o;
}

function iCaps(str) {
  if (typeof str === 'object') {
    var s = '';
    var p = '';
    for (var ix = 0; ix < str.length; ix++) {
      s = s + p + iCaps(str[ix]);
      p = '/';
    }
    return s;
  }
  var a = str.split(' ');
  if ((a.length == 1)
   && ((str.indexOf('/') > 0)
    || (str.indexOf(' ') < 0))) {
    // Someone may already have done this for us. Only mess with the first
    // character of the string; if it looks good, use the string as is.
    var c = str.substr(0,1);
    if (c == c.toUpperCase())
      return str;
  }
  var i;
  for (i = 0; i < a.length; i++) {
    var ic = a[i].substr(0,1).toUpperCase();
    var ir = a[i].substr(1).toLowerCase();
    a[i] = ic + ir;
  }
  return a.join('_');
}

function qBwd() {
  if (URLix <= 0)
    alert("You can't go backward from here.");
  else {
    URLix--;
    doFetch(false, false, 0);
  }
}

function qFwd() {
  if ((URLix + 1) >= URLstack.length)
    alert("You can't go forward from here.");
  else {
    URLix++;
    doFetch(false, false, 0);
  }
}

function qLink(url) {
  window.open(url, '_link', OpenWinOpts);
  return true;
}

function qInfo(which) {
  return doFetch(arguments, setQblInfo, 1);
}

function qNote(which) {
  return doFetch(arguments, setQblNote, 1);
}

function qPrint(lang) {
  var url = 'printer/' + lang + '/' + URLstack[URLix].page;
  window.open(url, '_printer', OpenWinOpts);
  return false;
}

function qRefresh() {
  doFetch(false, false, 0, true);
}

function qReset() {
  if (URLix == 0) {
    alert("You're already at the first page.");
  }
  else {
    URLix = 0;
    doFetch(false, false, 0);
  }
}

function setArrowBwd(target)  { ArrowBwd  = $_(target); }
function setArrowFwd(target)  { ArrowFwd  = $_(target); }
function setChangeCallback(f) { ChangeCallback = f;     }
function setDataCallback(f)   { DataCallback = f;       }
function setInfoBlock(target) { InfoBlock = $_(target); }
function setInfoTitle(target) { InfoTitle = $_(target); }
function setInitCallback(f)   { InitCallback = f;       }
function setNoteBlock(target) { NoteBlock = $_(target); }
function setNoteTitle(target) { NoteTitle = $_(target); }
function setNoteBox(target)   { NoteBox   = $_(target); }

function setNavArrows() {
  if (ArrowBwd) {
    ArrowBwd.src = (URLix > 0) ? 'Images/arrow-prev' : 'Images/blank';
  }
  if (ArrowFwd) {
    ArrowFwd.src = ((URLix + 1) < URLstack.length) ? 'Images/arrow-next' : 'Images/blank';
  }
}

function setQblBlock(a, title, data) {
  if (!title && !data) {
    alert('I fetched a page as requested, but the response cannot be displayed.');
    return;
  }
  var ix = URLix;
  var ti = a[0];
  var di = a[1];
  var obj = ((ix >= 0) && (ix < URLstack.length)) ? URLstack[ix] : null;
  if (data) {
    di = DataCallback(di);
    data.innerHTML = di;
    if (obj) URLstack[ix].data = obj.data = di;
  }
  if (title) {
    if (obj) URLstack[ix].title = obj.title = ti;
    ti = TitleCallback(ti, URLix, URLstack.length - 1);
    title.innerHTML = ti;
  }
  if (obj) {
    var ix;
    for (ix = 0; ix < URLvisits.length; ix++) {
      if (URLvisits[ix].page == obj.page) {
        URLvisits[ix].data = obj.data;
        URLvisits[ix].title = obj.title;
        break;
      }
    }
    if (ix == URLvisits.length)
      URLvisits[ix] = obj;
    addQueryURL(obj);
  }
  setNavArrows();
  ChangeCallback();
}

function setQblInfo()
{
  if (arguments.length == 2) {
    // Our data is preformatted and handed to us.
    if (InfoTitle) InfoTitle.innerHTML = arguments[0];
    if (InfoBlock) InfoBlock.innerHTML = arguments[1];
    if (NoteBox) NoteBox.style.visibility = 'hidden';
    setNavArrows();
    ChangeCallback();
  }
  else
  if ((xo = DataFetchObj)
   && (xo.readyState == 4)) {
    DataFetchObj = null;
    clearTimeout(DataFetchTimeout);
    DataFetchTimeout = null;
    if (xo.status == 200) {
      setQblBlock(splitResponse(xo), InfoTitle, InfoBlock);
      if (NoteBox) NoteBox.style.visibility = 'hidden';
    }
  }
  return;
}

function setQblNote()
{
  if (arguments.length == 2) {
    // Our data is preformatted and handed to us.
    if (NoteTitle) NoteTitle.innerHTML = arguments[0];
    if (NoteBlock) NoteBlock.innerHTML = arguments[1];
    if (NoteBox)   NoteBox.style.visibility = 'visible';
    setNavArrows();
    return;
  }
  xo = DataFetchObj;
  if (xo && (xo.readyState == 4)) {
    DataFetchObj = null;
    if (xo.status == 200) {
      var a = splitResponse(xo);
      a[1] = a[1].replace(/(="|'|\bp-)note-/g, '$1tn-');
      setQblBlock(a, NoteTitle, NoteBlock);
      if (NoteBox) NoteBox.style.visibility = 'visible';
    }
  }
  return;
}

function splitResponse(xo) {
  var i = xo.responseText.indexOf('\n');
  return Array(xo.responseText.substring(0, i),
               xo.responseText.substring(i+1));
}

function setQueryURL(target) { QueryURL = $_(target); }

function setStartPage(dflt,arg) {
  var p = document.URL.split('?');
  if (p.length == 1)
    return dflt;
  p = p[1].split('&');
  for (var ix = 0; ix < p.length; ix++) {
    var q = p[ix].split('=');
    if (q.length == 2 && q[0] == arg)
      return createURL(q[1]);
  }
  return dflt;
}

function setTitleCallback(f) { TitleCallback = f; }


