// only track one gallery globally (e.g., main image but not sidebar)
var globalgallery;
var lastdata;

var gallery = new Array();
var node = new Array();
var track;
var mintrack = 0;
var lasttrack;
var selfname;

// map of titles => feed indices
var nameindex = new Array();
var activeindex = 0;
var lastactive = 0;

function setHash(hash) {
	hashListener.setHash(hash);
}

function getHash() {
  var h = document.location.hash;
  if (!h) return h;
  return h.split('#')[1];
}

function dbg(s) {
	var out = document.getElementById("dbg");
	out.innerHTML = "";
	document.title = s;
	out.appendChild(document.createTextNode(s));
}
 

hashListener.onHashChanged = function () {
  var h = getHash();
  if (globalgallery) Advance(0, h);
};

function HasOverlay()
{
	var ov = document.getElementById('overlay');
	if (ov.style.display == 'block') return true;

	return false;
}

function getWinHeight()
{
  var winHeight = 0;

	if( typeof( window.innerWidth ) == 'number' ) {
		//Non-IE
		winHeight = window.innerHeight;
	} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
		//IE 6+ in 'standards compliant mode'
		winHeight = document.documentElement.clientHeight;
	} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
		//IE 4 compatible
		winHeight = document.body.clientHeight;
	}

  return winHeight;
}


function getWinWidth()
{
  var winWidth = 0;

	if( typeof( window.innerWidth ) == 'number' ) {
		//Non-IE
		winWidth = window.innerWidth;
	} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
		//IE 6+ in 'standards compliant mode'
		winWidth = document.documentElement.clientWidth;
	} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
		//IE 4 compatible
		winWidth = document.body.clientWidth;
	}

  return winWidth;
}

function cancelprop(e)
{
  if (!e) e = window.event;

	e.cancelBubble = true;
	if (e.stopPropagation) {
    e.stopPropagation();
    e.preventDefault();
  }
}

function dlfile()
{
  var item = gallery[activeindex];
  var hr   = item.href;
  if (hr) {
    hr += "?dl=1";
    if (item.enhance) hr += "&auto=2";
    document.location.href = hr;
  }
  cancelprop();
}

function enhance()
{
    var item = gallery[activeindex];
    item.enhance = !item.enhance;   
    refreshactive();
}

function zoom()
{
    var item = gallery[activeindex];
    item.zoom = !item.zoom;
    refreshactive();
}

function nobubble(e, fn)
{
  cancelprop(e);
  fn();
}

function CenterObj(w, h, o, d)
{
	var winHeight = 0, winWidth = 0;

	if( typeof( window.innerWidth ) == 'number' ) {
		//Non-IE
		winWidth = window.innerWidth;
		winHeight = window.innerHeight;
	} else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
		//IE 6+ in 'standards compliant mode'
		winWidth = document.documentElement.clientWidth;
		winHeight = document.documentElement.clientHeight;
	} else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
		//IE 4 compatible
		winWidth = document.body.clientWidth;
		winHeight = document.body.clientHeight;
	}

	//$$$todo read from DOM
	w = parseInt(w) + 24 * 2;
	h = parseInt(h) + 24 * 2;

	// position
	var xoff = winWidth - w;
	var yoff = winHeight - h;
	xoff /= 2;
	yoff /= 2;

  xoff += d;

	// center "up" for nice framing
	if (yoff > 5)
    yoff *= 0.9;

	o.style.left = xoff + "px";
	o.style.top = yoff + "px";	

	// and show it
	o.style.display = 'block';
}

function ServerMsg(obj)
{
	mintrack = obj.v;
	if (obj.owner != selfname) {
		Advance(0, obj.msg, 1);
	}
}

