var midfraction = 0.2;

var dest; 
var speedDefault = 10;
var speed;

var prekey = true;
var keyactive = true;
function keyon() { keyactive = true; }
function keyoff() { keyactive = false; }

var current = -1;
var currentid = "INVALID"; 
var inadwords = false;

function setcookie(i) {
  document.cookie = "kb=" + rand + "+" + i;
}

function load() {
  cookie = document.cookie;
  j = cookie.indexOf("kb=");
  k = cookie.indexOf("+", j);
  r = cookie.substring(j+3, k);
  if (r == rand) {
    current = parseInt(cookie.substring(k+1));
    if (current >= 1000) {
      inadwords = true;
      current -= 1000;
      moveto("awi" + current, true);
    } else {
      inadwords = false;
      moveto("i" + current, true);
    }
    prekey = false;
  } else if (fromkey == 1) {
    current = start;
    inadwords = false;
    moveto("i" + current, true);
    prekey = false;
  }
}

function moveto(id, animate) {
  e = document.getElementById(id);
  if (e != null) {
    c = document.getElementById(currentid);
    if (c != null) {
      c.style.display = "none";
    }
    e.style.display = "inline";
    if (id != "inext" && id != "prev") {
      scrollToMidpage(id, 100, animate);
    }
    currentid = id;
    return true;
  } else {
    // id doesn't exist; cancel move
    return false;
  }
}

function scrollpos() {
  return document.all ? document.body.scrollTop : window.pageYOffset;
}
function winheight() {
  return document.all ? document.body.clientHeight : window.innerHeight;
}

// scrolls object to middle of screen if it's not in view
// margin is the number of pixels at the bottom of the screen
// in which to consider the object "below the screen" and in need of scrolling
function scrollToMidpage(id, margin, animate) {
  windowHeight = winheight();
  scrollPosition = scrollpos();
  objectPosition = document.getElementById(id).offsetTop;
  if ((objectPosition > scrollPosition + windowHeight - margin) || (objectPosition < scrollPosition)) {
    dest = objectPosition - (windowHeight * midfraction);
    if (animate) {
      speed = speedDefault;
      animateScrollToDest();
    } else {
      window.scrollTo(0, dest);
    }
  }
}

function animateScrollToDest() {
  scrollPosition = scrollpos();
  dist = Math.abs(scrollPosition - dest)
  if ((dist <= 1) || (speed <= 1) || (dist < speed)) {
    // turns out that the screwy algorithm below doesn't
    // scroll quite to dest. but it's close enough for now.
    return;
  } else if (scrollPosition < dest) {
    delta = speed;
  } else {
    delta = -speed;
  }
  if (dist < 300) {
    speed = speedDefault - (speedDefault * (300 - dist) / 300.0);
  }
  window.scrollBy(0, delta);
  if (scrollpos() - scrollPosition == 0) {
    // haven't necessarily reached destination, but can't scroll anymore
    // ie, reached top or bottom of page
    return;
  }
  setTimeout("animateScrollToDest()", 10);
}

function inc() {
  newid = "i" + (current + 1);
  if (inadwords) {
    newid = "aw" + newid;
  }
  success = moveto(newid, true)
  if (success) {
    current += 1;
    c = inadwords? 1000 + current : current;
    setcookie(c);
  } else {
    if (inadwords) {
      success2 = moveto("i" + start, true);
      if (success2) {
        inadwords = false;
        current = start;
        setcookie(current);
      }
    } else {
      gonext();
    }
  }
}

function gonext() {
  success = moveto("inext", false);
  if (success) {
    nextpage();
  }
}

function dec() {
  newid = "i" + (current - 1);
  if (inadwords) {
    newid = "aw" + newid;
  }
  success = moveto(newid, true)
  if (success) {
    current -= 1;
    c = inadwords? 1000 + current : current;
    setcookie(c);
  } else {
    if (inadwords) {
      success2 = moveto("i" + start, true);
      if (success2) {
	inadwords = false;
        current = start;
        setcookie(current);
      }
    } else {
      goprev();
    }
  }
}

function goprev() {
  success = moveto("prev", false);
  if (success) {
    // show the prev message 
    document.getElementById("prevmsg").style.display = "inline";
    prevpage();
  }
}

function adwords() {
  if (inadwords) return;
  success = moveto("awi0", true);
  if (success) {
    current = 0;
    inadwords = true;
    setcookie(1000 + current);
  }
}

function results() {
  if (!inadwords) return;
  success = moveto("i" + start, true);
  if (success) {
    current = start;
    inadwords = false;
    setcookie(current);
  }
}

function followlink(id) {
  e = document.getElementById(id);
  if ((e != null) && (e.href != null)) {
    // fromkey indicates that we are entering the page via a keypress
    // so the page should display the google balls on arrival
    href = (e.href.indexOf("?") != -1) ?  e.href + "&fromkey=1" : e.href;
    location.href = href;
  }
}

function visit(n) {
  m = (parseInt(n) + start)
  newid = "i" + m;
  success = moveto(newid, true);
  if (success) {
    followlink("a"+m);
  }
}
function go() {
  aw = inadwords ? "aw" : "";
  followlink(aw+"a"+current);
}
function cache() { followlink("c"+current); }
function similar() { followlink("s"+current); }

function nextpage() {
  keyoff();
  followlink("next");
}

function prevpage() {
  keyoff();
  followlink("prev");
}

function searchbox() {
  document.forms[0].q.select();
  // moz/ns6 doesn't scroll to the textbox
  dest = 0;
  speed = speedDefault;
  animateScrollToDest();
}

function xprekey() {
  if (prekey) {
    success = moveto(startid, true);
    if (success) {
      current = start;
      prekey = false;
      return true;
    } else {
      return false;
    }
  } else {
    return false;
  }
}

function toghelp() {
  tog("ks");
}

var allowkeys = "anb/?1234567890";

function getkey(e) {
  if (!keyactive) return true;
  if (e == null) { // ie

    kcode = event.keyCode;
  } else { // mozilla
    if (e.altKey || e.ctrlKey) {
      // moz doesn't override ctrl keys,
      // eg, Ctrl-N won't bypass this function to open new window
      return true;
    }
    kcode = e.which;
  }
  key = String.fromCharCode(kcode).toLowerCase();
  // allow some keys to work w/o triggering prekey
  if (allowkeys.indexOf(key) == -1) {
    if (xprekey()) return true;
  }
  switch(key) {
    case "a": searchbox(); return false;
    case "n": gonext(); return false;
    case "p": goprev(); return false;
    case "k": inc(); return false;
    case "i": dec(); return false;
    case "l": adwords(); return false;
    case "j": results(); return false;
    case "\r": go(); return false;  // Enter
    //case "g": go(); return false;
    case "c": cache(); return false;
    case "s": similar(); return false;
    case "1": visit(0); return false;
    case "2": visit(1); return false;
    case "3": visit(2); return false;
    case "4": visit(3); return false;
    case "5": visit(4); return false;
    case "6": visit(5); return false;
    case "7": visit(6); return false;
    case "8": visit(7); return false;
    case "9": visit(8); return false;
    case "0": visit(9); return false;
    case "/": // / = ?
    case "?": toghelp(); return false;
  }
  return true;
}

document.onkeypress = getkey;

function tog(id) {
  e = document.getElementById(id);
  e.style.display = (e.style.display == "none") ? "inline" : "none";
}
