/*
  Copyright 2010 ZombieTuesday Ltd.

  Distributed under the terms of the GPL version 3.

  This program is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.
  
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  For a copy of the GNU General Public License see <http://www.gnu.org/licenses/>.
 */

var ios = false;
var tnelementwidth;
var tnelementheight;
var tnelements = new Array();
var catnames = new Array();
var catitems = new Array();
var rowcount;
var rows;

var fsimage;
var fsimgcont;
var loadoverlay;
var preloadimage;
var tnholder;

var docheight;
var docwidth;

var prevbox;
var prevboxwidth;
var nextbox;
var nextboxwidth;
var infobox;
var infoboxwidth;
var closebut;
var tncontainer;

var topmenu;
var topmenuheight = 100;
var topmenuclosedheight = 30;
var bottommenu;
var bottommenuheight = 95;
var bottommenuclosedheight = 15;

var infoboxclosedwidth = 64;
var prevboxclosedwidth = 12;
var nextboxclosedwidth = 25;

var exclusionzonetop = 0;
var exclusionzonebottom = 200;

var growstep = 70;
var ripplestep = 20;

var imgwidth = 0;
var imgheight = 0;

var rowptr = 0;
var current = -1;
var currentcat = -1;

var loaded = false;

var ripplemove = -1;
var ripplemovestep = 1.25;
var moves = new Array();
var toprow;
var bottomrow;
var middlerows;
var otoprows;
var obottomrows;

var rippling = false;

var showtgt;
//var growing = false;
var shrinking = false;

function getRow(row) {
  var result = new Array();
  for(var i = 0; i < tnelements.length; i++) {
    if(Math.floor(i / rowcount) == row) {
      result.push(tnelements[i]);
    }
  }
  return result;
}

function findTN(elem) {
  for(var j = 0; j < tnelements.length; j++) {
    if(tnelements[j] == elem) {
      return j;
    }
  }
  return -1;
}

function findCat(cat) {
  for(var j = 0; j < catnames.length; j++) {
    if(catnames[j] == cat) {
      return j;
    }
  }
  return -1;
}

function allDone() {
  for(var i = 0; i < moves.length; i++) {
    if(((ripplemovestep * tnelementheight) - moves[i]) > 0) {
      return false;
    }
  }
  return true;
}

function rippleUp() {
  var ad = allDone();
  if((ripplemove > 0)||(!ad)) {
    rippling = true;
    if(!ad) {
      for(var i = 0; i < rowcount; i++) {
	var move = Math.floor(Math.random() * (4 * ripplestep));
	var remain = ((ripplemovestep * tnelementheight) - moves[i]);
	if(move > remain) {
	  if(remain == Math.floor(remain)) {
	    move = Math.floor(remain);
	  } else {
	    move = Math.ceil(remain);
	  }
	}
	moves[i] = moves[i] + move;
	if(toprow[i]) {
	  toprow[i].style.top = (parseInt(toprow[i].style.top) - move) + 'px';
	}
	if(bottomrow[i]) {
	  bottomrow[i].style.top = (parseInt(bottomrow[i].style.top) - move) + 'px';
	}
      }
    }
    if(ripplemove > 0) {
      var step = (ripplestep < ripplemove) ? ripplestep : ripplemove;
      for(var i = 0; i < middlerows.length; i++) {
	middlerows[i].style.top = (parseInt(middlerows[i].style.top) - step) + 'px';
      }
      for(var i = 0; i < otoprows.length; i++) {
	otoprows[i].style.top = (parseInt(otoprows[i].style.top) - step) + 'px';
      }
      for(var i = 0; i < obottomrows.length; i++) {
	obottomrows[i].style.top = (parseInt(obottomrows[i].style.top) - step) + 'px';
      }
      ripplemove -= step;
    }
    wait(50);
  } else {
    rippling = false;
    end();
  }
}

function beginRippleUp() {
  if((rowptr + rows) >= (tnelements.length / rowcount)) {
    return;
  }
  if(!rippling) {
    rippling = true;
    moves = new Array();
    for(var i = 0; i < rowcount; i++) {
      moves.push(0);
    }
    otoprows = new Array();
    for(var i = 0; i < rowptr; i++) {
      otoprows = otoprows.concat(getRow(i));
    }
    toprow = getRow(rowptr);
    middlerows = new Array();
    for(var i = rowptr + 1; i < (rowptr + rows); i++) {
      middlerows = middlerows.concat(getRow(i));
    }
    bottomrow = getRow(rowptr + rows);
    obottomrows = new Array();
    for(var i = (rowptr + rows + 1); i <= Math.ceil(tnelements.length / rowcount); i++) {
      obottomrows = obottomrows.concat(getRow(i));
    }
    rowptr++;
    ripplemove = tnelementheight;
    createThread(rippleUp, RUN);
  }
}