function Advance(inc, name, server)
{
	var pe = activeindex + inc;

	if (inc == 0) {
		if (name && name.length > 0) {
            var rawname = unescape(name);
			pe = parseInt(nameindex[rawname]);
		} else {
			pe = -1;	// no popup
		}
	}

	if (activeindex == pe) return;

  lastactive = activeindex;
  
	if (name != "safe" && activeindex >= 0 && activeindex < gallery.length) {
		activeindex = pe;
	}

	if (pe >= 0 && pe < gallery.length) {
		activeindex = pe;
		
		if (!server) {
			var r = "&r=" + Math.random() + "&owner=" + selfname;

			if (inc != 0) {
				// update track:
				var t = lastdata.items[activeindex].title

				var ttrack = baseimg() + "1.gif?msg=" + t + r;
				if (ttrack != lasttrack) {
					lasttrack = ttrack;
					//track.src = "1.gif?msg=" + t + r;
					track.src = ttrack;
					//mintrack ++;
				}

				setHash(escape(t));
			} else {
				if (name != "all" && name != "safe") {
					track.src = baseimg() + "1.gif?msg=" + name + r;
				}
			}
		}

		var m, n1, p1;
		
		if (node[0].id == pe) {
		  m = 0; n1 = 1; p1 = 2;
		} else if (node[1].id == pe) {
		  m = 1; n1 = 0; p1 = 2; 
		} else if (node[2].id == pe) {
		  m = 2; n1 = 1; p1 = 0;
		} else {
		  m = 0; n1 = 1; p1 = 2;
		  node[m].obj.innerHTML = gallery[pe].ihtml;
		  node[m].id = pe;
		}
  
    var inf = document.getElementById("info");
    if (inf) inf.innerHTML = gallery[pe].desc;

		CenterObj(gallery[pe].lastwidth, gallery[pe].lastheight, node[m].obj, 0);
		//onTimer("start");

		var ind2 = pe + 1;
		var ind0 = pe - 1;
    
		if (ind0 >= 0 && ind0 < gallery.length) {
		  node[n1].obj.innerHTML = gallery[ind0].ihtml;
		  node[n1].id = ind0;
		}
		
		//if (node[n1].id != lastactive) {
      node[n1].obj.style.display = 'none';
    //}
    
		if (ind2 >= 0 && ind2 < gallery.length) {
		  node[p1].obj.innerHTML = gallery[ind2].ihtml;
		  node[p1].id = ind2;
		}
		
		//if (node[p1].id != lastactive) {
      node[p1].obj.style.display = 'none';
    //}
    
		showoverlay(1);

	} else if (name != "safe") {
		if (name != "all") {
			setHash("all");
		} else {
			hideoverlay_();
		}
	}
}


function hkeys(e) {
	
	var evtobj = window.event ? event : e;
	var unicode=evtobj.charCode? evtobj.charCode : evtobj.keyCode;
	
	if (HasOverlay()) {
    if (unicode == 68) dlfile();
    if (unicode == 69) enhance();
    if (unicode == 90) zoom();
	}
	
	if (unicode == 39) {
		if (!HasOverlay()) activeindex = -1;
		Advance(1);
	}
	if (unicode == 38) {
		showoverlay(0);
	}
	if (unicode == 37) {
		if (!HasOverlay()) activeindex = gallery.length;
		Advance(-1);
	}
	//esc
	if (unicode == 27) {
		showoverlay(0);
	}
	//enter
	if (unicode == 13) {
		if (HasOverlay()) showoverlay(0);
		else {
			activeindex = -1;
			Advance(1);
		}
	}
	//alert(unicode);
}
 
document.onkeydown = hkeys;

function navto(url)
{
	Advance(0, url);
	setHash(url);
}

function imghtml(index)
{
 	var winh = getWinHeight();

  var item = gallery[index];

  var width = item.width;
  var height = item.height;
  
  var iw = parseInt(item.width);
  var ih = parseInt(item.height);

  var sz = 640;
  //if (sz > 96) sz -= 96;

  // if we're in "zoom" adjust sz:
  if (item.zoom) {
    var winw = getWinWidth();
    var rx = winw / iw;
    var ry = winh / ih;
    
    var zw, zh;
    
    if (rx < ry) {
      zw = rx * iw;
      zh = rx * ih;
    } else {
      zw = ry * iw;
      zh = ry * ih;
    }
    
    sz = zw;
    if (zh > zw) sz = zh;
  }
  
  // auto-fit to sz
  if (iw < ih) {
    height = sz;
    width  = Math.floor(item.width * sz / item.height + 0.5);
  } else {
    width = sz;
    height = Math.floor(item.height * sz / item.width + 0.5);
  }
  
  if (iw < sz && ih < sz) {
    width = item.width;
    height = item.height;
  }
  
  item.lastwidth = width;
  item.lastheight = height;
  
  var turl = item.href + "?size=" + sz;
  //imgurl = imgurl + "?size=1024";
  
  if (item.enhance) {
    turl += "&auto=2";
  }

  var classname = "galbum";
  if (item.zoom) classname = "gzoom";
  
  var istr = "<a href='javascript:showoverlay(0);'><img class='" + classname + "' width=" + width + " height=" + height + " src=\"" + turl + "\"></a>";
  
  if (item.summary) {
    istr += "<div class='caption' style='margin-bottom:40px'>" + item.summary + "</div>";
  }
  
  return istr;
}

