/*******************************************************************************
 *
 *	JS QueryResult Class
 *
 *	Note that this needs to be loaded before jsLayer.js.
 *
 ******************************************************************************/
 

 
//	GLOBALS
var qResultMgr			= new queryResultMgr();




/***************************************************************************
 *	GENERAL FUNCTIONS
 *
 */

/*
 *	@parm	Date	theDate		(javascript Date object)
 *	@return	string				HH:MM:SS
 */
Date.prototype.getTimeStamp = function() {
	var sec = (this.getSeconds()<10)	? "0" + this.getSeconds().toString()	: this.getSeconds();
	var min = (this.getMinutes()<10)	? "0" + this.getMinutes().toString()	: this.getMinutes();
//	var hrs = (this.getHours()<10)		? "0" + this.getHours().toString()		: this.getHours();
	var hrs = this.getHours();			//	Don't add a leading 0 for hours.
	if (hrs>12) {
		var timeOfDay = 'pm';
		hrs -= 12;
	} else {
		var timeOfDay = 'am';
	}
//	return hrs + ":" + min + ":" + sec + timeOfDay;
	return hrs + ":" + min + timeOfDay;											//	Don't display seconds.
}


/*	isNumeric
 *	
 *	Tests to see if the text string is all numbers.
 *
 *	This is used to process the string results from QueryResults to determine if they're
 *	all numbers.  If they are all numbers, this will return true.
 *
 *	@param	string	$text	
 *	@return	boolean
 */
function isNumeric( text ) {
	result = text.search( /[^0-9]/ );
//	alert (result);
	if (result > -1 ) {	//	Found non-numeric number
		return false;
	} else {
		return true;
	}
}

/*	NumberFormat
 *	
 *	Adds commas to make numbers human-readable.  e.g. '1234567' becomes '1,234,567'
 *	This will test to see if text is all digits.  If it isn't, then text will be returned unformatted.
 *
 *	This is expecting 'text' as a string.
 *
 *	@param	string	text	
 *	@return	string
 */
function NumberFormat( text ) {
	var numString = text.toString();	//	Make sure this is a string
	if ( !isNumeric( numString ) ) {
		return text;
	}
	
	var result = '';
	var startIndex;
	var part	= numString.split('.');		//	Just in case this is a decimal
	var u		= part[0].length;
	for (var i=u; i>=0; i=i-3) {
		startIndex = i-3;
		if (i > 3) {
			result = "," + numString.substring(i-3, i) + result;
		} else {
			result = numString.substring(0, i) + result;
		}
	}
	return result;
}


/*
 *	!!! DEPRECATED in favor of AddLinkOpeners() !!!
 *
 *	ConvertLinksToChildWindow
 *
 *	Used to add a "target" parameter to links (A HREF) so that the link can be opened in a different window.
 *	If there is an existing "target" parameter, we replace it.
 *	If no link is found, it just returns text without modification.
 *
 *	@parm	string		text			String to be displayed
 *	@parm	string		target			Name of the target window
 *	@return	string						HTML link with target set to target
 */
/*function ConvertLinksToChildWindow( text, target ) {
	
	var ahrefWholeTagRegExp		= /\<a\s+?href\b[^\>]*\>(.*?)\<\/a\>/i ;		//	Match the whole <a href> and end <\/a> tag.
	var ahrefFrontRegExp		= /\<a\s+?href\b[^\>]*\>/i ;					//	Match just the <a href> (and not the end <\/a> tag).
	var targetInAhrefRegExp		= /\<a\s+?href\b[^\>]*target\b[^\>]*\>/i ;		//	Match the target tag w/in the <a href>
	var targetRegExp			= /target\s*?=\s*?[\'\"].*?[\'\"]/i ;			//	Match the target tag w/in the <a href>
	
	//	Is there a link in the text?
	if ( text.search( ahrefWholeTagRegExp ) ==-1 ) {			
		//	No Link in the text, so just return the text without modification
		linktext = text;
	} else {
		//	Link Exists!  Modify it!
		
		//	grab the <a href> tag
		var ahrefTag		= text.match( ahrefFrontRegExp ).toString();
		//	grab everthing after <a href>
		var restOfTag		= text.substring( ahrefTag.length );
		//	set the new target string
		var newTargetStr	= 'target="' + target + '"';
		
		//	Is there an existing "target" parameter?
		if ( text.search(   targetInAhrefRegExp   ) > -1) {
			//	"target" already defined, so replace the "target" in the <a href> part
			linktext = ahrefTag.replace( targetRegExp, newTargetStr ) + restOfTag;			
		} else {
			//	Insert a new target
			linktext = ahrefTag.slice(0,ahrefTag.length-1) + " " + newTargetStr + ">" + restOfTag;
		}
	}
//	alert( 'result = ' + linktext );
	return linktext;
}*/
 