function rippleDown() {
  var ad = allDone();
  if((ripplemove > 0)||(!ad)) {
    rippling = true;
    if(!ad) {
      for(var i = 0; i < rowcount; i++) {
	var move = Math.floor(Math.random() * (4 * ripplestep));
	var remain = ((ripplemovestep * tnelementheight) - moves[i]);
	if(move > remain) {
	  if(remain == Math.floor(remain)) {
	    move = Math.floor(remain);
	  } else {
	    move = Math.ceil(remain);
	  }
	}
	moves[i] = moves[i] + move;
	if(toprow[i]) {
	  toprow[i].style.top = (parseInt(toprow[i].style.top) + move) + 'px';
	}
	if(bottomrow[i]) {
	  bottomrow[i].style.top = (parseInt(bottomrow[i].style.top) + move) + 'px';
	}
      }
    }
    if(ripplemove > 0) {
      var step = (ripplestep < ripplemove) ? ripplestep : ripplemove;
      for(var i = 0; i < middlerows.length; i++) {
	middlerows[i].style.top = (parseInt(middlerows[i].style.top) + step) + 'px';
      }
      for(var i = 0; i < otoprows.length; i++) {
	otoprows[i].style.top = (parseInt(otoprows[i].style.top) + step) + 'px';
      }
      for(var i = 0; i < obottomrows.length; i++) {
	obottomrows[i].style.top = (parseInt(obottomrows[i].style.top) + step) + 'px';
      }
      
      ripplemove -= step;
    }
    wait(50);
  } else {
    rippling = false;
    end();
  }
}

function beginRippleDown() {
  if(rowptr == 0) {
    return;
  }
  if(!rippling) {
    rippling = true;
    moves = new Array();
    for(var i = 0; i < rowcount; i++) {
      moves.push(0);
    }
    otoprows = new Array();
    for(var i = 0; i <= (rowptr - 2); i++) {
      otoprows = otoprows.concat(getRow(i));
    }
    toprow = getRow(rowptr - 1);
    middlerows = new Array();
    for(var i = rowptr; i < (rowptr + rows - 1); i++) {
      middlerows = middlerows.concat(getRow(i));
    }
    bottomrow = getRow(rowptr + rows - 1);
    obottomrows = new Array();
    for(var i = (rowptr + rows); i <= Math.ceil(tnelements.length / rowcount); i++) {
      obottomrows = obottomrows.concat(getRow(i));
    }
    rowptr--;
    ripplemove = tnelementheight;
    createThread(rippleDown, RUN);
  }
}

function fsgrow() {
  if(shrinking) {
    end();
    return;
  }
  var w = parseInt(fsimage.style.width);
  var h = parseInt(fsimage.style.height);
  var t = parseInt(fsimage.style.top);
  var l = parseInt(fsimage.style.left);
  var iw = parseInt(fsimgcont.width);
  var ih = parseInt(fsimgcont.height);
  var gw = docwidth;
  var gh = docheight;
  if((w < gw)||(h < gh)||(t > 0)||(l > 0)||(ih < imgheight)||(iw < imgwidth)) {
    var step;
    if(t > 0) {
      step = Math.ceil(t / 2);
      step = (step > growstep) ? growstep : step;
      fsimage.style.top = (t - step) + 'px';
      if((gh - h) >= step) {
	h = h + step;
      }
      if((imgheight - ih) >= step) {
	ih = ih + step;
      }
    }
    if(l > 0) {
      step = Math.ceil(l / 2);
      step = (step > growstep) ? growstep : step;
      fsimage.style.left = (l - step) + 'px';
      if((gw - w) >= step) {
	w = w + step;
      }
      if((imgwidth - iw) >= step) {
	iw = iw + step;
      }
    }
    if(w < gw) {
      step = Math.ceil((gw - w) / 2);
      step = (step > growstep) ? growstep : step;
      fsimage.style.width = (w + step) + 'px';
    } else { 
      step = growstep;
    }
    if(iw < imgwidth) {
      var iwd = imgwidth - iw;
      step = (step > iwd) ? iwd : step;
      fsimgcont.width = iw + step;
    }
    if(h < gh) {
      step = Math.ceil((gh - h) / 2);
      step = (step > growstep) ? growstep : step;
      fsimage.style.height = (h + step) + 'px';
    } else { 
      step = growstep;
    }
    if(ih < imgheight) {
      var ihd = imgheight - ih;
      step = (step > ihd) ? ihd : step;
      fsimgcont.height = ih + step;
    }
    wait(10);
  } else {
    if(!loaded) {
      loadoverlay.style.top = ((docheight - parseInt(loadoverlay.style.height)) / 2) + 'px';
      loadoverlay.style.left = ((docwidth - parseInt(loadoverlay.style.width)) / 2) + 'px';
      loadoverlay.style.visibility = 'visible';
    }
    topmenu.style.visibility = 'visible';
    bottommenu.style.visibility = 'visible';
    infobox.style.visibility = 'visible';
    //prevbox.style.visibility = 'visible';
    //nextbox.style.visibility = 'visible';
    closebut.style.visibility = 'visible';
    end();
  }
}

var tgtw;
var tgth;
var tgtt;
var tgtl;

