var fw = new Object();

if (document.all != undefined)
{
	fw.browser = 'ie';	
}
else
{
	fw.browser = 'mozilla';
}
	
fw.events = {
	createEvent: function (eventName, id, func)
	{
		var __this = this;
		
		if (typeof(this.__events) == 'undefined') this.__events = new Object();	
		if (typeof(this.__events[eventName]) == 'undefined') this.__events[eventName] = new Object();
		
		this.__events[eventName][id] = func;
		if (typeof(this[eventName]) != 'function')
		{
			this[eventName] = function ()
			{
				fw.events.invokeAll(__this, eventName);
			}
		} 
		
	}
};

fw.timing = {
	setTimeout: function (id, func, timeout)
	{
		if (typeof(this.__timeouts) == 'undefined') this.__timeouts = new Array();
		if (typeof(this.__timeouts[id]) != 'undefined' && this.__timeouts[id] != null) this.clearTimeout(id);
		this.__timeouts[id] = setTimeout(func, timeout);
	},
	
	clearTimeout: function (id)
	{
		clearTimeout(this.__timeouts[id]);
		this.__timeouts[id] = null;
	},
	
	setInterval: function (id, func, interval)
	{
		if (typeof(this.__intervals) == 'undefined') this.__intervals = new Array();
		if (typeof(this.__intervals[id]) != 'undefined' && this.__intervals[id] != null) this.clearInterval(id);
		this.__intervals[id] = setInterval(func, interval);
	},
	
	clearInterval: function (id)
	{
		clearTimeout(this.__intervals[id]);
		this.__intervals[id] = null;
	}
};

fw.createClass = function (params)
{
	var c = params.init;
	fw.extendClass(c, params);
	
/*
	for (var i in params)
	{
		if (typeof(params[i]) == 'function')
		{
			c.prototype[i] = params[i];
		}
		else
		{
			c[i] = params[i];
		}
	}
	
	for (var i in mrj.__classPrototype)
	{
		if (typeof(mrj.__classPrototype[i]) == 'function')
		{
			c.prototype[i] = mrj.__classPrototype[i];
		}
		else
		{
			c[i] = mrj.__classPrototype[i];
		}
	}

/*	
	c.prototype.createEvent = function (eventId, func)
	{
		return mrj.createEvent(this, eventId, func);
	}

	c.prototype.invokeEvent = function (eventId, params)
	{
		return mrj.invokeEvent(this, eventId, params);
	}
	
	c.prototype.isEventDefined = function (eventId)
	{
		return mrj.isEventDefined(this, eventId);
	}
	
	c.prototype.argExists = function (id)
	{
		debug.walk(this.argv);
	}
	
	c.prototype.destroy = function ()
	{
		if (this.__destroy != undefined) this.__destroy();
	}
	
	
	c.prototype.getPlaceHolder = function ()
	{
		mrj.getPlaceHolder(this);
	}
	
	c.prototype.setTimeout = function (id, func, timeout)
	{
		mrj.setTimeout(this, id, func, timeout);
	}

	c.prototype.clearTimeout = function (id)
	{
		mrj.clearTimeout(this, id);
	}

	c.prototype.setInterval = function (id, func, interval)
	{
		mrj.setInterval(this, id, func, interval);
	}

	c.prototype.clearInterval = function (id)
	{
		mrj.clearInterval(this, id);
	}
*/
	return c;
}

