/* Lightbox display feature (embedded in page and image pages).
 * Required scripts: xbase.js netloader.js lbstore.js lbcache.js
 *
 * Required: DIV id lbframe   - holds lightbox entries
 *           DIV id lbadd     - 'add lightbox'
 *           FORM NAME lbform - for passing lightbox contents to server
 *           function         - for updating page if an image is added or removed
 *                              (e.g. links)
 *
 * Entry points:
 *    viewlightbox:  Serialises lightbox cookie contents in the lbform form and fires
 *                   a request to the server.
 *    addtolightbox: Adds an image to the lightbox, storing it in the cookie and
 *                   displaying it.
 *    loadlightbox:  Initialises (populates) the lightbox frame on page load.
 *    savelightbox:  Stores the lightbox cache data on page unload.
*/

/**************************************************************************************/

var lightBox      = new LightBox;
var lightBoxCache = new LbCache;
var lbupdatefn;		// pointer to display update callback function


/**************************************************************************************/
/* Lightbox frame manipulation primitives */
/* The lightbox is displayed as a frame (DIV ID lbframe) in which
 * entries are stored in DIV CLASS lbimageholder ID lbXXXX where XXXX 
 * the image ID.
*/


/*
 * createlbimageholder(imgid)
 * Creates a new lightbox entry frame and adds it to the lightbox.
 * The thumbnail is initialiased to a 'loading' image (loading.png) 
 * because the thumbnail dimensions and filename are not known
 * at this time. These are replaced later by callback routines.
*/
function createlbimageholder(imgid) {
	var d = document.createElement("div");
	d.className = 'lbimageholder';
	d.id = 'lb' + imgid;

	var im = document.createElement("div");
	im.className = 'lbimage';
	im.innerHTML += '<IMG ID=lbimg' + imgid + ' SRC="/loading.png" WIDTH="75" HEIGHT="75" ALT="" />'

	d.appendChild(im);
	d.innerHTML += imgid + '<br />' + '<A HREF="#" onclick="removelbentry(' + imgid + ')">Remove</A>';
/*
	d.innerHTML += '<br /><A HREF="#" onclick="viewimg(' + imgid + ')">Detail</A>';
*/
	return d;
}


/*
 * setthumbnail(imgid, w, h, srcurl)
 * Sets the thumbnail image in the lightbox for image imgid.
 * w and h are the desired display dimensions, srcurl is the 
 * URL for the thumbnail image.
 */
function setthumbnail(imgid, w, h, srcurl) {
	var imgele = xGetElementById('lbimg' + imgid);
	if (imgele) {
		imgele.src    = escape(srcurl);
		imgele.width  = escape(w);
		imgele.height = escape(h);
	}
}


/*
 * getimageidfromurl(url)
 * Examines the URL of the server query to extract the image details
 * and returns the image ID, or 0 in failure.
 * The URL is of the form: http://foo.bar.baz?id=nnnnn
 * where nnnnn is the image id.
*/
function getimageidfromurl(url) {
	var i = url.indexOf('id=');
	return i ? url.substr(i+3) : 0;
}


/* 
 * thumbnail_onload: callback function to set the thumbnail image from the
 * properties (width, height, filename) retrieved from the server.
 * The image id is retrieved from the query URL.
 */
function thumbnail_onload() {
	var imgid = getimageidfromurl(this.url);
	var re = /^(\d{5}):(\d{2,3}):(\d{2,3}):([0-9a-zA-Z_-]{1,32})\n$/;
	var props = re.exec(this.req.responseText);
	if (!(props && imgid == props[1])) {
		setthumbnail(imgid, 75, 75, '/loadfail.png');
		return;
	}
	setthumbnail(props[1], props[2]/2, props[3]/2, '/images/' + props[4] + 's.jpg');
	lightBoxCache.put(props[1], props[2], props[3], props[4]);
}


function thumbnail_onerror() {
alert("error: " + this.statusText);
}


/* 
 * thumbnail_onerror: callback function called if an error occurred
 * retrieving thumbnail properties from the server. We set the thumbnail
 * image to a "failed" image.
 * The image id is retrieved from the query URL.
*/
function thumbnail_onerror() {
	var imgid = getimageidfromurl(this.url);
	if (imgid) {
		setthumbnail(imgid, 75, 75, '/loadfail.png');
	}
}


/*
 * addlbentry(imgid)
 * Creates a new lightbox entry for image imgid.
 * Creates the frame, then initiates a call to the server to retrieve
 * the thumbnail size and URL.
*/
function addlbentry(imgid) {
	var lbf = xGetElementById('lbframe');
	if (lbf) {
		lbf.appendChild(createlbimageholder(imgid));
		var props = lightBoxCache.get(imgid);
		if (props) {
			setthumbnail(imgid, props[0]/2, props[1]/2, '/images/' + props[2] + 's.jpg');
		}
		else {
			var loader = new net.ContentLoader(
				'/cgi-bin/getthumb.cgi?id=' + imgid,
				thumbnail_onload,
				thumbnail_onerror);
		}
	}
}


/*
 * removelbentry(imgid)
 * Removes a lightbox entry from the lightbox.
 */
function removelbentry(imgid) {
	var lb = xGetElementById('lb' + imgid);
	if (lb) {
		lb.style.display = 'none';
		if (lb.parentNode) {
			lb.parentNode.removeChild(lb);
		}
	}
	lightBox.delImage(imgid);
	lightBoxCache.remove(imgid);
	if (lbupdatefn) {
		lbupdatefn.call();
	}
}


/**************************************************************************************/


/* 
 * addtolightbox(imgid)
 * Adds the image to the lightbox, storing it in the cookie and 
 * adding an entry to the lbframe.
*/
function addtolightbox(imgid) {
  if (lightBox.addImage(imgid)) {		// avoid duplicate entries
    addlbentry(imgid);
    if (lbupdatefn) lbupdatefn.call();
  }
}


// hack from IE 5 (reaches for sick bag)
// This will have to be fixed whenever the stylesheet is changed.
function ie5_fixup() {
	var ua = navigator.userAgent;
	var MSIEOffset = ua.indexOf("MSIE ");
	if (MSIEOffset >= 0 &&
            parseFloat(ua.substring(MSIEOffset + 5, ua.indexOf(';', MSIEOffset))) < 6) {
		var x = document.getElementById('lbframe');
		x.style.width      = '105px';
		x.style.height     = '550px';
		x.style.position   = 'absolute';
		x.style.top        = '80px';
		x.style.left       = '680px';
		x.style.paddingTop = '15px';
		x.style.overflow   = 'auto';
		x.style.borderColor = 'red';
		x.style.borderWidth = '1px';
	}
}


/*
 * loadlightbox(updatefn)
 * On initial load, loads the lightbox with images from the cookie.
 * updatefn is a callback function from the caller to update the
 * various links etc. on the page.
 */
function loadlightbox(updatefn) {
	ie5_fixup();		// ensure the lightbox frame is rendered properly in IE5
	var imageid = lightBox.getImages();
	var n = imageid.length;
	for (var i =0; i<n; i++) {
		addlbentry(imageid[i]);
	}
	lbupdatefn = updatefn ? updatefn : null;
	if (lbupdatefn) {
		lbupdatefn();
	}
}

function savelightbox() {
	lightBoxCache.store();
}



/*
 * viewlightbox
 * Serialises the lightbox cookie contents in the lbform form, and submits
 * the lbform request to the server.
*/
function viewlightbox() {
	var f = document.lbform;
	f.lbcontents.value = lightBox.serialise();
	f.submit();
}

/* END */
