function iGal(htmlElement)
{
	var self = this;
	var instanceName;
	var basePath = "";
	var minImageHeight;
	var maxImageWidth;

	this.thumbsWidth = 80;
	this.thumbsHeight = 80;
	this.inElement = null;
	this.lastSetId = -1;
	this.contents = null;
	this.isRendered = false;
	this.currentSet = null;
	this.currentImg = null;
	this.lastImg = null;
	this.attachToSet = [];
	this.playing = false;
	this.isNavBarShown = false;
	this.enableOSD = false;
	/*
	 * Possible layouts: "vertical", "horizontal" [TODO "grid"].
	 */
	this.layout = "vertical";
	
	if (!assignOutput()) {
		return false;
	}
	/*
	 * First entry
	 */
	this.addSet();
	this.indentSet();
	
	this.setGalName = function(newInstanceName)
	{
		instanceName = newInstanceName;
	};

	this.getGalName = function() {
		return instanceName;
	};
	
	this.setBasePath = function(path)
	{
		if (self.isRendered) {
			return;
		}
		if (typeof path == "undefined") {
			path = "";
		}
		basePath = path;
	};

	this.getBasePath = function() { return basePath; };
	
	this.getDropDown = function(id)
	{
		if (typeof id == "undefined" || isNaN(parseInt(id))) {
			id = 0;
		}
		var options = getDropDownCycle(self.contents, id);
		var result = "<select onchange='"+ instanceName +
			".showSet(this.options[this.selectedIndex].value)'>\n";
		result += options;
		result += "</select>";
		if (options === "") {
			return "";
		} else {
			return result;
		}
	};
	
	function getDropDownCycle(galSet, id, depth)
	{
		if (typeof depth == "undefined") {
			depth = 0;
		}
		var indent = "";
		for (var j=0; j<depth; ++j) {
			indent += "&#160;&#160;&#160;&#160;";
		}
		var result = "";
		for (var i in galSet.subset) {
			var sub = galSet.subset[i];
			result += "<option value='"+ sub.id +"'";
			if (sub.id == id) {
				result += " selected='selected'";
			}
			result += ">" + indent + sub.name + "</option>\n";
			result += getDropDownCycle(sub, id, depth+1);
		}
		return result;
	}
	
	/**
	 * Check if an element provided to draw the gallery
	 */
	function assignOutput()
	{
		if (typeof htmlElement == "undefined") {
			alert(iGal_i18n.program_error_8);
			return false;
		}
		var elem = document.getElementById(htmlElement);
		if (!elem) {
			alert(iGal_i18n.program_error_8);
			return false;
		}
		self.inElement = elem;
		return true;
	}
	
	/**
	 * Redraw the navigation area
	 */
	this.reloadNav = function()
	{
		document.getElementById("iGal"+ instanceName +"Prev").disabled =
			(self.checkPrevImage() !== false) ? false : "disabled";
		document.getElementById ("iGal"+ instanceName +"Next").disabled =
			(self.checkNextImage() !== false) ? false : "disabled";
	};
	
	/**
	 * Clear the current set visualization
	 */
	this.clearSet = function ()
	{
		document.getElementById("iGal"+ instanceName +"InfoTitle").innerHTML = "";
		document.getElementById("iGal"+ instanceName +"Images").innerHTML = "";
		document.getElementById("iGal"+ instanceName +"Images").className = "";
		var cImgPlace =	document.getElementById("iGal"+ instanceName +"Current");
		cImgPlace.style.height = cImgPlace.offsetHeight + "px";
		cImgPlace.innerHTML = "";
		self.currentImg = null;
		self.currentSet = null;
	};
	
	this.attachSet = function(newSet, toSet)
	{
		toSet.subset[toSet.subset.length] = newSet;
		++self.lastSetId;
	};
	
	this.debug = function(outElem)
	{
		if (typeof outElem !== "undefined") {
			outElem.innerHTML = debugContents();
			outElem.style.display = "block";
		} else {
			alert (debugContents());
		}
	};
	
	function debugContents( galSet, depth)
	{
		if (typeof galSet == "undefined") {
			galSet = self.contents;
		}
		if (typeof depth == "undefined") {
			depth = 0;
		}
		var indent = "";
		for (var j=0; j<=depth; ++j) {
			indent += "&#183; ";
		}
		var outHtml = "";
		for (var i in galSet.subset) {
			var sub = galSet.subset[i];
			if (sub.name) {
				outHtml += "<ul><li>" + sub.name;
			}
			if (sub.imgs.length > 0) {
				outHtml += "<ul>";
			}
			for (var k in sub.imgs) {
				var title = sub.imgs[k].title || sub.imgs[k].src;
				outHtml += "<li><a href='" + self.getBasePath() + sub.imgs[k].src + "'>" + title + "</a> </li> ";
			}
			if (sub.imgs.length > 0) {
				outHtml += "</ul>";
			}
			outHtml += debugContents(sub, depth+1);
			if (sub.name) {
				outHtml += "</li></ul>";
			}
		}
		return outHtml;
	}
	
	this.getSet = function(setId)
	{
		if (typeof setId == "undefined" && self.currentSet !== null) {
			return self.getSetById(self.currentSet);
		} else if (typeof setId != "undefined") {
			return self.getSetById(setId);
		} else {
			return false;
		}
	};
	
	this.getSetById = function(id)
	{
		if (id === 0) {
			return self.contents;
		}
		var theSet = getSetByIdCycle(id, self.contents);
		if (theSet === false) {
			//alert("Error: No set was found with the requested id #" + id + ".");
			return false;
		} else {
			return theSet;
		}
	};
	
	function getSetByIdCycle(id, galSet)
	{
		var theSet = false;
		for (var i in galSet.subset) {
			var sub = galSet.subset[i];
			if (sub.id == id) {
				return sub;
			} else if (sub.subset.length > 0) {
				theSet = getSetByIdCycle(id, sub);
				if (theSet !== false) {
					return theSet;
				}
			}
		}
		return false;
	}
	
	this.checkPrevImage = function(setId)
	{
		var cSet = self.getSet(setId);
		if (cSet === false) {
			return false;
		}
		var cImg;
		if (typeof setId == "undefined" && self.currentImg !== null) {
			cImg = self.currentImg-1;
		} else if (cSet.imgs.length > 0) {
			cImg = cSet.imgs.length-1;
		}
		if (cImg !== null && cImg >= 0 && typeof cSet.imgs[cImg] != "undefined") {
			return true;
		}
		if ( setId != "undefined" || cSet.imgs.length === 0) {
			return self.checkPrevImage (cSet.id-1);
		}
		return false;
	};
	
	this.checkNextImage = function(setId)
	{
	 	var cSet = self.getSet(setId);
		if (cSet === false) {
			return false;
		}
		var cImg;
		if (typeof setId == "undefined" && self.currentImg !== null) {
			cImg = self.currentImg + 1;
		} else if (cSet.imgs.length > 0) {
			cImg = 0;
		}
		if (cImg !== null && cImg >= 0 && typeof cSet.imgs[cImg] != "undefined") {
			return true;
		}
		if (setId != "undefined" || cSet.imgs.length === 0) {
			return self.checkNextImage (cSet.id+1);
		}
		return false;
	};
	
	this.setMinImageHeight = function(height)
	{
		if (isNaN(parseInt(height, 10)) || self.isRendered) {
			return false;
		}
		if (typeof minImageHeight == "undefined" || height < minImageHeight) {
			minImageHeight = parseInt(height, 10);
		}
		return true;
	};
	
	this.getThumbsHeight = function()
	{
		if (self.layout == "vertical") {
			if (minImageHeight < 300) {
				return 300;
			} else {
				return minImageHeight - 10;
			}
		} else if (self.layout == "horizontal") {
			return self.thumbsHeight + 25;
		}
	};
	
	this.getThumbsWidth = function() 
	{
		if (self.layout == "vertical") {
			return self.thumbsWidth + 20;
		} else {
			return self.getGalWidth() - 15;
		}
	};
	
	this.setMaxImageWidth = function(width)
	{
		if (isNaN(parseInt(width, 10)) || self.isRendered) {
			return false;
		}
		if (typeof maxImageWidth == "undefined" || width > maxImageWidth) {
			maxImageWidth = parseInt(width, 10);
		}
		return true;
	};
	
	this.getGalWidth = function()
	{
		if (self.layout == "vertical") {
			return(maxImageWidth + self.thumbsWidth + 50);
		} else if (self.layout == "horizontal") {
			return(maxImageWidth + 5);
		} else {
			return(maxImageWidth + 5);
		}
	};
	
	/**
	 * Common layout preparations
	 */
	var galName, galHeader, galNav, galImages, galCurrent, galInfo, galNavFix;
	function prepareLayout()
	{
		galName = self.getGalName();
		
		galHeader = document.createElement("div");
		galHeader.id = "iGal"+ galName +"Header";
		galHeader.className = "iGalHeader";
		
		galNav = document.createElement("div");
		galNav.id = "iGal"+ galName +"Nav";
		galNav.className = "iGalNav";
		
		galImages = document.createElement("div");
		galImages.id = "iGal"+ galName +"Images";
		galImages.className = "iGalImages";
		
		galCurrent = document.createElement("div");
		galCurrent.id = "iGal"+ galName +"Current";
		galCurrent.className = "iGalCurrent";
		
		galInfo = document.createElement("div");
		galInfo.id = "iGal"+ galName +"Info";
		galInfo.className = "iGalInfo";

		if (self.enableOSD) {
			var navButs = self.prepNavButtons();
			self.inElement.appendChild(navButs);
			self.showNavButs();
			self.refreshNavTime();
			self.inElement.onmousemove = new Function (self.getGalName() + ".refreshNavTime()");
		}
	}
	
	this.applyLayoutHorizontal = function()
	{
		prepareLayout();
		self.inElement.style.width = self.getGalWidth() + "px";
		
		/*
		galHeader.style.height = "25px";
		galHeader.style.marginBottom = "5px";
		self.inElement.appendChild(galHeader);
		*/

		galNav.style.height = "25px";
		galNav.style.marginBottom = "5px";
		galNav.style.textAlign = "center";
		galNav.innerHTML += "<input style='float:left;' id='iGal"+ galName +"Prev' type='button' onclick='" + galName +
			".showPrevImage()' disabled='disabled' value='"+ iGal_i18n.button_previous_photo +"'>";
		galNav.innerHTML += "<input style='float:right;' id='iGal"+ galName +"Next' type='button' onclick='" + galName +
			".showNextImage()' disabled='disabled' value='"+ iGal_i18n.button_next_photo +"'>";
		galNav.innerHTML += "<span id='iGal"+ instanceName +"Selector'>" +
			self.getDropDown(self.getCurrentLocation()) +
			"</span>";
		
		galImages.style.overflow = "auto";
		galImages.style.padding = "5px";
		galImages.style.borderWidth = "1px";
		galImages.style.borderStyle = "solid";
		galImages.style.cssFloat = "none";
		galImages.style.styleFloat = "none";
		galImages.style.height = self.getThumbsHeight() + "px";
		galImages.style.width = self.getThumbsWidth() + "px";
		galImages.style.whiteSpace = "nowrap";
		
		galCurrent.style.marginTop = "5px";
		galCurrent.style.backgroundImage = "url(iGal/requisites/indicator.gif)";
		galCurrent.style.backgroundRepeat = "no-repeat";
		galCurrent.style.backgroundPosition = "30px 30px";
		
		galInfo.innerHTML = "<span id='iGal"+ galName +"InfoTitle'></span>";

		self.inElement.appendChild(galNav);
		self.inElement.appendChild(galCurrent);
		self.inElement.appendChild(galInfo);
		self.inElement.appendChild(galImages);
	};
	
	this.applyLayoutVertical = function()
	{
		prepareLayout();
		self.inElement.style.width = self.getGalWidth() + "px";

		galHeader.style.height = "25px";
		galHeader.style.marginBottom = "5px";
		galHeader.innerHTML = "<span id='iGal"+ instanceName +"Selector'>" +
			self.getDropDown(self.getCurrentLocation()) +
			"</span>";
		self.inElement.appendChild(galHeader);

		galNav.style.height = "25px";
		galNav.style.marginBottom = "5px";
		galNav.style.textAlign = "left";
		galNav.innerHTML = "<input id='iGal"+ galName +"Prev' type='button' onclick='" + galName +
			".showPrevImage()' disabled='disabled' value='"+ iGal_i18n.button_previous_photo +"'>" +
			"<input id='iGal"+ galName +"Next' type='button' onclick='" + galName +
			".showNextImage()' disabled='disabled' value='"+ iGal_i18n.button_next_photo +"'>";
		self.inElement.appendChild(galNav);

		galImages.style.overflow = "auto";
		galImages.style.padding = "5px";
		galImages.style.borderWidth = "1px";
		galImages.style.borderStyle = "solid none solid none";
		galImages.style.cssFloat = "right";
		galImages.style.styleFloat = "right";
		galImages.style.height = self.getThumbsHeight() + "px";
		galImages.style.width = self.getThumbsWidth() + "px";
		self.inElement.appendChild(galImages);
	
		galCurrent.style.marginTop = "5px";
		galCurrent.style.backgroundImage = "url(iGal/requisites/indicator.gif)";
		galCurrent.style.backgroundRepeat = "no-repeat";
		galCurrent.style.backgroundPosition = "30px 30px";
		self.inElement.appendChild(galCurrent);
		
		galInfo.style.height = "25px";
		galInfo.innerHTML = "<span id='iGal"+ galName +"InfoTitle'></span>";
		self.inElement.appendChild(galInfo);
	};
	this.applyLayoutGrid = function()
	{
		prepareLayout();
		// Not implemented, falling back to horizontal
		self.applyLayoutHorizontal();
	};
	this.prepNavButtons = function(navButsElement)
	{
		if (typeof navButsElement != "undefined") {
			var navButs = navButsElement;
		} else {
			var navButs = document.createElement("div");
			navButs.id = "iGal"+ self.getGalName() +"NavButs";
			navButs.className = "iGalNavButs";
			navButs.onmouseout = self.restoreNavButs;
		}
		var gn = self.getGalName();
		navContents = "<button "+
			"onmousedown='" + gn + ".riseNavButs(this)' "+
			"onmouseup='window.setTimeout(function(){" + gn +".lowerNavButs(this);}, 100)' "+
			"onclick='" + gn + ".showPrevImage()' "+
			"class='btnPrev'></button>&nbsp;";
		navContents += "<button "+
			"onmousedown='" + gn + ".riseNavButs(this)' "+
			"onmouseup='window.setTimeout(function(){" + gn +".lowerNavButs(this);}, 100)' "+
			"onclick='" + gn + ".goSlideshow()' "+
			"class='btnPlay'></button>&nbsp;";
		navContents += "<button "+
			"onmousedown='" + gn + ".riseNavButs(this)' "+
			"onmouseup='window.setTimeout(function(){" + gn +".lowerNavButs(this);}, 100)' "+
			"onclick='" + gn + ".showNextImage()' "+
			"class='btnNext'></button>";
		navButs.innerHTML = navContents;
		navButs.style.position = "absolute"
		navButs.style.top = this.inElement.offsetTop + minImageHeight - 40 + "px";
		navButs.style.left = this.inElement.offsetLeft + self.getGalWidth()/3 +"px";
	
		return navButs;
	};

	//var ev = (!window.event) ? e : window.event;
	//var targa = (!ev.target) ? ev.srcElement : ev.target;

	this.lowerNavButs = function(btn)
	{
		self.refreshNavTime();
		self.restoreNavButs();
	};
	
	this.navButsTimer = null;
	
	this.refreshNavTime = function()
	{
		if (!self.isNavBarShown) {
			self.showNavButs();
		}
		window.clearTimeout(self.navButsTimer);
		self.navButsTimer = window.setTimeout( self.getGalName() + ".hideNavButs()", 3000);
	};
	
	this.showNavButs = function()
	{
		var navButs = document.getElementById("iGal"+ self.getGalName() +"NavButs");
		navButs.style.display = "block";
		self.isNavBarShown = true;
	};
	
	this.hideNavButs = function()
	{
		var navButs = document.getElementById("iGal"+ self.getGalName() +"NavButs");
		navButs.style.display = "none";
		self.isNavBarShown = false;
	};
	
	this.restoreNavButs = function()
	{
		var navButs = document.getElementById("iGal"+ self.getGalName() +"NavButs");
		navButs = navButs.getElementsByTagName("button")
		if (!self.checkPrevImage()) {
			navButs[0].className = "btnPrevDis";
			navButs[0].disabled = "";
		} else {
			navButs[0].className = "btnPrev";
			navButs[0].disabled = "";
		}
		if (self.playing) {
			navButs[1].className = "btnPause";
		} else {
			navButs[1].className = "btnPlay";
		}
		if (!self.checkNextImage()) {
			navButs[2].className = "btnNextDis";
			navButs[2].disabled = "disabled";
		} else {
			navButs[2].className = "btnNext";
			navButs[2].disabled = "";
		}
		//self.prepNavButtons(navButs);
	}
	this.riseNavButs = function(but)
	{
		switch (but.className) {
			case "btnPrev" :
				but.className = "btnPrevHov";
			break;
			case "btnPlay" :
				but.className = "btnPlayHov";
			break;
			case "btnPause" :
				but.className = "btnPauseHov";
			break;
			case "btnNext" :
				but.className = "btnNextHov";
			break;
		}
	};
	
	this.slideShowTimer = null;
	
	this.goSlideshow = function()
	{
		var navButs = document.getElementById("iGal"+ self.getGalName() +"NavButs");
		navButs = navButs.getElementsByTagName("button");
		navButs[1].className = "btnPause";
		navButs[1].onclick = new Function(self.getGalName() + ".stopSlideshow()");
		self.slideShowTimer = window.setInterval(self.getGalName() + ".showNextImage()", 5000);
		self.playing = true;
	};
	
	this.stopSlideshow = function()
	{
		var navButs = document.getElementById("iGal"+ self.getGalName() +"NavButs");
		navButs = navButs.getElementsByTagName("button");
		navButs[1].className = "btnPlay";
		navButs[1].onclick = new Function(self.getGalName() + ".goSlideshow()");
		window.clearInterval(self.slideShowTimer);
		self.playing = false;
	};
	
	this.getCurrentLocation = function()
	{
		var loc = (window.location).toString();
		if (loc.indexOf("#") !== -1) {
			loc = loc.substring(loc.lastIndexOf("#") + 1, loc.length);
		} else {
			loc = 0;
		}
		return loc;
	};
	this.storeLocation = function(imgId, setId)
	{
		var loc = (window.location).toString();
		if (loc.indexOf("#") != -1) {
			loc = loc.substring(0, loc.lastIndexOf("#"));
		}
		var myloc = (this.lastSetId === 0) ? (imgId+1): setId + ":" + (imgId+1);
		
		// window.location = loc + "#" + myloc;

		/*
		TODO IE back button fix
		var theSet = self.getSetById(setId);
		var cImg = theSet.imgs[imgId];
		galNavFix.src = self.getBasePath() + "" + cImg.src;
		*/
	}
}

