//---------------------------------------------------------------
// dbgtCode.js v.1.4
// Copyright (C) 2002 David Bollinger (davebollinger@hotmail.com)
//
// Support code for the "dbGroupToc" modification - A grouped
// table of contents for ArcIMS 3.1+ HTML viewer sites.
//
// Notice: This code may be freely distributed, used and
//         modified provided that this comment remains intact.
//---------------------------------------------------------------

//--------------------
// UNIQUE ID GENERATOR
//--------------------

var _nextTocID = 0;

function getNextTocID() {
	var id = _nextTocID;
	_nextTocID = _nextTocID + 1;
	return id;
}


//-----------------
// RESOURCE
//-----------------

function RESOURCE(name) {
	this.name = name;
}


//-----------------
// TOC
//-----------------

function TOC(title,name,autoRefreshMap) {
	// PROPERTIES
	this.title = title || 'LAYERS';
	this.name = name || title || 'LAYERS';
	this.root = new GROUP(name,true);
	this.isInited = false;
	this.divToc = null;
	this.divTocHelp = null;
	this.autoRefreshMap = autoRefreshMap || false;
	// METHODS
	this.init = TOC_init;
	this.setOutput = TOC_setOutput;
	this.addItem = TOC_addItem;
	this.addGroup = this.addItem; // for compatibility with previous versions of dbgtData.js
	this.addLayer = this.addItem; // for compatibility with previous versions of dbgtData.js
	this.onFolderClick = TOC_onFolderClick;
	this.onLayerClick = TOC_onLayerClick;
	this.onVisibleClick = TOC_onVisibleClick;
	this.onActiveClick = TOC_onActiveClick;
	this.onSwatchClick = TOC_onSwatchClick;
	this.onNameClick = TOC_onNameClick;
	this.onLabelClick = TOC_onLabelClick;
	this.refresh = TOC_refresh;
	this.refreshMap = TOC_refreshMap;
	this.writeHTML = TOC_writeHTML;
	this.writeHelpHTML = TOC_writeHelpHTML;
}

function TOC_init() {
	this.root.init();
	this.isInited = true;
}

function TOC_setOutput( divToc, divTocHelp ) {
	this.divToc = divToc;
	this.divTocHelp = divTocHelp;
}

function TOC_addItem(item) {
	return this.root.addItem(item);
}

function TOC_onFolderClick(tocid) {
	var item = this.root.findItemByTocID(tocid);
	if (item) item.toggleOpened();
	// customization note:
	// opportunity here to cascade and do a "deep open"
	// so that all child folders are opened too
	this.refresh();
}

function TOC_onLayerClick(tocid) {
	var item = this.root.findItemByTocID(tocid);
	if (item) item.setActive();
	// customization note:
	// currently is essentially the same function as onNameClick for a layer,
	// see notes in onNameClick for other ideas, all sorts of possible things
	// you might want to do in response to this event, or draw a question mark
	// on top of the layer icon and use this event to start up a query for this layer,
	// etc.
	this.refresh();
}

function TOC_onVisibleClick(tocid,value) {
	var item = this.root.findItemByTocID(tocid);
	if (item instanceof GROUP)
		item.setVisible(value);
	else if (item instanceof LAYER)
		item.toggleVisible();
	// customization note:
	// opportunity here to hide other layers within this layer's
	// group to create a "only one visible at a time" group
	this.refresh();
	this.refreshMap();
}

function TOC_onActiveClick(tocid) {
	var item = this.root.findItemByTocID(tocid);
	if (item) item.setActive();
	// customization note:
	// opportunity here to also force active layer visible
	this.refresh();
}

function TOC_onSwatchClick(tocid) {
	var item = this.root.findItemByTocID(tocid);
	// NO DEFAULT ACTION
	// customization note:
	// possible uses:	change renderer, enable labels, etc.
}

function TOC_onNameClick(tocid) {
	var item = this.root.findItemByTocID(tocid);
	if (item instanceof GROUP)
		item.toggleOpened();
	else if (item instanceof LAYER)
		item.setActive();
	// customization note:
	// alternatively, use the name click to pop open a window with metadata
	// example:	window.open('http://server/website/metadata/' + item.name + '.htm', 'InfoWindow', '');
	// or call showLayerInfo(this.index);
	this.refresh();
}