/*
 *	AddLinkOpeners
 *
 *	Used to add a "target" parameter to links (A HREF) so that the link can be opened in a different window.
 *	Walks down the DOM looking for TDs whose class="itemData" and adds an onClick function.
 *	Call this AFTER the QueryHistory has loaded to process the links.
 *	Currently called by loadMgr.js.
 *
 *	@parm	string		target			Name of the target window
 *	@return	string						HTML link with target set to target
 */
function AddLinkOpeners(target) {
	var e, url, ahrefs, fn;	//	element
	
	var className = isIE ? "className": "class"; 								//	Needed for the getAttributes

	var tds = document.getElementsByTagName( "td" );
	var u	= tds.length;
	for (var i=0; i<u; i++ ) {
		if (tds[i].getAttribute(className) &&										
			tds[i].getAttribute(className) == "itemData" ) {						//	Make sure attribute exists before checking the value.
			//	See if the element has a link in it
			ahrefs	= tds[i].getElementsByTagName( "a" );
			var au	= ahrefs.length;
			for (var j=0; j<au; j++) {
				SetAttribute( ahrefs[j], 'target', '_blank' );
			}			
		}
	}
}

/*
 *	SetAttribute
 *	
 *	This is the safe way to set an attribute.  It creates the attribute first
 *	so that IE won't choke on an empty attribute.
 */
function SetAttribute( element, attributeName, attributeValue ) {
	element.setAttribute( attributeName, '');
	element[attributeName] = attributeValue;
}
/***************************************************************************
 *	QUERYRESULT MANAGER CLASS
 *
 */