iGal.prototype.render = function()
{
	if (typeof iGal_i18n == 'undefined') {
		alert("Missing language information. Please check the usage guide for iGal.");
		return false;
	}
	if (this.getGalName() === null || eval( "typeof " + this.getGalName() + " == 'undefined'")) {
		alert(iGal_i18n.program_error_1);
		return false;
	}
	if (!this.inElement) {
		alert(iGal_i18n.program_error_2);
		return false;
	}
	
	switch (this.layout) {
		case "horizontal":
			this.applyLayoutHorizontal();
			break;
		case "vertical":
			this.applyLayoutVertical();
			break;
		case "grid":
			this.applyLayoutGrid();
			break;
	}
	this.isRendered = true;
	if (this.lastSetId !== 0) {
		this.showSet(this.getCurrentLocation());
	} else {
		this.showSet("0:" + this.getCurrentLocation());
	}
};

iGal.prototype.setLayout = function(mode)
{
	if (mode == "horizontal") {
		this.layout = "horizontal";
	} else if (mode == "vertical") {
		this.layout = "vertical";
	} else if (mode == "grid") {
		this.layout = "grid";
	}
};

iGal.prototype.setThumbs = function(sizeObj)
{
	if (typeof sizeObj == "undefined" || this.isRendered) {
		return;
	}
	if (typeof sizeObj.w != "undefined") {
		this.thumbsWidth = sizeObj.w;
	}
	if (typeof sizeObj.h != "undefined") {
		this.thumbsHeight = sizeObj.h;
	}
};