function fsshrink() {
  var w = parseInt(fsimage.style.width);
  var h = parseInt(fsimage.style.height);
  var t = parseInt(fsimage.style.top);
  var l = parseInt(fsimage.style.left);
  var iw = parseInt(fsimgcont.width);
  var ih = parseInt(fsimgcont.height);
  if((w != tgtw)||(h != tgth)||(t !=tgtt)||(l != tgtl)) {
    shrinking = true;
    var step;
    if(t != tgtt) {
      step = Math.ceil((tgtt - t) / 2);
      if(step > 0) {
	step = (step > growstep) ? growstep : step;
      } else {
	step = (step < (0 - growstep)) ? (0 - growstep) : step;
      }
      fsimage.style.top = (t + step) + 'px';
      if(h != tgth) {
	h = h - step;
	//ih = ih - ((step / h) * ih);
      }
    }
    if(l != tgtl) {
      step = Math.ceil((tgtl - l) / 2);
      if(step > 0) {
	step = (step > growstep) ? growstep : step;
      } else {
	step = (step < (0 - growstep)) ? (0 - growstep) : step;
      }
      fsimage.style.left = (l + step) + 'px';
      if(w != tgtw) {
	w = w - step;
	//iw = iw - ((step / w) * iw);
      }
    }
    if(w != tgtw) {
      step = Math.ceil((tgtw - w) / 2);
      if(step > 0) {
	step = (step > growstep) ? growstep : step;
      } else {
	step = (step < (0 - growstep)) ? (0 - growstep) : step;
      }
      fsimage.style.width = (w + step) + 'px';
      //fsimgcont.width = iw + ((step / w) * iw);
    }
    if(h != tgth) {
      step = Math.ceil((tgth - h) / 2);
      if(step > 0) {
	step = (step > growstep) ? growstep : step;
      } else {
	step = (step < (0 - growstep)) ? (0 - growstep) : step;
      }
      fsimage.style.height = (h + step) + 'px';
      //fsimgcont.height = ih + ((step / h) * ih);
    }
    w = parseInt(fsimage.style.width);
    h = parseInt(fsimage.style.height);
    t = parseInt(fsimage.style.top);
    l = parseInt(fsimage.style.left);
    if(Math.abs(tgtw - w) <= 1) {
      fsimage.style.width = tgtw + 'px';
    }
    if(Math.abs(tgth - h) <= 1) {
      fsimage.style.height = tgth + 'px';
    }
    if(Math.abs(tgtt - t) <= 1) {
      fsimage.style.top = tgtt + 'px';
    }
    if(Math.abs(tgtl - l) <= 1) {
      fsimage.style.left = tgtl + 'px';
    }
    wait(10);
  } else {
    topmenu.style.visibility = 'hidden';
    bottommenu.style.visibility = 'hidden';
    infobox.style.visibility = 'hidden';
    prevbox.style.visibility = 'hidden';
    nextbox.style.visibility = 'hidden';
    fsimgcont.style.visibility = 'hidden';
    fsimage.style.visibility = 'hidden';
    loadoverlay.style.visibility = 'hidden';
    shrinking = false;
    end();
  }
}

function hideImage() {
  loadoverlay.style.visiblitiy = 'hidden';
  closebut.style.visibility = 'hidden';
  if(current >= 0) {
    var elem = catitems[currentcat][current];
    tgtw = parseInt(elem.style.width);
    tgth = parseInt(elem.style.height);
    tgtt = parseInt(document.getElementById('header').offsetHeight) + parseInt(elem.style.top);
    tgtl = parseInt(tnholder.style.left) + parseInt(elem.style.left);
  } else {
    tgtw = 0;
    tgth = 0;
    tgtl = 0;
    tgtt = 0;
  }
  createThread(fsshrink, RUN);
}

// Preload images in the background. Work through in order. 
// This will be interrupted by a click since that will replace the onload event of the preloadimage
var preloadptr = 0;
function bgpreloaded() {
  preloadptr++;
  bgpreload();
}

// Yes, this is really stupid
// Yes, it is only necessary to make IE happy.
(function() {
  var bgpreload = function() {
    if(preloadptr < tnelements.length) {
      var img;
      var ipts = tnelements[preloadptr].getElementsByTagName('INPUT');
      for(var i = 0; i < ipts.length; i++) {
	if(ipts[i].name == 'image') {
	  preloadimage.onload = bgpreloaded;
	  preloadimage.src = ipts[i].value;
	  break;
	}
      }
    }
  }

  window.bgpreload = bgpreload;
 })();



function preloadedprev() {
  // Continue background preloading.
  bgpreload();
}

function preloadednext() {
  if((current - 1) > 0) {
    var ipts = tnelements[current-1].getElementsByTagName('INPUT');
    for(var i = 0; i < ipts.length; i++) {
      if(ipts[i].name == 'image') {
	preloadimage.onload = preloadedprev;
	preloadimage.src = ipts[i].value;
      }
    }
  }
}

function preloaded() {
  loaded = true;
  if(showtgt != '') {
    fsimgcont.src = showtgt;
    showtgt = '';
  } else {
    fsimgcont.src = preloadimage.src;
  }
  loadoverlay.style.visibility = 'hidden';
  if((current + 1) < tnelements.length) {
    var ipts = tnelements[current+1].getElementsByTagName('INPUT');
    for(var i = 0; i < ipts.length; i++) {
      if(ipts[i].name == 'image') {
	preloadimage.onload = preloadednext;
	preloadimage.src = ipts[i].value;
      }
    }
  }
}

