  // define a thumbnail object
  function thumbnail(apictid,acaption,afilename,apublic,canedit,isvideo,moddt)
  {
    this.ndx = null;
    this.pictid = apictid;
	this.caption = acaption;
	this.filename = afilename;
	this.ispublic = apublic;
	this.canedit = canedit;	
	this.statusBarString = null;
	this.titleString = null;
	this.bottomString = null;
	this.calculatedCaptions = false;
	this.parent = null;
	this.id = 'thumb' + apictid;
	this.moddate = moddt;
	this.cache = null;
	this.isvideo = isvideo;
	return this;
  }
  
  // fixup the captions
  thumbnail.prototype.calculateCaptions = function ()
  {
    if (this.calculatedCaptions == false)
	{
      crre = /%13%10/g;
      apre = /'/g;
      qure = /"/g;
      brre = /<BR>/g;
	  bsre = /\\/g;
	
	  var cap = unescape(this.caption.replace(crre,'<BR>'));
      cap = cap.replace(/  /g, '');
	  if (cap == '') cap = unescape(this.filename);
	  var hintcap = cap;

	  if (hintcap == '') hintcap = "Click on the thumbnail to view the picture";
	  if (this.parent.showCaptions == 'Filename') cap = unescape(this.filename);		 

	  acap = hintcap.replace(apre, "%27");
      acap = acap.replace(crre, '<BR>');
	  acap = acap.replace(qure, '%22');
      acap = acap.replace(brre, '  ');
	  acap = acap.replace(bsre, '%5c');

	  hintcap = hintcap.replace(apre, "&#39;");
	  hintcap = hintcap.replace(qure, '&quot;');
      hintcap = hintcap.replace(brre, '&#13;&#10;');
	  hintcap = hintcap.replace(bsre, '&#92;');	  

	  if (cap == '') cap = '&nbsp;';
	
	  this.statusBarString = acap;
	  this.titleString = hintcap;
	  this.bottomString = cap.substr(0,13);
	
	  this.calculatedCaptions = true;
	}
  }
  
  // build the anchor string for the thumbnail
  thumbnail.prototype.anchorString = function()
  {
	var anc = '<a';
	if (this.ndx == 0) anc += ' name=Thumb1';
	anc += ' class=classicThumbnail OnMouseMove="javascript:SetStatusBar(\'' + this.statusBarString + '\')"  ';
	anc += ' OnMouseOut="javascript:SetStatusBar(\'\')" ';	 
	anc += ' title=\'' + this.titleString + '\'';
	if (this.parent.usePopupViewer)
 	    anc += ' href="javascript:DetailWin(\'' + this.parent.userid + '\',' + this.ndx + ',\'' + this.parent.albumid + '\', \'' + this.parent.groupid + '\' )">';  	
	  else
 	    anc += ' href="javascript:Detail(\'' + this.parent.userid + '\',' + this.ndx + ',\'' + this.parent.albumid + '\', \'' + this.parent.groupid + '\' )">';  
	return(anc); 
  }
  
  // convert a thumbnail to a string
  thumbnail.prototype.toString = function()
  {
    if (this.cache == null) {
		this.calculateCaptions();
		var thstr = '';
		
		// start thumb
		thstr = thstr + '<td>';
		
		var anc = this.anchorString();
		var cmparms = "event,'" + this.pictid + "', " + this.ndx + ",\'" + this.parent.albumid + "\',\'" + this.parent.groupid + "\'," + this.ispublic + "," + this.canedit;
			 
		if (this.parent.showCaptions != 'None') thstr = thstr + '<table border=0><tr><td>';	 
		thstr += anc + '<img';
		if ((useragent.isie) && (this.parent.isguest == false)) thstr += ' id="' + this.pictid + '" onContextMenu="return thumbContext(' + cmparms + ');" ';
		thstr += ' src="/ftweb/bin/ft.dll/thumbsrc?pictid=' + this.pictid + '&guid=' + this.parent.guid + '&moddt=' + this.moddate + '" border=0 width=100 height=100></a>';
		if (this.bottomString != '&nbsp;') {
		  if (this.parent.showCaptions != 'None') thstr = thstr + '</td></tr><tr><td class=classicThumbnail>' + anc + this.bottomString + '</a></td></tr></table>';
		} else {
		  if (this.parent.showCaptions != 'None') thstr = thstr + '</td></tr><tr><td align=center>&nbsp;</td></tr></table>';	
		}
		 
		// end thumb
		thstr = thstr  + '</td>';
		this.cache = thstr;
	}
    return this.cache; 
  }