function TOC_onLabelClick(tocid) {
	var item = this.root.findItemByTocID(tocid);
	if (item) item.toggleLabel();
	// customization note:
	// possible uses:	enable label renderer or related annotation layer, etc.
	this.refresh();
	// customization note:
	// once you've added sufficient support code, you'll then also want to check for a map refresh...
	// this.refreshMap();
}

function TOC_refresh() {
	if (this.divToc != null)
		this.divToc.innerHTML = this.writeHTML();
	if (this.divTocHelp != null)
		this.divTocHelp.innerHTML = this.writeHelpHTML();
}

function TOC_refreshMap() {
	// called by other routines that have reason to refresh the map
	// this routine then determines if it actually should refresh map
	if ((this.autoRefreshMap) & (okToSend))
		sendMapXML();
}

function TOC_writeHTML() {
	var s = "";
	if (!this.isInited)
		this.init();

	//------
	// TITLE
	//------
	//s += '<CENTER><P CLASS="LayerListTitle">' + this.title + '<BR>';

	//-------------------
	// START OF TOC TABLE
	//-------------------
	s += '<TABLE WIDTH="300" BORDER="0" CELLSPACING="0" CELLPADDING="0" NOWRAP>';

	//--------
	// CASCADE
	//--------
	s += this.root.writeHTML('','');

	//-----------------
	// END OF TOC TABLE
	//-----------------
	s += '</TABLE><BR></CENTER>';
	return s;
}

function TOC_writeHelpHTML() {
	var s = '';
	s += '<BR><BR><CENTER>Help:<BR><DIV	CLASS="LayerListHelp" ALIGN="left" NOWRAP>';
	s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconClosed + '"> A closed group, click to open.<BR>';
	s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconOpened + '"> An open group, click to close.<BR>';
	s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconLayer + '"> A map layer.<BR>';
	s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconHidden + '"> A hidden group/layer, click to make visible.<BR>';
	s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconVisible + '"> A visible group/layer, click to hide.<BR>';
	s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconVisscale + '"> A visible layer, but not at this scale.<BR>';
	s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconTristate + '"> A partially visible group, click to make visible.<BR>';
	s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconInactive + '"> An inactive layer, click to make active.<BR>';
	s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconActive + '"> The active layer.<BR>';
	s += '</DIV></CENTER>';
	return s;
}

//-----------------
// ITEM
//-----------------

function ITEM(obj,name) {
	obj.parent = null;
	obj.tocid = getNextTocID();
	obj.name = name || '';
	obj.findItemByTocID = ITEM_findItemByTocID;
	obj.setActive = ITEM_setActive;
	obj.toggleLabel = ITEM_toggleLabel;
	obj.getVisible = ITEM_getVisible;
	obj.setVisible = ITEM_setVisible;
	obj.toggleVisible = ITEM_toggleVisible;
}

function ITEM_findItemByTocID(tocid) {
	if (this.tocid == tocid)
		return this;
	if (this instanceof GROUP)
		for (var i=0, n=this.items.length; i<n; i++) {
			var item = this.items[i].findItemByTocID(tocid);
			if (item) return item;
		}
	return null;
}

function ITEM_setActive() {
	if ((this instanceof LAYER) && (LayerIsFeature[this.index])) {
		setActiveLayer(this.index);
		var isOk = checkHyperLinkLayer(this.index);
		if (toolMode==15) {
			if (!isOk) {
				currentHyperLinkLayer='';
				currentHyperLinkField='';
				currentHyperLinkPrefix='';
				currentHyperLinkSuffix='';
				alert('This layer does not have any Hyperlinks.');
			}
		}
	} else { // GROUP
		// customization note:
		// group-level setActive not currently supported
		// (though might be useful as part of a modified identify-all tool)
	}
}

function ITEM_toggleLabel() {
	if (this instanceof LAYER) {
		this.labelled = !this.labelled;
		// customization note:
		// this is where you need to actually implement
		// something which turns on/off labels
	} else { // GROUP
		for (var i=0, n=this.items.length; i<n; i++)
			this.items[i].toggleLabel();
	}
}