iGal.prototype.showPrevImage = function(setId)
{
	if (!this.isRendered) {
		return false;
	}
	var cSet = this.getSet(setId);
	if (cSet === false) {
		return false;
	}
	var cImg;
	if (typeof setId == "undefined" && this.currentImg !== null) {
		cImg = this.currentImg-1;
	} else if (cSet.imgs.length > 0) {
		cImg = cSet.imgs.length-1;
	}
	if (cImg !== null && cImg >= 0 && typeof cSet.imgs[cImg] != "undefined") {
		if (cSet.id != this.currentSet) {
			this.showSet(cSet.id, true);
		}
		this.showImg(cImg);
		return true;
	}
	if ( setId != "undefined" || cSet.imgs.length === 0) {
		return this.showPrevImage(cSet.id-1);
	}
	return false;
};

iGal.prototype.showNextImage = function(setId)
{
	if (!this.isRendered) {
		logMsg("Not rendered yet");
		return false;
	}
	var cSet = this.getSet(setId);
	if (cSet === false) {
		// logMsg("Invalid set requested");
		return false;
	}
	// logMsg("In set #"+ cSet.id +"");
	var cImg;
	if (typeof setId == "undefined" && this.currentImg !== null) {
		cImg = this.currentImg + 1;
		// logMsg("Using current image.");
	} else if (cSet.imgs.length > 0) {
		cImg = 0;
		// logMsg("Using FIRST image.");
	}
	if (cImg !== null && cImg >= 0 && typeof cSet.imgs[cImg] != "undefined") {
		if (cSet.id != this.currentSet) {
			this.showSet(cSet.id, true);
		}
		this.showImg(cImg);
		// logMsg("Shown image #" + cImg);
		return true;
	}
	if (setId != "undefined" || cSet.imgs.length === 0) {
		// logMsg("Skipped an empty set");
		return this.showNextImage(cSet.id+1);
	}
	//logMsg("DEADEND")
	return false;
};