fw.element = {
	defaults: new Object(),

	getCurrentStyle: function ()
	{
		var s;
		
		if (document.defaultView && document.defaultView.getComputedStyle)
		{
			s = document.defaultView.getComputedStyle(this, "");
		}
		else if (this.currentStyle)
		{
			s = this.currentStyle;
		}
	
		return s;
	},

	show: function ()
	{
		this.style.display = (typeof(this.defaults.display) != 'undefined' ? this.defaults.display : '');
	},
	
	hide: function ()
	{
		if (this.style.display == 'none') return false;
		this.defaults.display = this.style.display;
		this.style.display = 'none';
		
		return true;
	},
	
	getWidth: function (renderedSize)
	{
		var w;
		if (typeof(renderedSize) == 'undefined') renderedSize = false;
		
		if (renderedSize == true)
		{
			w = this.offsetWidth;
		}
		else
		{
			var s = this.getCurrentStyle();
			w = parseInt(s.width);
		}
		
		return w;
	},
	
	getHeight: function (renderedSize)
	{
		var h;
		if (typeof(renderedSize) == 'undefined') renderedSize = false;
		
		if (renderedSize == true)
		{
			h = this.offsetHeight;
		}
		else
		{
			var s = this.getCurrentStyle();
			h = parseInt(s.height);
		}
		
		return h;
	},
	
	getSize: function (renderedSize)
	{
		var w, h;
		if (typeof(renderedSize) == 'undefined') renderedSize = false;
		
		if (renderedSize == true)
		{
			w = this.offsetWidth;
			h = this.offsetHeight;
		}
		else
		{
			var s = this.getCurrentStyle();
			w = parseInt(s.width);
			h = parseInt(s.height);
		}
		
		return { width: w, height: h };
	},
	
	getPos: function (offsetX, offsetY)
	{
		if (typeof(offsetX) == 'undefined') offsetX = 0;
		if (typeof(offsetY) == 'undefined') offsetY = 0;
		
		var left = offsetX;
		var top = offsetY;
	
		var curElement = this;
		while (curElement != null)
		{
			left += curElement.offsetLeft + curElement.scrollLeft;
			top += curElement.offsetTop - curElement.scrollTop;
			curElement = curElement.offsetParent;
		}
		
		return { left: left, top: top };
	},

	setTop: function (top)
	{
		this.style.top = parseInt_wd(top) + 'px';	
	},

	setLeft: function (left)
	{
		this.style.left = parseInt_wd(left) + 'px';
	},
	
	setPos: function (left, top)
	{
		if (typeof(left) == 'object')
		{
			top = left.top;
			left = left.left;
		}
		
		this.style.left = parseInt_wd(left) + 'px';
		this.style.top = parseInt_wd(top) + 'px';	
	},
	
	setSize: function (width, height)
	{
		if (typeof(width) == 'object')
		{
			height = width.height;
			width = width.width;
		}
		
		this.style.width = parseInt_wd(width) + 'px';
		this.style.height = parseInt_wd(height) + 'px';
	},
	
	setScrollH: function (h)
	{
		this.scrollLeft = h;
	},

	setScrollV: function (v)
	{
		this.scrollTop = v;
	},
	
	getScrollH: function ()
	{
		return this.scrollLeft;	
	},

	getScrollV: function ()
	{
		return this.scrollTop;	
	},
	
	setContent: function (content, append)
	{
		this.innerHTML = (typeof(append) != 'undefined' && append == true ? this.innerHTML : '') + content;	
	},
	
	disableSelection: function ()
	{
		var e = this;
		
		if (typeof(e.onselectstart) != undefined) // IE
		{
			e.onselectstart = function () { return false; }
		}
		else if (typeof(e.style.MozUserSelect) != undefined) // Firefox
		{
			e.style.MozUserSelect = 'none';
		}
		else // Other browsers
		{
			e.onmousedown = function () { return false; }
		}
	
		e.style.cursor = 'default';
	},
	
	zIndex: function (z)
	{
		if (z != undefined)
		{
			this.style.zIndex = z;
		}
		else
		{
			var s = this.getCurrentStyle();
			z = s.zIndex;
		}
		
		return z;
	},
	
	fitTo: function (e)
	{
		e = $(e);	
		this.style.position = 'absolute';
		this.setSize(this.calcSize(e.getSize(true)));
		this.setPos(e.getPos());
	},

	calcWidth: function (width, style)
	{
		var s = (typeof(style) == 'undefined' ? this.getCurrentStyle() : style);
		var w = 0;
		
		if (s.paddingLeftWidth > 0) w += s.paddingLeftWidth;
		if (s.paddingRightWidth > 0) w += s.paddingRightWidth;
		if (s.borderLeftWidth > 0) w += s.borderLeftWidth;
		if (s.borderRightWidth > 0) w += s.borderRightWidth;
		
		return width - w;
	},
	
	calcHeight: function (height, style)
	{
		var s = (typeof(style) == 'undefined' ? this.getCurrentStyle() : style);
		var h = 0;
		
		if (s.paddingTopWidth > 0) h += s.paddingTopWidth;
		if (s.paddingBottomWidth > 0) h += s.paddingBottomWidth;
		if (s.borderTopWidth > 0) h += s.borderTopWidth;
		if (s.borderBottomWidth > 0) h += s.borderBottomWidth;
		
		return height - h;
	},

	calcSize: function (width, height, style)
	{
		if (typeof(width) == 'object')
		{
			height = width.height;
			width = width.width;
			style = height;
		}

		var s = (typeof(style) == 'undefined' ? this.getCurrentStyle() : style);

		var w = 0;
		var h = 0;
		
		if (s.paddingLeftWidth > 0) w += s.paddingLeftWidth;
		if (s.paddingRightWidth > 0) w += s.paddingRightWidth;
		if (s.borderLeftWidth > 0) w += s.borderLeftWidth;
		if (s.borderRightWidth > 0) w += s.borderRightWidth;
		
		if (s.paddingTopWidth > 0) h += s.paddingTopWidth;
		if (s.paddingBottomWidth > 0) h += s.paddingBottomWidth;
		if (s.borderTopWidth > 0) h += s.borderTopWidth;
		if (s.borderBottomWidth > 0) h += s.borderBottomWidth;
		
		return { width: width - w, height: height - h };
	}
};