var checkcount = 0;
function checkPreload() {
  if(loaded) {
    end();
  } else {
    if(!preloadimage.complete) {
      checkcount++;
      wait(500);
    } else {
      preloaded();
      end();
    }
  }
}

function beginPreload(img) {
  loaded = false;
  preloadimage.src = img;
  preloadimage.onload = preloaded;
  checkcount = 0;
  createThread(checkPreload, RUN);
}

function loadTN() {
  var ipts = catitems[currentcat][current].getElementsByTagName('INPUT');
  for(var i = 0; i < ipts.length; i++) {
    if(ipts[i].name == 'image') {
      var tn = catitems[currentcat][current].getElementsByTagName('IMG')[0];
      fsimgcont.src = tn.src;
      loadoverlay.style.top = ((docheight - parseInt(loadoverlay.style.height)) / 2) + 'px';
      loadoverlay.style.left = ((docwidth - parseInt(loadoverlay.style.width)) / 2) + 'px';
      loadoverlay.style.visibility = 'visible';
      showtgt = ipts[i].value;
      beginPreload(showtgt);
    } else if(ipts[i].name == 'width') {
      imgwidth = ipts[i].value;
    } else if(ipts[i].name == 'height') {
      imgheight = ipts[i].value;
    } else if(ipts[i].name == 'description') {
      document.getElementById('infocont').innerHTML = ipts[i].value;
    }
  }
  
  //document.getElementById('infocont').innerHTML = '<h2>' + catnames[currentcat] + '</h2>' + document.getElementById('infocont').innerHTML;

  // recalc letterboxing instantly
  if(imgwidth < docwidth) {
    imgheight = Math.ceil((imgheight / imgwidth) * docwidth);
    imgwidth = docwidth;
  } else if(imgheight < docheight) {
    imgwidth = Math.ceil((imgwidth / imgheight) * docheight);
    imgheight = docheight;
  }
  imgwidth = imgwidth;
  imgheight = imgheight;
  if(imgwidth > docwidth) {
    imgheight = Math.ceil((imgheight / imgwidth) * docwidth);
    imgwidth = docwidth;
  }
  if(imgheight > docheight) {
    imgwidth = Math.ceil((imgwidth / imgheight) * docheight);
    imgheight = docheight;
  }
  fsimgcont.width = imgwidth;
  fsimgcont.height = imgheight;
  
  var nexttn = document.getElementById('nextcont');
  var prevtn = document.getElementById('prevcont');
  
  // Load next and prev tns
  if((current + 1) < catitems[currentcat].length) {
    var tn = catitems[currentcat][current+1].getElementsByTagName('IMG');
    nexttn.src = tn[0].src;
    nextbox.style.visibility = 'visible';
  } else {
    nextbox.style.visibility = 'hidden';
  }
  if((current - 1) >= 0) {
    var tn = catitems[currentcat][current-1].getElementsByTagName('IMG');
    prevtn.src = tn[0].src;
    prevbox.style.visibility = 'visible';
  } else {
    prevbox.style.visibility = 'hidden';
  }
}

function loadNext() {
  if(!loaded) {
    return;
  }
  if((current + 1) < catitems[currentcat].length) {
    current += 1;
    loadTN();
  }
}

function loadPrev() {
  if(!loaded) {
    return;
  }
  if((current - 1) >= 0) {
    current -= 1;
    loadTN();
  }
}

var popped = -1;
function tnunpop(e) {
  if(!e) {
    var e = window.event;
  }

  var reltg = (e.srcElement) ? e.srcElement : e.target
  while (reltg.className != 'tnelement' && reltg.nodeName != 'BODY') {
    reltg = reltg.parentNode;
  }
  if((reltg.nodeName == 'BODY')||(findTN(reltg) != popped)) {
    if(popped >= 0) {
      tnelements[popped].style.top = (parseInt(tnelements[popped].style.top) + 10) + 'px';
      tnelements[popped].style.left = (parseInt(tnelements[popped].style.left) + 10) + 'px';
      tnelements[popped].style.width = (parseInt(tnelements[popped].style.width) - 20) + 'px';
      tnelements[popped].style.height = (parseInt(tnelements[popped].style.height) - 20) + 'px';
      var img = tnelements[popped].getElementsByTagName('IMG')[0];
      img.width = img.width - 20;
      img.height = img.height - 20;
      tnelements[popped].style.zIndex = '1';
      popped = -1;
    }
  }
}

function tnunpopall() {
  if(popped >= 0) {
    tnelements[popped].style.top = (parseInt(tnelements[popped].style.top) + 10) + 'px';
    tnelements[popped].style.left = (parseInt(tnelements[popped].style.left) + 10) + 'px';
    tnelements[popped].style.width = (parseInt(tnelements[popped].style.width) - 20) + 'px';
    tnelements[popped].style.height = (parseInt(tnelements[popped].style.height) - 20) + 'px';
    var img = tnelements[popped].getElementsByTagName('IMG')[0];
    img.width = img.width - 20;
    img.height = img.height - 20;
    tnelements[popped].style.zIndex = '1';
    popped = -1;
  }
}