iGal.prototype.showImg = function(imgId)
{
	imgId = parseInt(imgId)
	var galName = this.getGalName();
	if (!this.isRendered || isNaN(imgId)) {
		return false;
	}
	var theSet = this.getSet();
	if (theSet === false) {
		//alert(iGal_i18n.program_error_3 + "" + this.currentSet);
		return false;
	}
	if (this.currentImg == imgId) {
		return false;
	}
	this.currentImg = imgId;
	this.reloadNav();
	
	var cImg = theSet.imgs[imgId];
	if (!cImg) {
		return false;
	}
	var imgSrc = this.getBasePath() + "" + cImg.src;
		
	var imgTag = "<img onclick='return "+ galName +".showNextImage();' src='" + imgSrc + "'";
	if (cImg.w !== "") {
		imgTag += " width='" + cImg.w + "'";
	}
	if (cImg.h !== "") {
		imgTag += " height='" + cImg.h + "'";
	}
	imgTag += " title='"+ imgSrc  +"'"
	imgTag += " alt='" + cImg.title + "' />";
	
	var imgPlace = document.getElementById("iGal"+ galName +"Current");
	imgPlace.innerHTML = imgTag;
	imgPlace.style.height = "auto";
	
	document.getElementById("iGal"+ galName +"InfoTitle").innerHTML = (cImg.title !== "") 
		? cImg.title : theSet.name;

	var curThumb = document.getElementById("thumb" + imgId);
	curThumb.className = "hiThumb";
		
	var imgHolder = document.getElementById("iGal"+ galName +"Images");
	
//	var animateThumbSettings;
// 	if (this.layout == "horizontal") {
// 		animateThumbSettings = {scroll: { to: [curThumb.offsetLeft - (imgHolder.offsetWidth/2 - curThumb.offsetWidth/3) , 0] }}
// 	} else if (this.layout == "vertical") {
// 		animateThumbSettings = {scroll: { to: [0, curThumb.offsetTop - (imgHolder.offsetHeight - curThumb.offsetHeight)] }}
// 	}
// 	var animateThumbs = new YAHOO.util.Scroll(imgHolder, animateThumbSettings, 0.1);
// 	animateThumbs.animate(); 
	
	var lastThumb = document.getElementById(this.lastImg);
	if (lastThumb) {
		lastThumb.className = "regularThumb";
	}
	curThumb.parentNode.className = "";
	this.storeLocation(imgId, theSet.id);
	this.lastImg = "thumb" + imgId;
	return true;
};