function ITEM_getVisible(value) {
	if (this instanceof LAYER) {
		return LayerVisible[this.index];
	} else { // GROUP
		for (var i=0, n=this.items.length, v=0; i<n; i++)
			v += this.items[i].getVisible(value);
		return (v==0) ? 0 : (v==n) ? 1 : 99999; // 99999=tristate
	}
}

function ITEM_setVisible(value) {
	if (this instanceof LAYER) {
		LayerVisible[this.index] = value;
	} else { // GROUP
		for (var i=0, n=this.items.length; i<n; i++)
			this.items[i].setVisible(value);
	}
}

function ITEM_toggleVisible() {
	if (this instanceof LAYER) {
		LayerVisible[this.index] = 1 - LayerVisible[this.index];
	} else { // GROUP
		for (var i=0, n=this.items.length; i<n; i++)
			this.items[i].toggleVisible();
	}
}


//-----------------
// GROUP
//-----------------

function GROUP(name,opened) {
	// INHERITED CONSTRUCTOR
	ITEM(this,name);
	// PROPERTIES
	this.opened = opened || false;
	this.items = new Array();
	// METHODS
	this.init = GROUP_init;
	this.addItem = GROUP_addItem;
	this.addLayer = this.addItem; // for compatibility with previous versions of dbgtData.js
	this.addGroup = this.addItem; // for compatibility with previous versions of dbgtData.js
	this.toggleOpened = GROUP_toggleOpened;
	this.writeHTML = GROUP_writeHTML;
}

function GROUP_init() {
	for (var i=0, n=this.items.length; i<n; i++) {
		this.items[i].init();
	}
}

function GROUP_addItem(item) {
	item.parent = this;
	this.items[this.items.length] = item;
	return item;
}

function GROUP_toggleOpened() {
	this.opened = !this.opened;
}

function GROUP_writeHTML(child_shim, sibling_shim) {
	var s = "";

	//-------------------
	// START OF GROUP ROW
	//-------------------
	s += '<TR><TD NOWRAP VALIGN="CENTER">';

	//------------------------
	// FIRST COL = FOLDER ICON
	//------------------------
	s += child_shim;
	if (this.opened)
		s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconOpened + '" onclick="t.toc.onFolderClick(' + this.tocid + ');" alt="Click to close">';
	else
		s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconClosed + '" onclick="t.toc.onFolderClick(' + this.tocid + ');" alt="Click to open">';

	//------------------------------
	// SECOND COL = VISIBLE CHECKBOX
	//------------------------------
	var vis = this.getVisible();
	if (vis == 0)
		s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconHidden + '" onclick="t.toc.onVisibleClick(' + this.tocid + ',1);" alt="Click to show">';
	else if (vis == 1)
		s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconVisible + '" onclick="t.toc.onVisibleClick(' + this.tocid + ',0);" alt="Click to hide">';
	else
		s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconTristate + '" onclick="t.toc.onVisibleClick(' + this.tocid + ',1);" alt="Click to show">';

	//-------------------------
	// THIRD+ COLS = GROUP NAME
	//-------------------------
	s += '<A HREF="javascript:t.toc.onNameClick(' + this.tocid + ')">' + this.name + '</A>';

	//-----------------
	// END OF GROUP ROW
	//-----------------
	s += '</TD></TR>';

	//--------
	// CASCADE
	//--------
	if (this.opened) {
		for (var i=0, n=this.items.length; i<n; i++) {
			var new_child_shim = sibling_shim + '<img src="' + dbgtResource.iconPath
				+ ((i==n-1) ? dbgtResource.iconChildLast : dbgtResource.iconChild) + '">';
			var new_sibling_shim = sibling_shim + '<img src="' + dbgtResource.iconPath
				+ ((i==n-1) ? dbgtResource.iconBlank : dbgtResource.iconSibling) + '">';
			s += this.items[i].writeHTML( new_child_shim, new_sibling_shim );
		}
	}

	return s;
}


//-----------------
// LAYER
//-----------------

function LAYER(name,swatch,legend,labelField) {
	// INHERITED CONSTRUCTOR
	ITEM(this,name);
	// PROPERTIES
	this.index = -1;
	this.swatch = swatch || '';
	this.legend = legend || '';
	this.labelField = labelField || '';
	this.labelled = false;
	// METHODS
	this.init = LAYER_init;
	this.writeHTML = LAYER_writeHTML;
}