function tnpop(e) {
  if(!e) {
    var e = window.event;
  }

  var reltg = (e.srcElement) ? e.srcElement : e.target
  while (reltg.className != 'tnelement' && reltg.nodeName != 'BODY') {
    reltg = reltg.parentNode;
  }
  if(reltg.className == 'tnelement') {
    var index = findTN(reltg);
    if(popped != index) {
      tnunpop(e);
      popped = index;
      tnelements[popped].style.zIndex = '2';
      reltg.style.top = (parseInt(reltg.style.top) - 10) + 'px';
      reltg.style.left = (parseInt(reltg.style.left) - 10) + 'px';
      reltg.style.width = (parseInt(reltg.style.width) + 20) + 'px';
      reltg.style.height = (parseInt(reltg.style.height) + 20) + 'px';
      var img = reltg.getElementsByTagName('IMG')[0];
      img.width = img.width + 20;
      img.height = img.height + 20;
    }
  }
}

function imageShow(reltg) {
  if(shrinking) {
    return;
  }
    tnunpopall();
    var ipts = reltg.getElementsByTagName('INPUT');
    for(var i = 0; i < ipts.length; i++) {
      if(ipts[i].name == 'image') {
	showtgt = ipts[i].value;
	beginPreload(showtgt);
	var tn = reltg.getElementsByTagName('IMG')[0];
	fsimage.style.visibility = 'hidden';
	fsimage.style.position = 'absolute';
	fsimgcont.src = tn.src;
	fsimage.style.width = reltg.style.width;
	fsimage.style.height = reltg.style.height;
	fsimgcont.width = parseInt(fsimage.style.width);
	fsimgcont.height = parseInt(fsimage.style.height);
	var index = findTN(reltg);
	fsimage.style.top = (document.getElementById('header').offsetHeight + ((Math.floor(index / rowcount) - rowptr) * tnelementheight)) + 'px';
	fsimage.style.left = (document.getElementById('header').offsetHeight + ((index % rowcount) * tnelementwidth)) + 'px';
	fsimage.style.visibility = 'visible';
	fsimgcont.style.visibility = 'visible';
      } else if(ipts[i].name == 'width') {
	imgwidth = ipts[i].value;
      } else if(ipts[i].name == 'height') {
	imgheight = ipts[i].value;
      } else if(ipts[i].name == 'id') {
	current = parseInt(ipts[i].value);
      } else if(ipts[i].name == 'description') {
	document.getElementById('infocont').innerHTML = ipts[i].value;
      } else if(ipts[i].name == 'cat') {
	currentcat = findCat(ipts[i].value);
      }
    }

    //document.getElementById('infocont').innerHTML = '<h2>' + catnames[currentcat] + '</h2>' + document.getElementById('infocont').innerHTML;
    
    var index = -1;
    for(var j = 0; j < catitems[currentcat].length; j++) {
      if(catitems[currentcat][j] == reltg) {
	index = j;
	break;
      }
    }
    current = index;

    var nexttn = document.getElementById('nextcont');
    var prevtn = document.getElementById('prevcont');

    // Load next and prev tns
    if((current + 1) < catitems[currentcat].length) {
      var tn = catitems[currentcat][current+1].getElementsByTagName('IMG');
      nexttn.src = tn[0].src;
      nextbox.style.visibility = 'visible';
    } else {
      nextbox.style.visibility = 'hidden';
    }
    if((current - 1) >= 0) {
      var tn = catitems[currentcat][current-1].getElementsByTagName('IMG');
      prevtn.src = tn[0].src;
      prevbox.style.visibility = 'visible';
    } else {
      prevbox.style.visibility = 'hidden';
    }

    if(imgwidth < docwidth) {
      imgheight = Math.ceil((imgheight / imgwidth) * docwidth);
      imgwidth = docwidth;
    } else if(imgheight < docheight) {
      imgwidth = Math.ceil((imgwidth / imgheight) * docheight);
      imgheight = docheight;
    }
    imgwidth = imgwidth;
    imgheight = imgheight;
    if(imgwidth > docwidth) {
      imgheight = Math.ceil((imgheight / imgwidth) * docwidth);
      imgwidth = docwidth;
    }
    if(imgheight > docheight) {
      imgwidth = Math.ceil((imgwidth / imgheight) * docheight);
      imgheight = docheight;
    }

    createThread(fsgrow, RUN);
}

function imageLoad(e) {
  if(!e) {
    var e = window.event;
  }

  //  alert(e.target);
  var reltg = (e.srcElement) ? e.srcElement : e.target
  while (reltg.className != 'tnelement' && reltg.nodeName != 'BODY') {
    reltg = reltg.parentNode;
  }
  if(reltg.className == 'tnelement') {
    imageShow(reltg);
  }

}

function imageDisplay(filename) {
  for(var i = 0; i < tnelements.length; i++) {
    var ipts = tnelements[i].getElementsByTagName('INPUT');
    for(var j = 0; j < ipts.length; j++) {
      if((ipts[j].name == 'image')&&(ipts[j].value == filename)) {
	imageShow(tnelements[i]);
	break;
	break;
      }
    }
  }
}