iGal.prototype.showSet = function(id, loadFirstImage)
{
	var galName = this.getGalName();
	if (!this.isRendered) {
		return false;
	}
	var loadImage;
	if (id.toString().indexOf(":") !== -1) {
		var ids = id.split(":");
		id = parseInt(ids[0]);
		loadImage = parseInt(ids[1]);
	}
	if (isNaN(id) || this.lastSetId === 0) {
		id = 0;
		loadImage = id;
	}
	if (typeof loadFirstImage == "undefined") {
		loadFirstImage = true;
	}
	this.clearSet();
	var theSet = this.getSetById(id);
	var galInfo = document.getElementById("iGal"+ galName +"InfoTitle");
	if (!theSet) {
		galInfo.innerHTML = iGal_i18n.msg_missing_set + "" + id;
		return false;
	}
	this.currentSet = id;
	if (theSet.imgs.length === 0) {
		galInfo.innerHTML = iGal_i18n.msg_choose_set;
		this.reloadNav();
		return false;
	}
	
	var images = "";
	for (var i in theSet.imgs) {
		images += "<p onclick='return "+ galName +".showImg(" + i + ");'";
		images += " onmouseover='this.className=\"over\"' onmouseout='this.className=\"\"' style='cursor:pointer; float:none;";
		if (this.layout == "horizontal") {
			images += "display: inline; padding: 0 7px;";
		} else if (this.layout == "vertical") {
			images += "display: block;";
		}
		images += "'>";
		images += "<img id='thumb"+ i +"' class='regularThumb' src='" + this.getBasePath() + theSet.imgs[i].thumb + "' alt='' ";
		if (this.layout == "horizontal") {
			images += "height='"+ this.thumbsHeight +"'";
		} else if (this.layout == "vertical") {
			images += "width='"+ this.thumbsWidth +"'";
		}
		images += " /></p>";
	}
	document.getElementById("iGal"+ galName +"Images").innerHTML = images;
	document.getElementById("iGal"+ galName +"Images").className = "iGalImages";
	
	document.getElementById("iGal"+ galName +"Selector").innerHTML = this.getDropDown(theSet.id);
	
	if (loadImage) {
		this.showImg(loadImage-1);
	} else if (loadFirstImage && this.checkNextImage() !== false) {
		this.showNextImage();
	}
	return true;
};