function $(id, createElement)
{
	var e = null;
	var type = typeof(id);
	
	if (typeof(createElement) != 'undefined' && createElement != null)
	{
		e = document.createElement(createElement);
		e.id = id;
	}
	else
	{
		if (type == 'string')
		{
			e = document.getElementById(id);
		}
		else if (type == 'object')
		{
			e = id;
		}
	}
	
	if (typeof(e.__isElement) == 'undefined')
	{
		e.__isElement = true;
		
		fw.extend(e, fw.element);
		fw.extend(e, fw.events);
		fw.extend(e, fw.timing);
	}
	
	return e;
}

function parseInt_wd(obj, defaultVal)
{
	if (typeof(defaultVal) == 'undefined')
		defaultVal = 0;
		
	var val = parseInt(obj);
	if (isNaN(val) || val == null || val == undefined || val == '')
		val = defaultVal;
		
	return val;
}

fw.extend = function (dst, src)
{
	for (var i in src)
	{
		dst[i] = src[i];
	}
}

fw.extendClass = function (dst, src)
{
	for (var i in src)
	{
		if (typeof(src[i]) == 'function')
		{
			dst.prototype[i] = src[i];
		}
		else
		{
			dst[i] = src[i];
		}
	}
}

 

fw.element.fade = function (opacity, speed, params)
{
	if (typeof(params) == 'undefined') params = {};
	var e = this;
	var o = e.getOpacity();
	var step = (opacity < o ? -1 : 1) * speed; 
	
	this.setInterval(
		'EFFECT:fade',
		function ()
		{
			o += step;
			if ((step < 0 && o <= opacity) || (step > 0 && o >= opacity))
			{
				o = opacity;
				e.clearInterval('EFFECT:fade');
				
				if (typeof(params.onComplete) != 'undefined') params.onComplete();
			}
			
			e.setOpacity(o);
		}, 
		10
	);
}

fw.element.ease = function (param, to, speed)
{
	var intId = 'EFFECT:ease:' + param;
	var curVal = 0;
	
	if (param == 'width') curVal = this.getWidth();
	else if (param == 'height') curVal = this.getHeight();
	else curVal = this[param];
	
	var e = this;
	var step = (param < curVal ? -1 : 1) * speed; 
	
	this.setInterval(
		intId,
		function ()
		{
			
		},
		10
	);
}

fw.element.clearFade = function ()
{
	this.clearInterval('EFFECT:fade');
}

fw.element.setOpacity = function (opacity)
{
	if (fw.browser == 'ie')
	{
		this.style.filter = 'alpha(opacity=' + opacity + ')';
	}
	else
	{
		this.style.MozOpacity = opacity / 100;
	}
}

fw.element.getOpacity = function ()
{
	var opacity;
	
	if (fw.browser == 'ie')
	{
		if (this.filters[0] == undefined)
			return 100;
		
		opacity = parseInt_wd(this.filters[0].opacity, 100)
	}
	else
	{
		if (this.style.MozOpacity == '')
			opacity = 1;
		else
			opacity = this.style.MozOpacity;
			
		opacity *= 100;
	}
	
	return opacity;
}


fw.json = {
	decode: function (str)
	{
		eval('var json = ' + str + ';');
		return json;
	},
	
	encode: function (obj)
	{
		var type;
		
		if (typeof(obj) == 'object')
		{
			if (typeof(obj.length) != 'undefined')
			{
				return this.arrayToString(obj);
			}
			else
			{
				return this.objToString(obj);
			}
		}
		else
		{
			return false;
		}
		
	},
	
	arrayToString: function (obj)
	{
		var value;
		var ret = '';
		
		for (var i=0; i<obj.length; i++)
		{
			value = obj[i];	
			ret += (ret != '' ? ',' : '') + this.generateValue(value);
		}
		
		return '[' + ret + ']';
	},
	
	objToString: function (obj)
	{
		var value;
		var ret = '';
		
		for (var i in obj)
		{
			value = obj[i];			
			ret += (ret != '' ? ',' : '') + this.generatePair(i, value);
		}

		return '{' + ret + '}';
	},
	
	generatePair: function (name, value)
	{
		var valueStr = this.generateValue(value);
		return '"' + name + '":' + valueStr;
	},
	
	generateValue: function (value)
	{
		var type = typeof(value);
		
		switch (type)
		{
			case 'string':
				return '"' + value + '"';
				
			case 'number':
				return value;
				
			case 'boolean':
				return (value ? 'true' : 'false');
				
			case 'object':
				return this.toString(value);
		}
		
		return false;
	}
	
	
};


