function TOCNR(title,caption,autoRefreshMap,swatch) {
  var toc = new TOC(title,caption,autoRefreshMap,swatch);
	inherit(this,toc);

	this.root.writeHTML = function(child_shim, sibling_shim) {
		var s = "";
		for (var i=0, n=this.items.length; i<n; i++) {
			s += this.items[i].writeHTML('','');
		}
		return s;
	};

	return this;
}

function GROUP01(caption,opened,swatch) {
  var group = new GROUP(caption,opened,swatch);
	inherit(this,group);

	this.getVisible = function() {
	  var gvr = this.zuper.getVisible();
		return (gvr==0) ? 0 : 1; 
	};

	this.setVisible = function(value) {
		if (value==0) {
			this.zuper.setVisible(0);
		} else {
		  var gvr = this.zuper.getVisible();
			if (gvr==0) {
				this.getItem(0).toggleVisible();
			}
		}
	};

	this.init = function() {
		this.zuper.init();
		var ltv = function() {
  		var wasVisible = (this.getVisible() == 1);
  		this.parent.setVisible(0); 
  		if (!wasVisible) this.setVisible(1);
		}
		for (var i=0, n=this.items.length; i<n; i++) {
			this.items[i].toggleVisible = ltv;
		}
	}

  return this;
}

function GROUP01N(caption,opened,swatch) {
  var group = new GROUP(caption,opened,swatch);
	inherit(this,group);
	this.klass = "GROUP01N";

	this.writeHTML = function(child_shim, sibling_shim) {
		var s = "";
		s += '<TR><TD NOWRAP VALIGN="Top" CLASS="Group">';
		s += child_shim;
		if (this.opened) {
			s += '<IMG SRC="' + this.iconOpened.src + '"' + _cache.strIconSize + ' onmouseover="style.cursor=\'hand\'"; onmousedown="t.toc.onIconClick(' + this.tocid + ');" alt="Click to close">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
		} else {
			s += '<IMG SRC="' + this.iconClosed.src + '"' + _cache.strIconSize + ' onmouseover="style.cursor=\'hand\'"; onmousedown="t.toc.onIconClick(' + this.tocid + ');" alt="Click to open">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
		}
		
		s += '<A CLASS="Group" HREF="javascript:t.toc.onCaptionClick(' + this.tocid + ')">&nbsp;' + this.caption + '</A>';
		s += '</TD></TR>';
		if (this.opened) {
			for (var i=0, n=this.items.length; i<n; i++) {
				var new_child_shim = sibling_shim + '<img src="' +
					((i==n-1) ? _cache.iconChildLast.src : _cache.iconChild.src) + '"' + _cache.strIconSize + '>';
				var new_sibling_shim = sibling_shim + '<img src="' + 
					((i==n-1) ? _cache.iconBlank.src : _cache.iconSibling.src) + '"' + _cache.strIconSize + '>';
				s += this.items[i].writeHTML( new_child_shim, new_sibling_shim );
			}
		}
		return s;
	}

	this.getVisible = function() {
	  var gvr = this.zuper.getVisible();
		return (gvr==0) ? 0 : 1;
	};

	this.setVisible = function(value) {
		if (value==0) {
			this.zuper.setVisible(0);
		} else {
		  var gvr = this.zuper.getVisible();
			if (gvr==0) {
				this.getItem(0).toggleVisible();
			} 
		}
	};

	this.hideRecursiveUp = function() {
		if (this.parent.klass == "GROUP01N")
			this.parent.hideRecursiveUp();
		else
			this.setVisible(0);
	}

	this.init = function() {
		this.zuper.init();
		var ltv = function() {
  		var wasVisible = (this.getVisible() == 1);
			this.parent.hideRecursiveUp();
  		if (!wasVisible) this.setVisible(1); 
		}
		for (var i=0, n=this.items.length; i<n; i++) {
			this.items[i].toggleVisible = ltv;
		}
	}

  return this;
}

function GROUPNV(caption,opened,swatch) {
  var group = new GROUP(caption,opened,swatch);
	inherit(this,group);

	this.writeHTML = function(child_shim, sibling_shim) {
		var s = "";
		s += '<TR><TD NOWRAP VALIGN="Top" CLASS="Group">';
		s += child_shim;
		if (this.opened) {
			s += '<IMG SRC="' + this.iconOpened.src + '"' + _cache.strIconSize + ' onmouseover="style.cursor=\'hand\'"; onmousedown="t.toc.onIconClick(' + this.tocid + ');" alt="Click to close">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
		} else {
			s += '<IMG SRC="' + this.iconClosed.src + '"' + _cache.strIconSize + ' onmouseover="style.cursor=\'hand\'"; onmousedown="t.toc.onIconClick(' + this.tocid + ');" alt="Click to open">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;';
		}
		s += '<A CLASS="Group" HREF="javascript:t.toc.onCaptionClick(' + this.tocid + ')">&nbsp;' + this.caption + '</A>';
		s += '</TD></TR>';
		if (this.opened) {
			for (var i=0, n=this.items.length; i<n; i++) {
				var new_child_shim = sibling_shim + '<img src="' +
					((i==n-1) ? _cache.iconChildLast.src : _cache.iconChild.src) + '"' + _cache.strIconSize + '>';
				var new_sibling_shim = sibling_shim + '<img src="' + 
					((i==n-1) ? _cache.iconBlank.src : _cache.iconSibling.src) + '"' + _cache.strIconSize + '>';
				s += this.items[i].writeHTML( new_child_shim, new_sibling_shim );
			}
		}
		return s;
	}

	return this;
}