iGal.prototype.addSet = function(name, desc)
{
	if (this.isRendered) {
		alert(iGal_i18n.program_error_7);
		return false;
	}
	if (typeof name == "undefined") {
		name = "";
	}
	if (typeof desc == "undefined") {
		desc = "";
	}
	var newSet = new this.iGalSet(this.lastSetId + 1, name, desc);
	if (this.contents === null) {
		this.contents = newSet;
		this.lastSetId = 0;
	} else {
		var lastSet = this.getSetById(this.lastSetId);
		if (lastSet === false) {
			alert(iGal_i18n.program_error_6 + name);
			return false;
		}
		var desiredSet = this.getSetById(this.attachToSet[this.attachToSet.length - 1]);
		if (desiredSet === false) {
			alert(iGal_i18n.program_error_4);
			alert(this.attachToSet[this.attachToSet.length - 1]);
			return false;
		}
		this.attachSet(newSet, desiredSet);
	}
	return newSet;
};

iGal.prototype.indentSet = function()
{
	this.attachToSet[this.attachToSet.length] = this.lastSetId;
};

iGal.prototype.outdentSet = function()
{
	if (this.attachToSet.length > 1) {
		delete this.attachToSet[this.attachToSet.length - 1];
		this.attachToSet.length = this.attachToSet.length - 1;
	}
};