fw.net = new Object();

fw.net.Ajax = fw.createClass(
{
	init: function (params)
	{
		this.httpRequest = null;
		this.method = 'GET';
		this.postData = '';
		
		fw.extend(this, params);
		
		try
		{
			// Firefox, Opera 8.0+, Safari
			this.httpRequest = new XMLHttpRequest();
		}
		catch (e)
		{
			// Internet Explorer
			try
			{
				this.httpRequest = new ActiveXObject('Msxml2.XMLHTTP');
			}
			catch (e)
			{
				try
			  	{
					this.httpRequest = new ActiveXObject('Microsoft.XMLHTTP');
				}
				catch (e)
		  		{
		  			alert('Your browser does not support AJAX!');
		  			return false;
		  		}
			}
		}

	},

	request: function (url, params)
	{
		var __this = this;
		if (params != undefined) fw.extend(this, params);

		this.httpRequest.onreadystatechange = null;
		this.httpRequest.abort();

		this.httpRequest.onreadystatechange = function ()
		{
			__this.__onReceiveData();
		}
		
		if (typeof(url) == 'undefined' || url == null) url = this.url;
		
		this.httpRequest.open(this.method, url, true);
		this.httpRequest.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
		if (this.method == 'post')
		{
			this.httpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;utf-8');
			this.httpRequest.setRequestHeader('Content-length', this.postData.length);
			this.httpRequest.setRequestHeader('Connection', 'close');
		}

		if (typeof(this.header) != 'undefined')
		{
			for (var i in this.header)
			{
				if (typeof(this.header[i]) == 'string')
					this.httpRequest.setRequestHeader(i, this.header[i]);
			}
		}
		
		this.httpRequest.send((this.method == 'post' ? this.postData : null));
	},
	
	getJSON: function (decode)
	{
		if (typeof(decode) == 'undefined') decode = true;
		var pos = 0;
		var json = new Array();
		
		while ((pos = this.responseText.indexOf('[JSON]', pos)) > -1)
		{
			if ((endPos = this.responseText.indexOf('[/JSON]', pos)) > -1)
			{
				json.push(this.responseText.substr(pos + 6, endPos - pos - 6));
				pos = endPos;
			} 
		}

		if (decode)
		{
			for (var i=0; i<json.length; i++)
			{
				json[i] = mrj.json.parse(json[i]);
			}
		}
		
		if (json.length == 1) return json[0];
		if (json.length == 0) return null;
		return json;
	},
	
	parseResponse: function ()
	{
		var rt = this.responseText;
		
		this.responseTags = this.getSpecialTags(rt);

		if (typeof(this.responseTags['REDIRECT']) != 'undefined')
		{
			top.location.href = this.responseTags['REDIRECT']['default'].content;
		}

		if (typeof(this.responseTags['EXEC']) != 'undefined')
		{
			
			var execTags = this.responseTags['EXEC'];

			for (var i=0; i<execTags.length; i++)
			{
				var e = execTags[i];				
				eval('var fp = ' + e.func);
				if (typeof(fp) != 'undefined') fp(e.obj);
			}
		}
	},
	
	getSpecialTags: function (code)
	{
		var pos = 0;					// current code position
		var tags = new Array();			// tag storage
		var content, epos, tagParams, tagName, cstart, cend, id;
		
		while ((pos = code.indexOf('[!!', pos)) > -1)
		{
			epos = code.indexOf('!!]', pos);
			tagParams = code.substring(pos + 3, epos).split(':');
			tagName = tagParams[0];
			id = tagParams[1];
			if (typeof(id) == 'undefined' || id == '') id = 'default'; 
			
			cstart = epos + 3;
			cend = code.indexOf('[!!/' + tagParams[0] + '!!]', cstart);
			content = code.substring(cstart, cend);

			if (typeof(tags[tagName]) == 'undefined') tags[tagName] = new Array();

			if (tagName == 'JSON' || tagName == 'EXEC') content = fw.json.decode(content);

			if (tagName == 'JSON')
			{
				tags['JSON'][id] = content;
			}
			else if (tagName == 'EXEC')
			{
				tags['EXEC'].push({ func: id, obj: content });
			}
			else if (tagName == 'REDIRECT')
			{
				top.location.href = content;
			}
			else
			{
				tags[tagName][id] = {
					id: id, 
					name: tagName,
					params: tagName, 
					content: content
				};
			} 

			pos = cend + 7 + tagParams[0].length;
		}
		return tags;
	},
	
	parseHeadTags: function (content, tagName)
	{
		var head = document.getElementsByTagName('head');
		var tagNameLen = tagName.length;
		var pos = 0;
		
		while ((pos = content.indexOf('<' + tagName, pos)) > -1)
		{

			var tagEnd = content.indexOf('>', pos);
			var codeBegin = tagEnd + 1;
			
			var newElement = document.createElement(tagName);
			var endTagPos = content.indexOf('</' + tagName + '>', pos);
			if (endTagPos > -1)
			{
				newElement.innerHTML = content.substr(codeBegin, endTagPos - codeBegin);
			}

			var attribStr = content.substr(pos + tagNameLen + 1, tagEnd - pos - tagNameLen - 1);
			var attribs = attribStr.match(/ ([^=]+)="[^"]*"/g);

			if (attribs != null)
			{
				for (var i=0; i<attribs.length; i++)
				{
					var segs = attribs[i].split('=');
					newElement[segs[0].substr(1)] = segs[1].substr(1, segs[1].length - 2);
				}
				
				/*
				if (tagName == 'script' && newElement['src'] != '')
				{
					this.setInterval(
						'checkScript',
						function ()
						{
							//if (mrj.loadedScripts['950960302'] == true) alert('LOADED!');
						},
						2000
					);
				}*/ 
			} 

			head[0].appendChild(newElement);
				
			pos++;
		}
	},
	
	__onReceiveData: function ()
	{
		var httpReq = this.httpRequest;

		if (httpReq.readyState == 4)
		{
			this.responseText = httpReq.responseText;
			this.status = httpReq.status;
			
			if (httpReq.status == 200)
			{
				this.parseResponse();
				//setTimeout(function () { mrj.__onPageLoaded(); }, 500);
			
				if (typeof(this.execute) == 'undefined')
				{
				//	g.invokeEvent('onReceiveData', g);
				}
				else
				{
					this.execute();
				}
			}
			else
			{
				this.invokeEvent('onError', this);
			}
		}
	}
});