var bmclosing = false;
function showBottomMenu() {
  if(bmclosing) {
    end();
    return;
  }
  var h = parseInt(bottommenu.style.height);
  if(h < bottommenuheight) {
    var step = Math.ceil((bottommenuheight - h) / 2);
    h = h + step;
    bottommenu.style.height = h + 'px';
    bottommenu.style.top = (docheight - h) + 'px';
    wait(50);
  } else {
    end();
  }
}

function hideBottomMenu() {
  var h = parseInt(bottommenu.style.height);
  if(h > bottommenuclosedheight) {
    bmclosing = true;
    var step = Math.ceil((h - bottommenuclosedheight) / 2);
    h = h - step;
    bottommenu.style.height = h + 'px';
    bottommenu.style.top = (docheight - h) + 'px';
    wait(50);
  } else {
    bmclosing = false;
    end();
  }
}

function beginShowBottomMenu() {
  createThread(showBottomMenu, RUN);
}
function beginHideBottomMenu() {
  createThread(hideBottomMenu, RUN);
}

var tmclosing = false;
function showTopMenu() {
  if(tmclosing) {
    end();
    return;
  }
  var h = parseInt(topmenu.style.top);
  if(h < 0) {
    var step = Math.ceil((0 - h) / 2);
    topmenu.style.top = (h + step) + 'px';
    wait(50);
  } else {
    end();
  }
}

function hideTopMenu() {
  var h = parseInt(topmenu.style.top);
  if(h > (0 - (topmenu.offsetHeight - topmenuclosedheight))) {
    tmclosing = true;
    var step = Math.floor(((0 - (topmenu.offsetHeight - topmenuclosedheight)) - h) / 2);
    topmenu.style.top = (h + step) + 'px';
    wait(50);
  } else {
    tmclosing = false;
    end();
  }
}

function beginShowTopMenu(e) {
  createThread(showTopMenu, RUN);
}

var ibclosing = false;
function showInfoBox() {
  if(ibclosing) {
    end();
    return;
  }
  var l = parseInt(infobox.style.left);
  if(l < 0) {
    var step = Math.ceil((0 - l) / 2);
    infobox.style.left = (l + step) + 'px';
    wait(50);
  } else {
    end();
  }
}

function hideInfoBox() {
  var l = parseInt(infobox.style.left);
  if(l > (0 - (infobox.offsetWidth - infoboxclosedwidth))) {
    ibclosing = true;
    // Its negative so we need floor rather than ceil....
    var step = Math.floor(((0 - (infobox.offsetWidth - infoboxclosedwidth)) - l) / 2);
    infobox.style.left = (l + step) + 'px';
    wait(50);
  } else {
    ibclosing = false;
    end();
  }
}

function beginShowInfoBox(e) {
  createThread(showInfoBox, RUN);
}

function beginHideInfoBox(e) {
  createThread(hideInfoBox, RUN);
}

var pbclosing = false;
function showPrevBox() {
  if(pbclosing) {
    end();
    return;
  }
  var l = parseInt(prevbox.style.left);
  if(l < 0) {
    var step = Math.ceil((0 - l) / 2);
    prevbox.style.left = (l + step) + 'px';
    wait(50);
  } else {
    end();
  }
}

function hidePrevBox() {
  var l = parseInt(prevbox.style.left);
  if(l > (0 - (prevbox.offsetWidth - prevboxclosedwidth))) {
    pbclosing = true;
    // Its negative so we need floor rather than ceil....
    var step = Math.floor(((0 - (prevbox.offsetWidth - prevboxclosedwidth)) - l) / 2);
    prevbox.style.left = (l + step) + 'px';
    wait(50);
  } else {
    pbclosing = false;
    end();
  }
}

function beginShowPrevBox(e) {
  createThread(showPrevBox, RUN);
}

function beginHidePrevBox(e) {
  createThread(hidePrevBox, RUN);
}

var nbclosing = false;
function showNextBox() {
  if(nbclosing) {
    end();
    return;
  }
  var l = parseInt(nextbox.style.left);
  if(l > (docwidth - nextbox.offsetWidth)) {
    var step = Math.ceil((l - (docwidth - nextbox.offsetWidth)) / 2);
    nextbox.style.left = (l - step) + 'px';
    wait(50);
  } else {
    end();
  }
}

function hideNextBox() {
  var l = parseInt(nextbox.style.left);
  if(l < (docwidth - nextboxclosedwidth)) {
    nbclosing = true;
    var step = Math.ceil(((docwidth - nextboxclosedwidth) - l) / 2);
    nextbox.style.left = (l + step) + 'px';
    wait(50);
  } else {
    nbclosing = false;
    end();
  }
}

function beginShowNextBox(e) {
  createThread(showNextBox, RUN);
}

function beginHideNextBox(e) {
  createThread(hideNextBox, RUN);
}

function beginHideMenus(e) {
  createThread(hideTopMenu, RUN);
  //createThread(hideBottomMenu, RUN);
  createThread(hideInfoBox, RUN);
  createThread(hidePrevBox, RUN);
  createThread(hideNextBox, RUN);
}