iGal.prototype.addImg = function(thumb, src, width, height, title)
{
	if (this.isRendered) {
		alert(iGal_i18n.program_error_7);
		return false;
	}
	if (typeof title == "undefined") {
		title = "";
	}
	if (typeof width == "undefined") {
		width = "";
	}
	if (typeof height == "undefined") {
		height = "";
	}
	if (typeof thumb == "undefined" || typeof src == "undefined") {
		alert (iGal_i18n.program_error_5);
		return false;
	}
	var newImg = new this.iGalImg(thumb, src, width, height, title);
	this.setMinImageHeight(height);
	this.setMaxImageWidth(width);
	var galSet = this.getSetById(this.lastSetId);
	if (galSet === false) {
		return false;
	}
	galSet.imgs[galSet.imgs.length] = newImg;
	return newImg;
};

/*
 * Show a message in debug panel
 */
function logMsg(msg)
{
	var debugDivId = "debugPanel";
	var debDiv = document.getElementById(debugDivId);
	if (!debDiv) {
    	var newDiv = document.createElement("div");
    	newDiv.id = debugDivId;
		newDiv.style.position = "absolute";
		newDiv.style.right = "10px";
		newDiv.style.top = "10px";
		newDiv.style.zIndex = "1000";
		newDiv.style.width = "200px";
		newDiv.style.height = "500px";
		newDiv.style.overflow = "auto";
		newDiv.style.fontSize = "9pt";
		newDiv.style.backgroundColor = "white";
		newDiv.style.color = "black";
		newDiv.style.border = "outset 2px silver";
		newDiv.style.fontFamily = "monospace"
		newDiv.style.padding = "5px";
    	debDiv = document.body.appendChild(newDiv);
	}
	debDiv.innerHTML += "<br />. " + msg;
}