var ajaxLoader = new fw.net.Ajax();
var menu;
var lastPath = null;

setInterval(checkPath, 50);

function checkPath()
{
	var hashPos = top.location.href.indexOf('#');
	if (hashPos > -1)
	{
		var newPath = top.location.href.substr(hashPos + 1);
		if (newPath != lastPath)
		{
			loadPage(newPath);
		}
	}
}

var lastMenuButton = null;
var lastSectionId = null;

function loadPage(path)
{
	if (path == '' || path == '/') path = '/home';
	
	lastPath = path;
	top.location.href = '/#' + path;
	
	var segs = path.split('/');
	var sectionId = (segs[0] == '' ? segs[1] : segs[0]);
	
	if (lastMenuButton != null)
	{
		var mb = lastMenuButton;
		var link = mb.getElementsByTagName('a')[0];
		var lmbPath = '/' + lastSectionId;
		mb.setContent('<a href="' + lmbPath + '" onclick="loadPage(\'' + lmbPath + '\'); return false">' + link.innerHTML + '</a>');
	}
	
	var mb = $('mb_' + sectionId);
	var h = mb.innerHTML;
	mb.setContent('<div class="menuBar-item_active menuBar-item-middle_active"><div class="menuBar-item-left_active"></div>' + h + '<div class="menuBar-item-right_active"></div></div>');
	lastMenuButton = mb;
	lastSectionId = sectionId;
	
	ajaxLoader.request(
		path,
		{
			execute: function ()
			{
				$('content').setContent(this.responseTags['CONTENT']['default'].content);
				var rootNode = this.responseTags['JSON']['menu'];
				var imageSetId = this.responseTags['JSON']['imageSetId'];
				
				if (typeof(rootNode.nodes) == 'undefined')
				{
					
					hideSideMenu();
				}
				else
				{
					showSideMenu();
					renderMenu(rootNode);
					
				}
				
				initLightbox();
			}
		}
	);
}

function hideSideMenu()
{
	$('sideMenu').hide();
	$('sideMenuTop').hide();
	$('content').style.width = '750px';
}

function showSideMenu()
{
	$('sideMenu').show();
	$('sideMenuTop').show();
	$('content').style.width = '550px';
}

function setTitle(breadcrumbs)
{
	var bc = '';
	var winTitle = breadcrumbs[0].title;
	for (var i=1; i<breadcrumbs.length; i++)
	{
		bc += ' &raquo; ' + breadcrumbs[i].title;
		winTitle += ' › ' + breadcrumbs[i].title;
	}

	document.title = 'Ferguson Brown Ltd - ' + winTitle;
		
	$('sectionName').setContent(breadcrumbs[0].title);
	$('breadcrumbs').setContent(bc);
}