function queryResultMgr() {
	var self				= this;
	
	this.maps = new Array();	//	Array of queryResults
	
	/*
	 *
	 *	This reads the query from the layerMgr object that is passed in.
	 *
	 *	@param	layerMgr		lMgr
	 */
	this.loadFromLegendMgr = function( legendMgr, selectedLegendLayer, urlQueryString, mapDate, currentCmdStr, latlon ) {
Debug('loadFromLegendMgr: setting selectedLegendLayer to ' + selectedLegendLayer );
		self.addMap( legendMgr.getQueryResults(), selectedLegendLayer, urlQueryString, mapDate, currentCmdStr, latlon );
	}


	/*	@parm	queryResultsMap	newQuery
	 */
	this.addMap = function( newQueryResultsMap, selectedLegendLayer, urlQueryString, mapDate, currentCmdStr, latlon ) {
		var currentTime = new Date();
		newQueryResultsMap.id		= currentTime.getTimeStamp();
		newQueryResultsMap.mapDate	= mapDate;
		newQueryResultsMap.setMainDataIndex( selectedLegendLayer );
		newQueryResultsMap.setURLQueryString( urlQueryString );
		newQueryResultsMap.currentCmdStr = currentCmdStr;
		newQueryResultsMap.latlon = latlon;
		self.maps.push( newQueryResultsMap );
	}
	
	
	this.initListeners = function() {
		var qt = document.getElementById( 'queryTable' );
		addEvent(qt, 'mouseover', self.handleMouseOver, false);		//	Can't use css "hover" here b/c IE doesn't support hover in Tables
		addEvent(qt, 'mouseout', self.handleMouseOut, false);			//	Can't use css "hover" here b/c IE doesn't support hover in Tables
	}
	this.handleMouseOver = function( event ) {
		//	Select the row
		var selectedRow = ascendDOM( GetElementFromEvent(event), 'tr');
		if (selectedRow.nodeName.toLowerCase() == 'tr') {
			//	Only hover if this is a queryHistoryRow
			//	This is needed to prevent an IE bug where rows in the legendTable are also selected.
			if (selectedRow.className.indexOf('queryHistoryRow') > -1) {
				selectedRow.className += ' hover';
			}
		}
	}
	this.handleMouseOut = function( event ) {
		//	Select the row
		var selectedRow = ascendDOM( GetElementFromEvent(event), 'tr');
		if (selectedRow.nodeName.toLowerCase() == 'tr') {
			selectedRow.className = selectedRow.className.replace(' hover','');
		}
	}
	
	
	this.setURLQueryString = function( newQueryString ) {
		self.URLQueryString = newQueryString;
		alert( 'URLQueryString being set to ' + newQueryString );
	}
	
	
	this.getHTML = function(width, showSelectedOnly) {
		var s = '';
		var showLabel = true;
		var lastCmdObject;
		var lastCmd;
		var layerLabel;
		
		s += '<table id="queryTable" width="' + width + 'px" cellpadding="2" cellspacing="1">';
		s += '<tr><td colspan="4" class="legendTitle">QUERY HISTORY</td></tr>';
		s += '<tr class="legendRow">';
		s +=	'<th width="35px">Time</th>';
//		s +=	'<th width="35px">Lat/Lon</th>';
		s +=	'<th width="35px">Year</th>';
		s +=	'<th width="100px">Layer</th>';
		s +=	'<th width="60%">Selected Data</th>';		
		s += '</tr>';
		
		var u = self.maps.length - 1 ;
		for (var i=u; i>=0; i--) {												//	Walk down backwards to get most recent first
			if (i==u) {
				showLabel = true;
				s += '<tr class="queryHistoryRow hilite" id="mostRecentQueryResult">';
			} else {				
				showLabel = false;
				s += '<tr class="queryHistoryRow">';
			}
			lastCmdObject	= document.getElementById('lastCmd');
			lastCmd			= lastCmdObject.innerHTML;
			
			layerLabel		= GetLayerLabelFromTimelineData( self.maps[i].mainDataIndex );

			s +=	'<td style="vertical-align:bottom;"><a href="#" onclick="DoSubmitWithURL(\'m1\',\'' + self.maps[i].URLQueryString +'\')">' + self.maps[i].id + '</a></td>';
//			s +=	'<td style="vertical-align:bottom;"><a href="#" onclick="DoSubmitWithURL(\'m1\',\'' + self.maps[i].URLQueryString +'\')">' + self.maps[i].latlon  + '</a></td>';
			s +=	'<td style="vertical-align:bottom; text-align:right;">' + self.maps[i].mapDate  + '</td>';
			s +=	'<td style="vertical-align:bottom;">' + layerLabel + '</td>';
			s +=	'<td style="vertical-align:bottom;">' + self.maps[i].getHTML( showSelectedOnly, showLabel ) + '</td>';		
			s += '</tr>';
		}
		
		s += '</table>';
		
		return s;
	}
}


/***************************************************************************
 *	QUERYRESULT CLASS
 *
 */