function outputg(data, divname)
{
	lastdata = data;
	var str = new Array();
	var si = 0;

	var container = document.getElementById(divname);

	var endindex = data.items.length;
	var startindex = 0;

	//str[si++] = "<div style='float:right'><a href='javascript:Advance(-1)'>prev</a>";
	//str[si++] = "&nbsp;&nbsp;&nbsp;";
	//str[si++] = "<a href='javascript:Advance(1)'>next</a></div>";

	var gi = 0;
	
	for (var i = startindex; i < endindex; i++) {
	
		var item = data.items[i];
		var imgurl = item.url;
		var turl = item.thumb;
		
		var desc = item.summary;
		
		var metadata = item.title + " (" + item.width + "x" + item.height + ")";
		if (item.summary) {
      metadata += item.summary;
		}
	
	  // set up image object...	
		nameindex[item.title] = gi;
		gallery[gi] = new Object();
		
		gallery[gi].width   = item.width;
		gallery[gi].height  = item.height;
		gallery[gi].href    = imgurl;
		gallery[gi].desc    = metadata;
		gallery[gi].enhance = 0;
		gallery[gi].zoom    = 0;

		gallery[gi].ihtml  = imghtml(gi);
		
		gi ++;
	}

	// write some nodes
	str[si++] = "<div style='display:none;position:fixed;z-index:100;' id='n0'></div>";
	str[si++] = "<div style='display:none;position:fixed;z-index:100;' id='n1'></div>";
	str[si++] = "<div style='display:none;position:fixed;z-index:100;' id='n2'></div>";

	var basetrack = baseimg() + '1.gif?msg=all';

	str[si++] = "<img src='" + basetrack + "' style='display:none;' id='ntrack'>";

  // topnav
  str[si++] = "<div class='topnav' id='topnav'></div>";

	// and container for thumbs
	str[si++] = "<div id='thumbcontainer'></div>";
	
	// and container for subdirs
	str[si++] = "<div id='subdir'></div>";

	result = str.join("");
	container.innerHTML = result;
	
	for (var i = 0; i < 3; i++) {
		node[i] = new Object();
		node[i].id = -1;
	}

	node[0].obj = document.getElementById('n0');
	node[1].obj = document.getElementById('n1');
	node[2].obj = document.getElementById('n2');
	track		= document.getElementById('ntrack');

	var hash = getHash();
	
	Advance(0, hash);
  
    // write topnav (siblings and parents)
    if (document.location.pathname != '/') {
        var paren = "";
        if (typeof(data.items) != 'undefined' && data.items.length) {
          paren = " (" + data.items.length + " photos)";
        }
        document.getElementById("topnav").innerHTML = "<a href='..'>Stuff</a> &raquo; " + data.name + paren;
    }

	// write thumbs here so the larger image loads quickly
	var str2 = new Array();

	var tsize = 180;

	for (var i = startindex; i < endindex; i++) {
		var item = data.items[i];
		var turl = item.url + "?size=" + tsize + "&shadow=4&bgcolor=f3f3f3";
        //exifthumb:
		//var turl = item.url + "?size=" + tsize + "&shadow=4&bgcolor=f3f3f3&thumb=1";
		var label = data.items[i].title;
		if (label == null) label = "";
		
		// ignores the shadow:
		/*
		var width = tsize;
		var height = tsize;
		if (item.width > item.height) {
			height = Math.floor(tsize * item.height / item.width + 0.5);
		} else {
			width = Math.floor(tsize * item.width / item.height + 0.5);
		}*/

		var href = escape(data.items[i].title);

		str2[si++] = "<a class='x-inline-block thumb' onmousedown=\"navto('" + href + "')\" label='" + label + "' href=\"#" +  href + "\"><img style='border:none' src=\"" + turl + "\"></a>";
	}

/*
	var str4 = new Array();	

	var xi = 0;
str4[xi++] = "<table><tr>";

	for (var i = startindex; i < endindex; i++) {
		var item = data.items[i];
		var turl = item.url + "?ymax=640";
		var label = data.items[i].title;
		if (label == null) label = "";

		//var href = "'" + data.items[i].title + "'";
		var href = data.items[i].title;

		str4[xi++] = "<td><a class='white-space:nowrap;' onmousedown=\"navto('" + href + "')\" label='" + label + "' href=#" +  href + "><img style='border:none' src='" + turl + "'></a></td>";
	}

	str4[xi++] = "</tr></table>";

	document.getElementById("thumbcontainer").innerHTML = str2.join("") + str4.join("");
	*/
	document.getElementById("thumbcontainer").innerHTML = str2.join("");

  // finally write subdirs at bottom/left/etc.
  var str3 = new Array();

  if (typeof(data.subdir) != 'undefined') {
	  var slen = data.subdir.length;
	  for (var i = 0; i < slen; i++) {
		var item = data.subdir[i];
		var rimg = "<img style='width:16px;height:16px;border:0;background-color:#f00' align=left border=0 src=\"" + item.link + "/first.jpg?thumb=1&xmax=16&ymax=16&sharpen=1\"/>";
		str3[si++] = rimg + "<a class='sublink' href=\"" + item.link + "/\">" + item.name + "</a>";
	  }
	}
	document.getElementById("subdir").innerHTML = str3.join("");

	// get focus out of address bar...
	document.body.focus();
}