/*
 * Gallery set micro object
 */
iGal.prototype.iGalSet = function(id, name, desc)
{
	this.id = 0;
	this.name = "";
	this.desc = "";
	this.imgs = [];
	this.subset = [];
	
	if (typeof name == "undefined" || typeof desc == "undefined") {
		return false;
	} else {
		this.id = id;
		this.name = name;
		this.desc = desc;
		return this;
	}
};

/*
 * Gallery image micro object
 */
iGal.prototype.iGalImg = function(thumb, src, width, height, title)
{
	this.thumb = thumb;
	this.src = src;
	this.title = title;
	this.w = width;
	this.h = height;
	return this;
};

iGal.prototype.showOsdButtons = function (toggle) 
{
	this.enableOSD = (toggle) ? true : false;
};

iGal.prototype.getImageLinkMap = function (set)
{
	if (typeof set == "undefined") {
		set = this.contents.subset;
		totalSets = 1;
	}
	var result = [];
	for (var i in set) {
		if (set[i].imgs) {
			var theimgs = set[i].imgs
			for (var j in theimgs) {
				result.push ({
					title: theimgs[j].title,
					img: theimgs[j].src,
					id: totalSets + ':' + (parseInt(j)+1)
					});
			}
		}
		if (set[i].subset) {
			totalSets++;
			var nextResult = this.getImageLinkMap(set[i].subset);
			if (nextResult.length > 0) {
				result = result.concat(nextResult);
			}
		}
	}
	return result;
}
iGal.prototype.showImageLinkMap = function () 
{
	var result = "";
	var ids = theGal.getImageLinkMap();
// JS
// 	for (var i in ids) {
// 		result += '"' + ids[i].img + '":\t"' + ids[i].id + '"<br />';
// 	}
// XML
	for (var i in ids) {
		result += '&lt;photo&gt;&lt;img&gt;' + ids[i].img + '&lt;/img&gt;&lt;link&gt;' + 
			ids[i].id + '&lt;/link&gt;&lt;/photo&gt;<br />';
	}
// HTML
// 	for (var i in ids) {
// 		var imgto = (ids[i].title == "") ? ids[i].img : ids[i].title;
// 		result += '&lt;li&gt;&lt;a href="'+
// 			this.getBasePath() + ids[i].img +'"&gt;' + imgto + '&lt;/a&gt;&lt;/li&gt;<br />';
// 	}
// PHP
// 	for (var i in ids) {
// 		result += '"' + ids[i].img + '" =&gt; "' + ids[i].id + '"<br />';
// 	}
	this.inElement.innerHTML = result;
}