function queryResultsMap() {
	var self				= this;
	
	this.id;					//	String		Unique identifier.  Use current time by default?
	this.lat;					//	Float		
	this.lon;					//	Float
	this.mapDate;				//	String
	
	this.mainDataIndex;			//	String		Index of the main data item (the queryResultObject that is the selected query that the student requested)
	
	this.URLQueryString = '';	//	String		The query parameters for this map. Used to generate a clickable URL in the query history.
	
	this.layers = new Array();	//	Array of queryResultItems
	
	
	this.setMainDataIndex = function( newIndex )	{ self.mainDataIndex = newIndex; }
	
	
	/*
	 *
	 * @param	queryResultsLayer		newItem
	 */
	this.addLayer = function( newQueryResultsLayer ) {
		self.layers.push( newQueryResultsLayer );
	}
	
	this.setURLQueryString = function( newURLQueryString ) {
		self.URLQueryString = newURLQueryString;
	}
	
	//	Use DIV instead of table
	this.getHTML = function( showSelectedOnly, showLabel ) {
		var s = '';
		
		var u = self.layers.length;
		for (var i=0; i<u; i++) {
			if (self.layers[i] != null) {
				if ( (!showSelectedOnly) || (showSelectedOnly && (self.layers[i].layerID == self.mainDataIndex)) ) {
					var itemsHTML = self.getItemsHTML( self.layers[i].getItems(), showLabel );
					if (itemsHTML != '') {
						s +=	itemsHTML;		
					}
				} else {
					//	Don't show anything.
					//s += '<tr><td>layerID='+self.layers[i].layerID+' mainDataIndex='+self.mainDataIndex+'</td>';
				}
			}
		}
		
		return s;
	}
/* working: using table
	this.getHTML = function( showSelectedOnly, showLabel ) {
		var s = '';
		
		s += '<table width="100%" border="0" cellpadding="0" cellspacing="0">';
		
		var u = self.layers.length;
		for (var i=0; i<u; i++) {
			if (self.layers[i] != null) {
				if ( (!showSelectedOnly) || (showSelectedOnly && (self.layers[i].layerID == self.mainDataIndex)) ) {
					var itemsHTML = self.getItemsHTML( self.layers[i].getItems(), showLabel );
					if (itemsHTML != '') {
						s += '<tr>';
						//s +=	'<td class="rangeLabel">' + self.layers[i].layerID + '</td>';
						s +=	'<td>' + itemsHTML + '</td>';		
						s += '</tr>';
					} else {					
						s += '<tr><td>n/a</td></tr>';			
					}
				} else {
					//	Don't show anything.
					//s += '<tr><td>layerID='+self.layers[i].layerID+' mainDataIndex='+self.mainDataIndex+'</td>';
				}
			}
		}
		
		s += '</table>';
		
		return s;
	}
*/
	//	Use DIVs instead of table
	this.getItemsHTML = function( items, showLabel ) {
		var s = '';
		var units = '';
		if (items != null) {
			var u = items.length - 1;

			//	Label
			for (var i=u; i>=0; i--) {
				s += '<div class="querydataLabel" style="float:left; width:' + (100/(u+1)) + '%;">' + items[i].label + '</div>';
			}
			s += '<br>';

			//	Data
			for (var i=u; i>=0; i--) {
				if (i==0) {
					units = items[i].units;		//	Show units for the last value
				}
				s += '<div class="itemData" style="float:left; width:' + (100/(u+1)) + '%;">' + NumberFormat( items[i].data ) + ' ' + units + '</div>';
//				s += '<td width="' + (100/u) + '%" class="itemData">' + NumberFormat( items[i].data ) + ' ' + units + '</td>';
			}
		} else {
			s = 'getItemsHTML: items was null.  items=' + items;
		}
		return s;
	}
/*working using table
	this.getItemsHTML = function( items, showLabel ) {
		var s = '<table class="querydataTable" width="100%" border="0" cellpadding="0" cellspacing="0">';
		var units = '';
		if (items != null) {
			var u = items.length - 1;

			//	Label
			s += '<tr>';
			for (var i=u; i>=0; i--) {
				s += '<td><div class="querydataLabel">' + items[i].label + '</div></td>';
			}
			s += '</tr>';


			//	Data
			s += '<tr>';
			for (var i=u; i>=0; i--) {
				if (i==0) {
					units = items[i].units;		//	Show units for the last value
				}
				s += '<td width="' + (100/(u+1)) + '%" class="itemData">' + NumberFormat( items[i].data ) + ' ' + units + '</td>';
//				s += '<td width="' + (100/u) + '%" class="itemData">' + NumberFormat( items[i].data ) + ' ' + units + '</td>';
			}
			s += '</tr>';
		} else {
			s = 'getItemsHTML: items was null.  items=' + items;
		}
		return s + '</table>';
	}
*/
/*orig	this.getItemsHTML = function( items ) {
		var s = '';
		if (items != null) {
			var u = items.length;
			for (var i=0; i<u; i++) {
				s += items[i].label + ': ' + items[i].data + '<br>';
			}
		} else {
			s = 'getItemsHTML: items was null.  items=' + items;
		}
		return s;
	}*/
}