function loadData(url) {
	var headTag = document.getElementsByTagName("head").item(0);
	var scriptTag = document.createElement("script");
	scriptTag.src = url;
	headTag.appendChild(scriptTag);
}

function hideoverlay_()
{
	var ov = document.getElementById('overlay');
	ov.style.display = 'none';
	node[0].obj.style.display = 'none';
	node[1].obj.style.display = 'none';
	node[2].obj.style.display = 'none';
}

function showoverlay(d)
{
	var ov = document.getElementById('overlay');
	if (d) {
		ov.style.display = 'block';
	} else {
		hideoverlay_();
		setHash("all");
	}
}

var galcounter = 0;
var whee = 0;

var tdelta = 0;

function wheel(event){
	    
	if (!HasOverlay()) {
		return;
	}

    var delta = 0;
    var isMac = -1 != (navigator.userAgent.indexOf("Macintosh"));

    if (!event) // IE
            event = window.event;
    if (event.wheelDelta) { // IE/opera/safari
            if (isMac) delta = event.wheelDelta / 40;
            else delta = event.wheelDelta / 120;
            if (window.opera) delta = -delta;
    } else if (event.detail) { // gecko
            delta = -event.detail;
            if (!isMac) delta /= 3;
            else delta /= 2;
    }

    tdelta += delta;
    var idelta = parseInt(tdelta);
    tdelta -= idelta;
    
    if (idelta) Advance(-idelta, "safe");

	// cancel default scroll
	if (event.preventDefault) event.preventDefault();
	event.returnValue = false;
}

function refreshactive() {
  if (HasOverlay()) {
    var item = gallery[activeindex];
    item.ihtml = imghtml(activeindex);

		for (var i = 0; i < 3; i++) {
			if (node[i].id == activeindex) {
        node[i].obj.innerHTML = item.ihtml;
        CenterObj(item.lastwidth, item.lastheight, node[i].obj, 0);
			}
		}
  }
}

function onresize(event) {

	if (HasOverlay()) {
		for (var i = 0; i < 3; i++) {
			if (node[i].id == activeindex) {
				CenterObj(gallery[activeindex].lastwidth, gallery[activeindex].lastheight, node[i].obj, 0);
			}
		}
	}
}

var gbug = 0;

