function TPPlanImgGallery(imgData, defaultID, galleryID, imgDir, thumbDir)
	{
	this.imgData = imgData;
	this.defaultID = defaultID;
	this.galleryID = galleryID;
	this.imgDir = imgDir;
	this.thumbDir = thumbDir;
	this.maxLgWidth = 450;
	this.maxLgHeight = 0;
	this.maxThumbWidth = 56;
	this.maxThumbHeight = 56;
	this.preloaders = new Array();
	//-------------------------------------------------------------------------------------
	// LOAD IMAGE DATA INTO TEMPLATES
	//-------------------------------------------------------------------------------------
	this.buildGallery = function()
		{
		// select gallery div and delete any exiting nodes
		galleryDiv = document.getElementById(this.galleryID);
		this.clearChildren(galleryDiv);
		// build default large image container div
		var lgImgDiv = document.createElement('div');
		lgImgDiv = this.setElementClass(lgImgDiv, 'image-large');
		// build default large image tag
		var lgImgData = this.imgData[this.defaultID];
		var lgImage = this.createNamedElement('img', this.galleryID+'LgImg');
		lgImage.setAttribute('id', this.galleryID+'LgImg');
		lgImage.setAttribute('src', this.buildImgPath(lgImgData, 'large'));
		lgImage.setAttribute('alt', 'plan image');
		var lgSizeData = this.getImgSize(
			lgImgData.width, lgImgData.height,
			this.maxLgWidth, this.maxLgHeight
			);
		lgImage.setAttribute('width', lgSizeData.width);
		lgImage.setAttribute('height', lgSizeData.height);
		// add large image to gallery div
		lgImgDiv.appendChild(lgImage);
		galleryDiv.appendChild(lgImgDiv);
		// build container(s) and table for thumbnails
		var thumbDiv = document.createElement('div');
		thumbDiv.setAttribute('id', this.galleryID+'TContainer');
		var thumbTable = document.createElement('table');
		thumbTable.setAttribute('cellspacing', '0');
		thumbTable.setAttribute('align', 'center');
		var thumbTableHead = document.createElement('thead');
		var headRow = document.createElement('tr');
		var headCell = document.createElement('th');
		var thisColSpan = this.countProperties(this.imgData)
		headCell.setAttribute('colspan', thisColSpan);
		headCell.colSpan = thisColSpan;
		var headText = document.createTextNode('PLAN IMAGE GALLERY:');
		headCell.appendChild(headText);
		headRow.appendChild(headCell);
		thumbTableHead.appendChild(headRow);
		thumbTable.appendChild(thumbTableHead);
		var thumbTableBody = document.createElement('tbody');
		var thumbRow = document.createElement('tr');
		// build block for each thumbnail
		for (var imgID in this.imgData)
			{
			var thisTData = this.imgData[imgID];
			// build thumbnail block div
			var thisTBlock = document.createElement('td');
			thisTBlock.setAttribute('align', 'center');
			thisTBlock.setAttribute('valign', 'middle');
			var thisTClass = (thisTData.id == this.defaultID)
				? 'thumb-block-selected' : 'thumb-block';
			thisTBlock = this.setElementClass(thisTBlock, thisTClass);
			thisTBlock.setAttribute('id', this.galleryID+'T'+imgID);
			// build thumbnail link
			var thisTLink = document.createElement('a');
			thisTLink.setAttribute('href', '#');
			thisTLink.onclick = this.thumbEventBuilder(this.galleryID, imgID);
			// build thumbnail image
			var thisTImg = document.createElement('img');
			var thisTPath = this.buildImgPath(thisTData, 'thumb');
			thisTImg.setAttribute('src', this.buildImgPath(thisTData, 'thumb'));
			// add image to link, link to block and block to container
			thisTLink.appendChild(thisTImg);
			thisTBlock.appendChild(thisTLink);
			thumbRow.appendChild(thisTBlock);
			}
		// load gallery into page/div
		thumbTableBody.appendChild(thumbRow);
		thumbTable.appendChild(thumbTableBody);
		thumbDiv.appendChild(thumbTable);
		galleryDiv.appendChild(thumbDiv);
		};
	// update gallery when new thumbnail is clicked
	this.updateGallery = function(thisID)
		{
		var lgImage = document.getElementById(this.galleryID+'LgImg');
		for (var imgID in this.imgData)
			{
			var thisImage = this.imgData[imgID];
			var tImageBlock = document.getElementById(this.galleryID+'T'+imgID);
			if (imgID == thisID)
				{
				var lgSizeData = this.getImgSize(
					thisImage.width, thisImage.height,
					this.maxLgWidth, this.maxLgHeight
					);
				lgImage.setAttribute('src', this.buildImgPath(thisImage, 'large'))
				lgImage.setAttribute('width', lgSizeData.width);
				lgImage.setAttribute('height', lgSizeData.height);
				lgImage.style.marginTop = thisImage.padtop+'px';
				lgImage.style.marginBottom = thisImage.padbtm+'px';
				tImageBlock.setAttribute('class', 'thumb-block-selected');
				tImageBlock.className = 'thumb-block-selected';
				} else {
				tImageBlock.setAttribute('class', 'thumb-block');
				tImageBlock.className = 'thumb-block';
				}
			}
		}
	// build image path from data object
	this.buildImgPath = function(data, type)
		{
		if (type == 'large')
			var results = this.imgDir+'/'+data.id+'_'+data.ts+data.ext;
			else results = this.thumbDir+'/'+data.id+'_'+data.ts+data.ext;
		return results;
		};
	// determine new size based on current and max
	this.getImgSize = function(oldWidth, oldHeight, maxWidth, maxHeight)
		{
		newWidth = oldWidth;
		newHeight = oldHeight;
		if (oldWidth > maxWidth && maxWidth > 0) {
			newWidth = maxWidth;
			newHeight = Math.round((oldHeight * newWidth) / oldWidth);
			oldWidth = newWidth;
			oldHeight = newHeight;
			}
		if (oldHeight > maxHeight && maxHeight > 0) {
			newHeight = maxHeight;
			newWidth = Math.round((oldWidth * newHeight) / oldHeight);
			}
		return { width: newWidth, height: newHeight }
		};
	// onclick event scope preserver for thumbnails
	this.thumbEventBuilder = function(galleryID, imgID)
		{
		return function()
			{
			MPTPPlanGalleries[galleryID].updateGallery(imgID);
			return false;
			}
		};
	//-------------------------------------------------------------------------------------
	// GENERAL UTILITY FUNCTIONALITY
	//-------------------------------------------------------------------------------------
	// create named element compatible with IE
	this.createNamedElement = function(type, name)
		{
		var element = null;
		try
			{
			element = document.createElement('<'+type+' name="'+name+'">');
			} catch (e) {}
		if (!element || element.nodeName != type.toUpperCase())
			{
			element = document.createElement(type);
			element.name = name;
			}
		return element;
		};
	// assign a class to an element compatible with IE
	this.setElementClass = function(element, className)
		{
		element.setAttribute('class', className);
		element.className = className;
		return element;
		};
	// add event listener to element (IE safe)
	this.addEvent = function(elm, evType, fn, useCapture)
		{
		if (elm.addEventListener)
			{
			elm.addEventListener(evType, fn, useCapture);
			return true;
			} else if (elm.attachEvent) {
			var r = elm.attachEvent('on' + evType, fn);
			return r;
			} else {
			elm['on' + evType] = fn;
			}
		};
	// function to clear all child nodes from element
	this.clearChildren = function(elm)
		{
		while(elm.hasChildNodes()) elm.removeChild(elm.firstChild);
		}
	// function to count object properties (for associative arrays)
	this.countProperties = function(obj)
		{
		var results = 0;
		for (var x in obj) results++;
		return results;
		}
	}