function renderMenu(node)
{
	var menu = $('sideMenuItems');
	
	var path = '/' + node.id;
	var h = '';
	
	if (typeof(node.hideIndex) == 'undefined')
		h += '<li>' + menuLink(path, node.title) + '</li>';

	if (typeof(node.nodes) != 'undefined')
	{
		h += renderSubMenus(path, node.nodes, 0);
	}

	menu.setContent('<ul>' + h + '</ul>');
}

function renderSubMenus(path, nodes, level)
{
	var h = '';
	for (var i in nodes)
	{
		var curPath = path + '/' + i;
		var n = nodes[i];
		h += '<li>' + menuLink(curPath, n.title);
		if (typeof(n.nodes) != 'undefined')
		{
			h += '<ol>' + renderSubMenus(curPath, n.nodes, level + 1) + '</ol>';
		}
	}
	
	return h;
}

function menuLink(path, text)
{
	return '<a href="' + path + '" onclick="loadPage(\'' + path + '\'); return false">' + text + '</a>';
}


/*
	Lightbox JS: Fullsize Image Overlays 
	by Lokesh Dhakar - http://www.huddletogether.com

	For more information on this script, visit:
	http://huddletogether.com/projects/lightbox/

	Licensed under the Creative Commons Attribution 2.5 License - http://creativecommons.org/licenses/by/2.5/
	(basically, do anything you want, just leave my name and link)
	
	Table of Contents
	-----------------
	Configuration
	
	Functions
	- getPageScroll()
	- getPageSize()
	- pause()
	- getKey()
	- listenKey()
	- showLightbox()
	- hideLightbox()
	- initLightbox()
	- addLoadEvent()
	
	Function Calls
	- addLoadEvent(initLightbox)

*/



//
// Configuration
//

// If you would like to use a custom loading image or close button reference them in the next two lines.
var loadingImage = '/images/lightbox/loading.gif';		
var closeButton = '/images/lightbox/close.gif';		





//
// getPageScroll()
// Returns array with x,y page scroll values.
// Core code from - quirksmode.org
//
function getPageScroll(){

	var yScroll;

	if (self.pageYOffset) {
		yScroll = self.pageYOffset;
	} else if (document.documentElement && document.documentElement.scrollTop){	 // Explorer 6 Strict
		yScroll = document.documentElement.scrollTop;
	} else if (document.body) {// all other Explorers
		yScroll = document.body.scrollTop;
	}

	arrayPageScroll = new Array('',yScroll) 
	return arrayPageScroll;
}



//
// getPageSize()
// Returns array with page width, height and window width, height
// Core code from - quirksmode.org
// Edit for Firefox by pHaez
//
function getPageSize(){
	
	var xScroll, yScroll;
	
	if (window.innerHeight && window.scrollMaxY) {	
		xScroll = document.body.scrollWidth;
		yScroll = window.innerHeight + window.scrollMaxY;
	} else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
		xScroll = document.body.scrollWidth;
		yScroll = document.body.scrollHeight;
	} else { // Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari
		xScroll = document.body.offsetWidth;
		yScroll = document.body.offsetHeight;
	}
	
	var windowWidth, windowHeight;
	if (self.innerHeight) {	// all except Explorer
		windowWidth = self.innerWidth;
		windowHeight = self.innerHeight;
	} else if (document.documentElement && document.documentElement.clientHeight) { // Explorer 6 Strict Mode
		windowWidth = document.documentElement.clientWidth;
		windowHeight = document.documentElement.clientHeight;
	} else if (document.body) { // other Explorers
		windowWidth = document.body.clientWidth;
		windowHeight = document.body.clientHeight;
	}	
	
	// for small pages with total height less then height of the viewport
	if(yScroll < windowHeight){
		pageHeight = windowHeight;
	} else { 
		pageHeight = yScroll;
	}

	// for small pages with total width less then width of the viewport
	if(xScroll < windowWidth){	
		pageWidth = windowWidth;
	} else {
		pageWidth = xScroll;
	}


	arrayPageSize = new Array(pageWidth,pageHeight,windowWidth,windowHeight) 
	return arrayPageSize;
}


//
// pause(numberMillis)
// Pauses code execution for specified time. Uses busy code, not good.
// Code from http://www.faqts.com/knowledge_base/view.phtml/aid/1602
//
function pause(numberMillis) {
	var now = new Date();
	var exitTime = now.getTime() + numberMillis;
	while (true) {
		now = new Date();
		if (now.getTime() > exitTime)
			return;
	}
}