function GROUPVL(caption,opened,swatch) {
  var group = new GROUP(caption,opened,swatch);
	inherit(this,group);

	this.opened = false;

	this.toggleOpened = function() {
		this.opened = false;
	}

	this.onCaptionClick = function() {
		var helpurl = parent.MapFrame.app_path+'documentation/metadata.htm#'+this.caption;
		window.open( helpurl,"Meta_Data_Window","width=600,height=400,scrollbars=yes,resizable=yes");
	}

	this.writeHTML = function(child_shim, sibling_shim) {
		var s = "";
		// START OF GROUP ROW IN LAYER LIST
		s += '<TR><TD NOWRAP VALIGN="Top" CLASS="Layer">';
		s += child_shim;

		s += '<IMG SRC="' + _cache.iconHSibling.src + '"'  + _cache.strIconSize + '>';

		var vis = this.getVisible();
		if (vis == 0)
			s += '<IMG SRC="' + _cache.iconHidden.src + '"' + _cache.strIconSize + ' onmousedown="t.toc.onVisibleClick(' + this.tocid + ',1);" alt="Click to show layer">';
		else if (vis == 1)
			s += '<IMG SRC="' + _cache.iconVisible.src + '"' + _cache.strIconSize + ' onmousedown="t.toc.onVisibleClick(' + this.tocid + ',0);" alt="Click to hide layer">';
		else
			s += '<IMG SRC="' + _cache.iconTristate.src + '"' + _cache.strIconSize + ' onmousedown="t.toc.onVisibleClick(' + this.tocid + ',1);" alt="Click to show layer">';

		s += '<A CLASS="Layer" HREF="javascript:t.toc.onCaptionClick(' + this.tocid + ')">&nbsp;' + this.caption + '</A>';

		s += '</TD></TR>';

		return s;
	}
	return this;
}

function LAYERWS(name,caption,swatch,legend,labelField) {
	var lyr = new LAYER(name,caption,swatch,legend,labelField);
	inherit(this,lyr);
	this.shadow = null;

	// override LAYER init
	this.init = function() {
		this.zuper.init();
		this.index = this.zuper.index; // primitive hack
		if (this.shadow)
			this.shadow.init(); // must manually init shadow since not known in toc
	}

	this.addShadow = function(shadow) {
		this.shadow = shadow;
	}

	this.setVisible = function(value) {
		LayerVisible[this.index] = value;
		if (this.shadow)
			LayerVisible[this.shadow.index] = value;
	}

	this.toggleVisible = function() {
		LayerVisible[this.index] = 1 - LayerVisible[this.index];
		if (this.shadow)
			LayerVisible[this.shadow.index] = 1 - LayerVisible[this.shadow.index];
	}

	return this;
}

function inherit(sub,zuper) {
	sub.zuper = zuper;
	for (var i in zuper) {
		sub[i] = zuper[i];
	}
	return sub;
}

function LAYERWSM(name,caption,swatch,legend,labelField) {
	var lyr = new LAYER(name,caption,swatch,legend,labelField);
	inherit(this,lyr);
	this.shadows = new Array();

	// override LAYER init
	this.init = function() {
		this.zuper.init();
		this.index = this.zuper.index; // primitive hack
		for (var i=0, n=this.shadows.length; i<n; i++)
			this.shadows[i].init(); // must manually init shadow since not known in toc
	}

	this.addShadow = function(shadow) {
		this.shadows[this.shadows.length] = shadow;
	}

	this.setVisible = function(value) {
		LayerVisible[this.index] = value;
		for (var i=0, n=this.shadows.length; i<n; i++)
			LayerVisible[this.shadows[i].index] = value;
	}

	this.toggleVisible = function() {
		LayerVisible[this.index] = 1 - LayerVisible[this.index];
		for (var i=0, n=this.shadows.length; i<n; i++)
			LayerVisible[this.shadows[i].index] = LayerVisible[this.index]; // toggle? no. sync to master
	}

	return this;
}