// support for sub-groups
  function group(apictid,agroupid,aname)
  {
    this.ndx = null;
    this.pictid = apictid;
    this.name = aname;
    this.groupid = agroupid;
    this.statusBarString = aname;
    this.titleString = aname;
    this.bottomString = aname;
    this.parent = null;
    this.id = 'grp' + apictid;
    this.cache = null;	
    this.fixedBottomString = this.fixCaption();
    return this;
  }

  // build the anchor string for the thumbnail
  group.prototype.anchorString = function()
  {
    var anc = '<a';
    if (this.ndx == 0) anc += ' name=Group1';
    anc += ' class=classicThumbnail OnMouseMove="javascript:SetStatusBar(\'' + this.statusBarString + '\')"  ';
    anc += ' OnMouseOut="javascript:SetStatusBar(\'\')" ';	 
    anc += ' title=\'' + this.titleString + '\'';
    anc += ' href="/ftweb/bin/ft.dll/pictures?userid=' + this.parent.userid + '&albumid=' + this.parent.albumid + '&groupid=' + this.groupid + '">';  	
    return(anc); 
  }


  group.prototype.fixCaption = function() {
    var a = unescape(this.bottomString);
    return(a);
  }

  group.prototype.toString = function()
  {
    if (this.cache == null) {
		var thstr = '';
		
		// start thumb
		thstr = thstr + '<td>';
		
		var anc = this.anchorString();
			 
		thstr = thstr + '<table border=0><tr><td>';	 
		thstr += anc + '<img';
		if ((useragent.isie) && (this.parent.isguest == false)) thstr += ' id="' + this.pictid + '" ';
		thstr += ' src="/ftweb/bin/ft.dll/thumbsrc?pictid=' + this.pictid + '&guid=' + this.parent.guid + '&moddt=' + this.moddate + '" border=0 width=100 height=100></a>';
		if (this.bottomString != '&nbsp;') {
		  thstr = thstr + '</td></tr><tr><td class=classicThumbnail>' + anc + this.fixedBottomString + '</a></td></tr></table>';
		} else {
		  thstr = thstr + '</td></tr><tr><td align=center>&nbsp;</td></tr></table>';	
		}
		 
		// end thumb
		thstr = thstr  + '</td>';
		this.cache = thstr;
	}
    return this.cache; 
  }

  
  
  // the thumbnails collection
  function ftThumbnails() {
    this.thumbs = [];
	this.groups = [];
    this.showCaptions = "Captions";
	this.albumid = null;
	this.groupid = null;
	this.userid = null;
	this.guid = null;
	this.isinvite = false;
	this.isguest = false;   
	this.lastrowsize = 0;
	this.curAlbumGroupName = null;
	this.usePopupViewer = false;
  }
  
  // pass in a newly created thumbnail to add it to the list
  ftThumbnails.prototype.add = function (thumb) {
    thumb.parent = this;
	thumb.ndx = this.thumbs.length;
	this.thumbs[this.thumbs.length] = thumb;
  } 

  // pass in a newly created thumbnail to add it to the list
  ftThumbnails.prototype.addGroup = function (group) {
    group.parent = this;
	group.ndx = this.groups.length;
	this.groups[this.groups.length] = group;
  } 

  
  // calculate the max # of thumbnails per row
  ftThumbnails.prototype.getThumbnailsPerRow = function() {
    var maxthumbs = 0;
	// get width different ways for ie and netscape
	if (document.body && document.body.clientWidth) 
	  ww = document.body.clientWidth; else ww = window.innerWidth;

    if (this.showCaptions != "None") 
      maxthumbs = (ww - 205) / 106; else maxthumbs = (ww - 202) / 104;
    imaxthumbs = Math.floor(maxthumbs);
	if (imaxthumbs < 1) imaxthumbs = 1;
	return imaxthumbs;
  }

  // convert the thumbnail list for string output
  ftThumbnails.prototype.toString = function() {
    var imaxthumbs = this.getThumbnailsPerRow();
	this.lastrowsize = imaxthumbs;
	var html = '';
	var curr=1;	
    var addedGroups = false;
	var addedPhotos = false;
		
	html += '<table border=0 cellspacing=0 cellpadding=0>';

    if (this.groups.length > 0) {
	  html += '<tr><td colspan=' + imaxthumbs + ' style="padding-bottom:0px; text-align:left" class=albumComments>Sub albums for "' + this.curAlbumGroupName + '"</td></tr>';
	}

    var needTR = false;
	for (var i = 0; i < this.groups.length; i++) {
	  addedGroups = true;
	  gr = this.groups[i]; 
	  
	  // start a new row???
	  if (curr == 1)  html += '<tr>';	  	  
	  
	  // output the thumbnail
	  html += gr;
	  needTR = true;
		 
	  // end row if necessary
	  if (curr == imaxthumbs) {
	    html += '</tr>';		 
		needTR = false;
	  }
		 
	  // inc curr on row - check to see if need new row
	  curr = curr + 1;
	  if (curr == imaxthumbs +  1) curr = 1;
    } // end while

    if ((addedGroups) && (needTR)) html += '</tr>';
    curr = 1;
	
	if ((this.thumbs.length > 0) && (addedGroups)) {
	  html += '<tr><td colspan=' + imaxthumbs + ' style="padding-bottom:0px; padding-top:15px; text-align:left" class=albumComments>Photos for "' + this.curAlbumGroupName + '"</td></tr>';	
	}

	for (var i = 0; i < this.thumbs.length; i++) {
	  addedPhotos = true;
	  th = this.thumbs[i]; 
	  
	  // start a new row???
	  if (curr == 1)  html += '<tr>';	  	  
	  
	  // output the thumbnail
	  html += th;
		 
	  // end row if necessary
	  if (curr == imaxthumbs)  html += '</tr>';		 
		 
	  // inc curr on row - check to see if need new row
	  curr = curr + 1;
	  if (curr == imaxthumbs +  1) curr = 1;
    } // end while

	// finish off table
	html += '</tr></table>'; 
	
	// what to display if now thumbnails
    if ((addedGroups == false) && (addedPhotos == false))
	{
	  if ((this.isinvite) && (this.albumid == "") && (this.groupid == ""))
	     html = '<B>Your invite does not include access to view any pictures with this account.</B>';
	  else
	  if ((this.isguest) && (this.albumid == "") && (this.groupid == ""))
	     html = '<B>Your guest access to this account does not include access to view any pictures with this account.</B>';
	  else	  
	  if (this.isinvite)
  	     html = '<B>Click on any of the groups within this album to see pictures for your invitation.</B>';
	  else
	  if (this.isguest)
  	     html = '<B>Click on any of the groups within this album to see pictures you have access to.</B>';
	  else
         html = '<B>Click on any of the groups within this album to see its pictures.</B>';	   	   
    }

	// give back the results
  	return html;
  }

  // put the thumbails in the cell they are supposed to be in
  // optimized not to do this unless the # of thumbs per row changes
  ftThumbnails.prototype.write = function() {
    var imaxthumbs = this.getThumbnailsPerRow();
	if (imaxthumbs != this.lastrowsize) {
      if (document.getElementById)
	    tc = document.getElementById("thumbcell"); else tc = thumbcell;	
		//alert("start");
		var html = this.toString();
		//alert("got html");
        tc.innerHTML = html;
		//alert("done");
	}
  }