//
// getKey(key)
// Gets keycode. If 'x' is pressed then it hides the lightbox.
//

function getKey(e){
	if (e == null) { // ie
		keycode = event.keyCode;
	} else { // mozilla
		keycode = e.which;
	}
	key = String.fromCharCode(keycode).toLowerCase();
	
	if(key == 'x'){ hideLightbox(); }
}


//
// listenKey()
//
function listenKey () {	document.onkeypress = getKey; }
	

//
// showLightbox()
// Preloads images. Pleaces new image in lightbox then centers and displays.
//
function showLightbox(objLink)
{
	// prep objects
	var objOverlay = document.getElementById('overlay');
	var objLightbox = document.getElementById('lightbox');
	var objCaption = document.getElementById('lightboxCaption');
	var objImage = document.getElementById('lightboxImage');
	var objLoadingImage = document.getElementById('loadingImage');
	var objLightboxDetails = document.getElementById('lightboxDetails');

	
	var arrayPageSize = getPageSize();
	var arrayPageScroll = getPageScroll();

	// center loadingImage if it exists
	if (objLoadingImage) {
		objLoadingImage.style.top = (arrayPageScroll[1] + ((arrayPageSize[3] - 35 - objLoadingImage.height) / 2) + 'px');
		objLoadingImage.style.left = (((arrayPageSize[0] - 20 - objLoadingImage.width) / 2) + 'px');
		objLoadingImage.style.display = 'block';
	}

	// set height of Overlay to take up whole page and show
	objOverlay.style.height = (arrayPageSize[1] + 'px');
	objOverlay.style.display = 'block';

	// preload image
	imgPreload = new Image();

	imgPreload.onload=function(){
		objImage.src = objLink.href;

		// center lightbox and make sure that the top and left values are not negative
		// and the image placed outside the viewport
		var lightboxTop = arrayPageScroll[1] + ((arrayPageSize[3] - 35 - imgPreload.height) / 2);
		var lightboxLeft = ((arrayPageSize[0] - 20 - imgPreload.width) / 2);
		
		objLightbox.style.top = (lightboxTop < 0) ? "0px" : lightboxTop + "px";
		objLightbox.style.left = (lightboxLeft < 0) ? "0px" : lightboxLeft + "px";


		objLightboxDetails.style.width = imgPreload.width + 'px';
		
		if(objLink.getAttribute('title')){
			objCaption.style.display = 'block';
			//objCaption.style.width = imgPreload.width + 'px';
			objCaption.innerHTML = objLink.getAttribute('title');
		} else {
			objCaption.style.display = 'none';
		}
		
		// A small pause between the image loading and displaying is required with IE,
		// this prevents the previous image displaying for a short burst causing flicker.
		if (navigator.appVersion.indexOf("MSIE")!=-1){
			pause(250);
		} 

		if (objLoadingImage) {	objLoadingImage.style.display = 'none'; }

		// Hide select boxes as they will 'peek' through the image in IE
		selects = document.getElementsByTagName("select");
        for (i = 0; i != selects.length; i++) {
                selects[i].style.visibility = "hidden";
        }

	
		objLightbox.style.display = 'block';

		// After image is loaded, update the overlay height as the new image might have
		// increased the overall page height.
		arrayPageSize = getPageSize();
		objOverlay.style.height = (arrayPageSize[1] + 'px');
		
		// Check for 'x' keypress
		listenKey();

		return false;
	}

	imgPreload.src = objLink.href;
	
}





//
// hideLightbox()
//
function hideLightbox()
{
	// get objects
	objOverlay = document.getElementById('overlay');
	objLightbox = document.getElementById('lightbox');

	// hide lightbox and overlay
	objOverlay.style.display = 'none';
	objLightbox.style.display = 'none';

	// make select boxes visible
	selects = document.getElementsByTagName("select");
    for (i = 0; i != selects.length; i++) {
		selects[i].style.visibility = "visible";
	}

	// disable keypress listener
	document.onkeypress = '';
}