function initWindow() {
  if( typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    docwidth = window.innerWidth;
    docheight = window.innerHeight;
  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
    //IE 6+ in 'standards compliant mode'
    docwidth = document.documentElement.clientWidth;
    docheight = document.documentElement.clientHeight;
  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
    //IE 4 compatible
    docwidth = document.body.clientWidth;
    docheight = document.body.clientHeight;
  }

  topmenu.style.position = 'absolute';
  topmenu.style.zIndex = '4';
  topmenu.style.top = (0 - (topmenu.offsetHeight - topmenuclosedheight)) + 'px';
  topmenu.style.left = ((docwidth - parseInt(topmenu.offsetWidth)) / 2) + 'px';
  bottommenu.style.position = 'absolute';
  bottommenu.style.zIndex = '4';
  bottommenu.style.height = bottommenuclosedheight + 'px';
  bottommenu.style.top = (docheight - bottommenu.offsetHeight) + 'px';
  bottommenu.style.left = ((docwidth - parseInt(bottommenu.offsetWidth)) / 2) + 'px';

  infobox = document.getElementById('infobox');
  prevbox = document.getElementById('prevbox');
  infoboxwidth = parseInt(infobox.offsetWidth);
  infobox.style.position = 'absolute';
  infobox.style.zIndex = '4';
  infobox.style.top = Math.floor((docheight - ((infobox.offsetHeight * 1.5) + prevbox.offsetHeight)) / 2) + 'px';
  infobox.style.left = (0 - (infobox.offsetWidth - infoboxclosedwidth)) + 'px';

  closebut.style.top = (parseInt(infobox.style.top) - (1.5 * closebut.offsetHeight)) + 'px';
  closebut.style.zIndex = '3';

  prevboxwidth = parseInt(prevbox.offsetWidth);
  prevbox.style.position = 'absolute';
  prevbox.style.zIndex = '4';
  prevbox.style.top = Math.floor(parseInt(infobox.style.top) + (infobox.offsetHeight * 1.5)) + 'px'
  prevbox.style.left = (0 - (prevbox.offsetWidth - prevboxclosedwidth)) + 'px';

  nextbox = document.getElementById('nextbox');
  nextboxwidth = parseInt(nextbox.offsetWidth);
  nextbox.style.position = 'absolute';
  nextbox.style.zIndex = '4';
  nextbox.style.top = prevbox.style.top;
  nextbox.style.left = (docwidth - nextboxclosedwidth) + 'px';

  loadoverlay.style.top = ((docheight - parseInt(loadoverlay.offsetHeight)) / 2) + 'px';
  loadoverlay.style.left = ((docwidth - parseInt(loadoverlay.offsetWidth)) / 2) + 'px';

  var arrowwidth = document.getElementById('upDownHolder').offsetWidth + 30;
  var oldrowcount = rowcount ? rowcount : 0;
  rowcount = Math.floor((docwidth - arrowwidth) / tnelementwidth);
  tnholder.style.width = (rowcount * tnelementwidth) + 'px';

  var tnheight = docheight - (document.getElementById('header').offsetHeight + document.getElementById('subFooter').offsetHeight + document.getElementById('uberFooter').offsetHeight);
  tncontainer.style.height = tnheight + 'px';
  rows = Math.floor((tnheight - (tnelementheight / 2)) / tnelementheight);
  tnholder.style.height = ((rows + 0.5) * tnelementheight) + 'px';
  rowptr = Math.floor((rowptr * oldrowcount) / rowcount);

  for(var i = 0; i < tnelements.length; i++) {
    var row = Math.floor(i / rowcount);
    if((i >= (rowptr * rowcount))&&(i < ((rowptr * rowcount) + (rows * rowcount)))) {
      // mid
      tnelements[i].style.top = ((tnelementheight / 4) + ((row - rowptr) * tnelementheight))+ 'px';      
    } else if(i >= ((rowptr * rowcount) + (rows * rowcount))) {
      // bottom
      tnelements[i].style.top = (((row - rowptr) * tnelementheight) + (tnelementheight / 2)) + 'px';
    } else {
      // top
      tnelements[i].style.top = (0 - ((rowptr - row) * tnelementheight)) + 'px';
    }
    tnelements[i].style.left = ((i % rowcount) * tnelementwidth) + 'px';
  }
  tnholder.style.left = (((docwidth - parseInt(tnholder.offsetWidth)) - arrowwidth) / 2) + 'px';
  tnholder.style.visibility = 'visible';

  // If fsimage is shown then resize it
  if(fsimage.style.visibility == 'visible') {
    fsimage.style.width = docwidth + 'px';
    fsimage.style.height = docheight + 'px';
    if(imgwidth < docwidth) {
      imgheight = Math.ceil((imgheight / imgwidth) * docwidth);
      imgwidth = docwidth;
    } else if(imgheight < docheight) {
      imgwidth = Math.ceil((imgwidth / imgheight) * docheight);
      imgheight = docheight;
    }
    imgwidth = imgwidth;
    imgheight = imgheight;
    if(imgwidth > docwidth) {
      imgheight = Math.ceil((imgheight / imgwidth) * docwidth);
      imgwidth = docwidth;
    }
    if(imgheight > docheight) {
      imgwidth = Math.ceil((imgwidth / imgheight) * docheight);
      imgheight = docheight;
    }
    fsimgcont.width = imgwidth;
    fsimgcont.height = imgheight;
  }

}