function xhrtrack(url) {

	//dbg("Loaded." + gbug ++);
	if (window.XMLHttpRequest) {
		req = new XMLHttpRequest();
		req.onreadystatechange = function() { xhrDone(req); };
		req.open("GET", url, true);
		req.send(null);
		// IE/Windows ActiveX version
	} else if (window.ActiveXObject) {
		req = new ActiveXObject("Microsoft.XMLDOM");
		if (req) {
			req.onreadystatechange = function() {xhrDone(req);};
			req.open("GET", url, true);
			req.send(null);
		}
	}
}

function baseimg() {
	var baseimg = window.location.protocol;
	var host = window.location.host;
	
	if (host.indexOf(".herf") != -1) {
    baseimg += "//img-";
  } else {
    baseimg += "//img.";
    if (host.indexOf("www.") == 0) {
      host = host.substr(4);
    }
  }
 	baseimg += host;
	baseimg += window.location.pathname;

	return baseimg;
	//return "";
}

function firexhr() {
 		// build new url and fire off
		var msgurl = window.location.protocol;
		msgurl += "//msg-";
 		msgurl += window.location.host;
		msgurl += window.location.pathname;

		//msgurl += "msg.json?v=" + mintrack + "&r=" + Math.random() + "&owner=" + selfname;
		msgurl = "msg.json?v=" + mintrack + "&r=" + Math.random() + "&owner=" + selfname;
		xhrtrack(msgurl);
}

function xhrDone(req) {

	//dbg(req.readyState + ": " + req.responseText);
	//dbg(req.readyState + ": " + req.responseText);

	//dbg("Done" + req.readyState + " " + gbug);
	var fail = 0;
	if (req.readyState == 4) {
		if (req.status == 200) {

			var tobj = eval( "(" + req.responseText +")");

			if (typeof(tobj.msg) != 'undefined') {
				// only accept this msg if we're not "skipping" it due to our own events
				ServerMsg(tobj);
				firexhr();
			} else {
				fail = 1;
			}
		} else {
			fail = 1;
		}

		if (fail) window.setTimeout(firexhr, 1000);

		req = null;
	}
}

function loadg140(folderjson, thumbsz, imgsz) {

	galcounter ++;
	var galname = "gallery" + galcounter;
	var galcbk  = "galcbk" + galcounter;

	// overlay layer
	//document.writeln("<div id='overlay' class='overlay' onclick='javascript:showoverlay(0);' onmousedown='javascript:showoverlay(0);'></div>");
	document.writeln("<div id='overlay' class='overlay' onclick='javascript:showoverlay(0);'>");
	document.writeln("<div class='bottombar'>Actions: ");
	document.writeln("<a class='act' onclick='nobubble(event, zoom);'><b>Z</b>oom</a>");
	document.writeln("<a class='act' onclick='nobubble(event, enhance);'><b>E</b>nhance</a>");
	document.writeln("<a class='act' onclick='nobubble(event, dlfile);'><b>D</b>ownload</a>");
	document.writeln("<div id='info' class='info'></div>");

	document.writeln("</div></div>");
	document.writeln("<pre><span id='dbg'></span></pre>");
	document.writeln("<div id=" + galname + ">Loading...</div>");

	// emit a callback for this instance
	var headTag = document.getElementsByTagName("head").item(0);
	var scriptTag = document.createElement("script");
	scriptTag.text = "function " + galcbk + "(data) {outputg(data, '" + galname + "');}";
	headTag.appendChild(scriptTag);
	
	var delim = '?';
	
	if (folderjson.indexOf('?') != -1) {
    delim = '&';
	}
	
	var feed = folderjson + delim + 'callback=' + galcbk;
	
	loadData(feed);

	selfname = Math.round(Math.random() * 100000000);

	if (!globalgallery) {
    globalgallery = galname;

		window.onresize = onresize;

		if (window.addEventListener) {
			/** DOMMouseScroll is for mozilla. */
			window.addEventListener('DOMMouseScroll', wheel, false);
			window.addEventListener('resize', onresize, false);
		} else {
			/** IE/Opera. */
			window.onmousewheel = document.onmousewheel = wheel;
		}
		
		// safari/chrome appear to need an extra kick here:
		window.onmousewheel = wheel;

    window.setTimeout(firexhr, 500);
	}
}