//
// initLightbox()
// Function runs on window load, going through link tags looking for rel="lightbox".
// These links receive onclick events that enable the lightbox display for their targets.
// The function also inserts html markup at the top of the page which will be used as a
// container for the overlay pattern and the inline image.
//
function initLightbox()
{
	
	if (!document.getElementsByTagName){ return; }
	var anchors = document.getElementsByTagName("a");

	// loop through all anchor tags
	for (var i=0; i<anchors.length; i++){
		var anchor = anchors[i];

		if (anchor.getAttribute("href") && (anchor.getAttribute("rel") == "lightbox")){
			anchor.onclick = function () {showLightbox(this); return false;}
		}
	}

	// the rest of this code inserts html at the top of the page that looks like this:
	//
	// <div id="overlay">
	//		<a href="#" onclick="hideLightbox(); return false;"><img id="loadingImage" /></a>
	//	</div>
	// <div id="lightbox">
	//		<a href="#" onclick="hideLightbox(); return false;" title="Click anywhere to close image">
	//			<img id="closeButton" />		
	//			<img id="lightboxImage" />
	//		</a>
	//		<div id="lightboxDetails">
	//			<div id="lightboxCaption"></div>
	//			<div id="keyboardMsg"></div>
	//		</div>
	// </div>
	
	var objBody = document.getElementsByTagName("body").item(0);
	
	// create overlay div and hardcode some functional styles (aesthetic styles are in CSS file)
	var objOverlay = document.createElement("div");
	objOverlay.setAttribute('id','overlay');
	objOverlay.onclick = function () {hideLightbox(); return false;}
	objOverlay.style.display = 'none';
	objOverlay.style.position = 'absolute';
	objOverlay.style.top = '0';
	objOverlay.style.left = '0';
	objOverlay.style.zIndex = '90';
 	objOverlay.style.width = '100%';
	objBody.insertBefore(objOverlay, objBody.firstChild);
	
	var arrayPageSize = getPageSize();
	var arrayPageScroll = getPageScroll();

	// preload and create loader image
	var imgPreloader = new Image();
	
	// if loader image found, create link to hide lightbox and create loadingimage
	imgPreloader.onload=function(){

		var objLoadingImageLink = document.createElement("a");
		objLoadingImageLink.setAttribute('href','#');
		objLoadingImageLink.onclick = function () {hideLightbox(); return false;}
		objOverlay.appendChild(objLoadingImageLink);
		
		var objLoadingImage = document.createElement("img");
		objLoadingImage.src = loadingImage;
		objLoadingImage.setAttribute('id','loadingImage');
		objLoadingImage.style.position = 'absolute';
		objLoadingImage.style.zIndex = '150';
		objLoadingImageLink.appendChild(objLoadingImage);

		imgPreloader.onload=function(){};	//	clear onLoad, as IE will flip out w/animated gifs

		return false;
	}

	imgPreloader.src = loadingImage;

	// create lightbox div, same note about styles as above
	var objLightbox = document.createElement("div");
	objLightbox.setAttribute('id','lightbox');
	objLightbox.style.display = 'none';
	objLightbox.style.position = 'absolute';
	objLightbox.style.zIndex = '100';	
	objBody.insertBefore(objLightbox, objOverlay.nextSibling);
	
	// create link
	var objLink = document.createElement("a");
	objLink.setAttribute('href','#');
	objLink.setAttribute('title','Click to close');
	objLink.onclick = function () {hideLightbox(); return false;}
	objLightbox.appendChild(objLink);

	// preload and create close button image
	var imgPreloadCloseButton = new Image();

	// if close button image found, 
	imgPreloadCloseButton.onload=function(){

		var objCloseButton = document.createElement("img");
		objCloseButton.src = closeButton;
		objCloseButton.setAttribute('id','closeButton');
		objCloseButton.style.position = 'absolute';
		objCloseButton.style.zIndex = '200';
		objLink.appendChild(objCloseButton);

		return false;
	}

	imgPreloadCloseButton.src = closeButton;

	// create image
	var objImage = document.createElement("img");
	objImage.setAttribute('id','lightboxImage');
	objLink.appendChild(objImage);
	
	// create details div, a container for the caption and keyboard message
	var objLightboxDetails = document.createElement("div");
	objLightboxDetails.setAttribute('id','lightboxDetails');
	objLightbox.appendChild(objLightboxDetails);

	// create caption
	var objCaption = document.createElement("div");
	objCaption.setAttribute('id','lightboxCaption');
	objCaption.style.display = 'none';
	objLightboxDetails.appendChild(objCaption);

	// create keyboard message
	var objKeyboardMsg = document.createElement("div");
	objKeyboardMsg.setAttribute('id','keyboardMsg');
	objKeyboardMsg.innerHTML = 'press <a href="#" onclick="hideLightbox(); return false;"><kbd>x</kbd></a> to close';
	objLightboxDetails.appendChild(objKeyboardMsg);


}




//
// addLoadEvent()
// Adds event to window.onload without overwriting currently assigned onload functions.
// Function found at Simon Willison's weblog - http://simon.incutio.com/
//
function addLoadEvent(func)
{	
	var oldonload = window.onload;
	if (typeof window.onload != 'function'){
    	window.onload = func;
	} else {
		window.onload = function(){
		oldonload();
		func();
		}
	}

}



addLoadEvent(initLightbox);	// run initLightbox onLoad