function LAYER_init() {
	for (var i=0, n=LayerName.length; i<n; i++)
		if (LayerName[i] == this.name) {
			this.index = i;
			return;
		}
	if (debugOn > 0)
		alert('Error in dbgtCode.js.\nUnable to get layer index for "' + name + '".	Check toc definition.');
}


function LAYER_writeHTML(child_shim, sibling_shim) {
	var s = '';

	//-------------------
	// START OF LAYER ROW
	//-------------------
	var highlight = (ActiveLayerIndex == this.index) ? ' CLASS="Highlight"' : '';
	s += '<TR' + highlight + '><TD NOWRAP>';

	//----------------
	// CONNECTING LINE
	//----------------
	s += child_shim;
	s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconLayer + '" onclick="javascript:t.toc.onLayerClick(' + this.tocid + ');" alt="" >';

	//--------------------
	// VISIBILITY CHECKBOX
	//--------------------
	if (LayerVisible[this.index]) {
		if ((mapScaleFactor>=LayerMinScale[this.index]) && (mapScaleFactor<=LayerMaxScale[this.index])) {
			s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconVisible + '" onclick="t.toc.onVisibleClick(' + this.tocid + ');" alt="Click to hide">';
		} else {
			s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconVisscale + '" onclick="t.toc.onVisibleClick(' + this.tocid + ');" alt="Click to hide">';
		}
	} else {
		s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconHidden + '" onclick="t.toc.onVisibleClick(' + this.tocid + ');" alt="Click to hide">';
	}

	//----------------
	// ACTIVE RADIOBOX
	//----------------

	// customization note:
	// if you keep the active layer highlight and are content to leave the layer name click
	// event behaviour as "set active" then this radio is redundant and could be removed

	if (LayerIsFeature[this.index]) {
		if (ActiveLayerIndex == this.index) {
			s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconActive + '">';
		} else {
			s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconInactive + '" onclick="t.toc.onActiveClick(' + this.tocid + ');" alt="Click to make active">';
		}
	} else {
		// customization note:
		// this blank is desirable if feature and image layers are mixed
		// within a single group in order to maintain horizontal alignment,
		// otherwise may safely be commented out
		s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconBlank + '">';
	}

	//-------------
	// SWATCH IMAGE
	//-------------
	if (this.swatch != "") {
		s += '<IMG SRC="' + dbgtResource.swatchPath + this.swatch + '" onclick="t.toc.onSwatchClick(' + this.tocid + ');" alt="">';
	} else {
		// customization note:
		// may want to insert an iconBlank here to keep layer names
		// aligned if you have a mix of layers some with swatches
		// and some without, otherwise by default we insert nothing
		// here (assuming either all layers have swatches or none
		// have swatches) in order to conserve horizontal space in
		// swatch-less tocs.
	}

	//-----------
	// LAYER NAME
	//-----------
	s += '<A HREF="javascript:t.toc.onNameClick(' + this.tocid + ');">' + this.name + '</A>';

	//-------------
	// LABEL TOGGLE
	//-------------
	if (this.labelField != "") {
		var labelicon = (this.labelled) ? dbgtResource.iconLabelOn : dbgtResource.iconLabelOff;
		s += '<IMG SRC="' + dbgtResource.iconPath + labelicon + '" onclick="t.toc.onLabelClick(' + this.tocid + ');" alt="Toggle Labels">';
	}

	//-----------------
	// END OF LAYER ROW
	//-----------------
	s += '</TD></TR>';

	//--------------------
	// OPTIONAL LEGEND ROW
	//--------------------
	if (this.legend != "") {
		s += '<TR><TD NOWRAP>' + sibling_shim; // connecting lines
		s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconBlank + '">'; // layer icon
		s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconBlank + '">'; // visible checkbox
		s += '<IMG SRC="' + dbgtResource.iconPath + dbgtResource.iconBlank + '">'; // active radio
		s += '<IMG SRC="' + dbgtResource.legendPath + this.legend + '">'; // line up legend with swatch
		s += '</TD></TR>';
	}

	return s;
}

//-----------------
// eof
//-----------------