function doScroll(delta) {
  if(delta > 0) {
    beginRippleDown();
  } else {
    beginRippleUp();
  }
}

var lastmouse = 0;
var mousedir = 0;
function mouseMove(e) {
  if(!e) {
    e = window.event;
  }
  mousedir = e.clientX - lastmouse;
  lastmouse = e.clientX;
}

function wheel(e) {
  var delta = 0;
  if(!e) {
    e = window.event;
  }
  if(e.wheelDelta) {
    delta = e.wheelDelta / 120;
    if(window.opera) {
      delta = - delta;
    }
  } else if(e.detail) {
    delta = 0 - (e.detail / 3);
  }
  if(delta == 0) {
    delta = mousedir;
  }
  if(delta != 0) {
    doScroll(delta);
  }
}

var bounce = false;
function keyHandler(e) {
  if(!e) {
    e = window.event;
  }
  if(((e.type == 'keydown')&&(!bounce))||(e.type == 'keypress')) {
    bounce = true;
    switch(e.keyCode) {
    case 33:
    case 38:
      // up arrow, go down
      beginRippleDown();
      break;
    case 34:
    case 40:
      // down arrow, go up
      beginRippleUp();
      break;
    }
  } else {
    bounce = false;
  }
}

function showCat(cat) {
  var catidx = findCat(cat);
  if(catidx >= 0) {
    imageShow(catitems[catidx][0]);
  }
}

function initGal() {

  fsimage = document.getElementById('fsimage');
  fsimage.style.visibility = 'hidden';
  fsimage.style.zIndex = '3';
  fsimage.style.backgroundColor = '#000000';
  fsimage.style.overflow = 'hidden';
  fsimgcont = document.getElementById('fsimgcont');
  fsimgcont.style.visibility = 'hidden';
  fsimage.onmouseover = beginHideMenus;

  loadoverlay = document.getElementById('loadoverlay');

  preloadimage = new Image();
  tnholder = document.getElementById('tnholder');
  tnholder.style.visibility = 'hidden';
  tnholder.style.position = 'relative';
  tnholder.style.float = 'center';
  tnholder.style.overflow = 'hidden';

  tncontainer = document.getElementById('tncontainer');

  var tns = document.getElementsByTagName('DIV');
  for(var i = 0; i < tns.length; i++) {
    if(tns[i].className == 'tnelement') {
      if(!tnelementheight) {
	tnelementheight = parseInt(tns[i].offsetHeight);
	tnelementwidth = parseInt(tns[i].offsetWidth);
      }
      var ipts = tns[i].getElementsByTagName('INPUT');
      for(var j = 0; j < ipts.length; j++) {
	if(ipts[j].name == 'id') {
	  ipts[j].value = tnelements.length;
	} else if(ipts[j].name == 'cat') {
	  var cat = findCat(ipts[j].value);
	  if(cat < 0) {
	    cat = catnames.length;
	    catnames.push(ipts[j].value);
	    catitems[cat] = new Array();
	  }
	  catitems[cat].push(tns[i]);
	}
      }
      tnelements.push(tns[i]);
      tns[i].style.position = 'absolute';
      tns[i].onclick = imageLoad;
      tns[i].onmouseover = tnpop;
    }
  }

  document.body.onmouseover = tnunpop;

  topmenu = document.getElementById('topmenu');
  topmenuheight = parseInt(topmenu.offsetHeight);
  topmenu.style.visibility = 'hidden';
  topmenu.onmouseover = beginShowTopMenu;
  bottommenu = document.getElementById('bottommenu');
  bottommenuheight = parseInt(bottommenu.offsetHeight);
  bottommenu.style.visibility = 'hidden';
  //bottommenu.onmouseover = beginShowBottomMenu;

  closebut = document.getElementById('closebut');
  closebut.onclick = hideImage;

  rowptr = 0;
  initWindow();
  window.onresize = initWindow;
  infobox.onmouseover = beginShowInfoBox;
  prevbox.onmouseover = beginShowPrevBox;
  document.getElementById('prevcont').onclick = loadPrev;
  nextbox.onmouseover = beginShowNextBox;
  document.getElementById('nextcont').onclick = loadNext;

  if(window.addEventListener) {
    window.addEventListener('DOMMouseScroll', wheel, false);
    window.addEventListener('scroll', wheel, false);
    window.addEventListener('keypress', keyHandler, false);
    window.addEventListener('keydown', keyHandler, false);
    window.addEventListener('keyup', keyHandler, false);
  }
  document.onmousewheel = wheel;
  document.onscroll = wheel;
  document.onkeypress = keyHandler;
  document.onkeyup = keyHandler;
  document.onkeydown = keyHandler;
  if(navigator.platform == 'iPhone') {
    if(window.addEventListener) {
      window.addEventListener('mousedown', mouseMove, false);
      window.addEventListener('mouseup', mouseMove, false);
      window.addEventListener('click', mouseMove, false);
    }
    document.onmousedown = mouseMove;
    document.onmouseup = mouseMove;
    ios = true;
  }
  document.body.style.overflow = 'hidden';
  // Begin background preloading.
  bgpreload();

}