/*
 *	These two classes usually don't have to be instantiated via js
 *	b/c they're created directly from the JSON object.  
 *	They're defined here for documentation purposes primarily.
 *
 */


function queryResultsLayer() {
	var self			= this;
	
	this.layerName		= '';						//	String		Unique identifier
	this.items			= new Array();				//	Array of queryResultItems
	
	this.getItems		= function() { return this.items; }
	
	this.addItem		= function( newItem ) { 
		self.items.push( newItem ); 
//Debug('new length = ' + self.items.length + ' newItem = ' + self.items[self.items.length-1]);
	}
	
	/*	qrArray comes in with this form:
	 *		Layerarray(	Marker0array( label, data),
	 *					Marker1array( label, data),
	 *					Marker2array( label, data)
	 *				)
	 *
	 *	We're currently ignoring markers 1 and 2.
	 */
	this.loadFromArray	= function( qrArray ) {
		var lyrResult;
		
		var u = qrArray.length;
//		for (var i=0; i<u; i++) {
// debug.  i = markerPoint Index.  Since we're currently only using one markerpoint, set i to 0 only (the first markerpoint)
var i = 0;
			lyrResult	= qrArray[i];
			if (lyrResult != null) {
				self.layerID	= lyrResult.layerID;
//Debug( 'lyrResult.items = ' + lyrResult.items);
				if (lyrResult.items != null) {
//Debug( 'lyrResult.items.length = ' + lyrResult.items.length);
					for (var j=0; j<lyrResult.items.length; j++) {
						var qri = new queryResultItem();
						qri.label	+= lyrResult.items[j].label;						//	This is a hack.  Since we might be 
						qri.data	+= lyrResult.items[j].data;
						qri.units	+= lyrResult.items[j].units;
						qri.latlon	+= lyrResult.items[j].latlon;
//Debug( 'lyrResult.items[j].label = ' + qri.label + ' lyrResult.items[j].data = ' + qri.data );
	//					qrl.items = qri;
	//Debug( 'qrl.items = ' + qrl.items);// + ' qrl.items.length = ' + qrl.items.length );
						self.addItem( qri );
//Debug( 'qrl.id = ' + qrl.id + ' qrl.items = ' + qrl.getItems() );// + ' qrl.items.length = ' + qrl.items.length );
					}			
				}
			}
//Debug( 'qrArray = ' + qrArray + ' len=' + qrArray.length + ' qrArray[0].id='+qrArray[0].id + ' qrl.id=' + qrl.id + ' qrl.items=' + qrl.items + ' qrl.items.length=' + qrl.items.length);
//Debug( 'queryResults.id=' + self.queryResults.id + ' queryResults.items = ' + self.queryResults.items);
//		}
	}
	
	/*	getFirstItemValue
	 *	Returns the first value of the first item.
	 *	The first item is the value used when creating a tickMark for the ramp.
	 *
	 *	@return		float		Returns null if there are no items.
	 */
	this.getFirstItemValue	= function(type) {
		if (self.items.length>0) {
			switch (type) {
			case 'float':
Debug('-- float = ' + self.items[0].data) + ' parseFloat= ' +  parseFloat( self.items[0].data );
				return parseFloat( self.items[0].data );
				break;
			case 'string':
Debug('-- string = ' + self.items[0].data);
				var results = self.items[0].data.split( '<br>' );
				if (results.length>0) return results[0];
				break;
			}
		}
		
		return null;
	}
}


function queryResultItem() {
	var self				= this;
	
	/*	Default to '' so that we can do a += operation on them. */
	this.layerName	= '';				//	String
	this.date		= '';				//	String
	this.label		= '';				//	String
	this.data		= '';				//	String
	this.units		= '';				//	String
}


