// 2008-06-15 JFC Converted to jQuery

String.prototype.trim = function() {
	return this.replace(/^\s+|\s+$/g,"");
}
String.prototype.ltrim = function() {
	return this.replace(/^\s+/,"");
}
String.prototype.rtrim = function() {
	return this.replace(/\s+$/,"");
}
String.prototype.right = function(len) {
	return this.substr(this.length-len);
}
String.prototype.left = function(len) {
	return this.substr(0,len);
}

// Namespace placeholder
ss = {};

// Initialize things
$(document).ready(
	function() {
		initPup();
		initPageToc();
		initQuote();
	}
);

function initPup() {
	// initPup() installs handlers the Pop-Up Pedigree buttons
	$(".pupbutton").click( pup );
}

function pup(e) {
	// pup() handles clicks on Pop-Up Pedigree buttons

	// Get the ID of the data element
	var $button = $(e.target);
	var partsID = $button.attr('id').replace(/pup/i, 'pupd');

	// Get the data and convert it into a table
	var sContent = getPupContent(partsID);

	// Add the new HTML to the pup element,
	// move it relative to button, and show it.
	var pos = $button.offset();
	$("#pup").html(sContent).css(
				{left: pos.left+'px', top: (pos.top+$button.height())+'px'}
			).show();
}

function getPupContent(partsID) {
	/* Initialize the arrays */
	var msg = "";
	var names = new Array(7);
	var stats = new Array(7);
	var links = new Array(7);
	var i, j;

	for (j=0; j<7; j++) {
		names[j] = "";
		stats[j] = "";
		links[j] = "";
	}

	// Get the data from the hidden DIV
	var sParts = $('#'+partsID).text();
	
	/* Fix some potential encoding issues */
	sParts = sParts.replace(/\\n/gi, '<br>');
	sParts = sParts.replace(/&lt;/gi, '<');
	sParts = sParts.replace(/&gt;/gi, '>');

	/* Parse the sParts into the things we need */
	var args = sParts.split("|");

	for (j=0, i=0; i<args.length && j<7;i++, j++) {
		names[j] = args[i++];
		if (names[j] == "") names[j]="&nbsp;";

		stats[j] = args[i++];

		if (args[i] != "") {
			links[j] = '<a href="'+args[i]+'">'+names[j]+'</A>';
		} else {
			links[j] = names[j];
		}
	}

	/* Start the content */
	var s1='<table><tbody>\n';

	/* Build the table from the parts */

	/* Row 1: 3 cells (0, 1, 3) */
	s1 += '<tr><td width="30%" rowspan="4" class="pupsubject">'+
			links[0]+'<br>'+stats[0]+'</td>';
	s1 += '<td width="30%" rowspan="2" class="pupmale">';
	s1 += links[1]+'<br>'+stats[1]+'</td>';
	s1 += '<td width="40%" class="pupmale">';
	s1 += links[3]+'<br>'+stats[3]+'</td></tr>\n';

	/* Row 2: 1 cell (4) */
	s1 += '<tr><td width="40%" class="pupfemale">'+links[4]+'<br>'+
			stats[4]+'</td></tr>\n';

	/* Row 3: 2 cells (2, 5) */
	s1 += '<tr><td width="30%" rowspan="2" class="pupfemale">'+links[2]
			+'<br>'+stats[2]+'</td>';
	s1 += '<td width="40%" class="pupmale">';
	s1 += links[5]+'<br>'+stats[5]+'</td></tr>\n';

	/* Row 4: 1 cell (6) */
	s1 += '<tr><td width="40%" class="pupfemale">'+links[6]+'<br>'+
			stats[6]+'</td></tr>\n';

	s1 += '<tr><td colspan="3"><input type="button" class="pupbutton" value="Close"'+
			' onclick="$(\'#pup\').hide();"></td></tr>\n';

	/* End the content */
	s1 += '</tbody></table>\n';

	return s1;
}

function initPageToc() {
	// The page "table of contents" creates a list of
	// h2 tags on the page if it finds an element with
	// the id "pagetoc". It only functions if
	// JavaScript is supported, and enabled, and if
	// the user has added HTML similar to the
	// following in one of the static content
	// sections:
	
	// <div id="pagetoc"><ul></ul></div>
	
	// 2007-04-06 JFC Now allows pagetoc on UL or OL, or on
	//                container DIV

	var $outerElement = $('#pagetoc');


	if ($outerElement.length>0) {
		var $tocElement = $outerElement.children("ul,ol").filter(":first");

		if ($tocElement.length==0) {
			$tocElement = $outerElement;
		}
		// Toggling display from none to block speeds
		// up execution, presumably because the browser
		// ignores the new content as it is being
		// added, and only computes locations, size, etc.
		// once at the end. That's just a guess based
		// on observing Firefox. If it actually isn't
		// faster, it seems like it, and that's good
		// enough for me in this case.
		$outerElement.hide();
		addPageToc($tocElement);
		$outerElement.show();
	}
}

function addPageToc($tocElement) {
	$('#content h2').each( function(index) {
		var eListElement = document.createElement('li');
		eListElement.className = 'toc'+this.tagName.toLowerCase();

		/* Get text of H2 and add to TOC as link */
		var sItemText = $(this).text();
		var nText = document.createTextNode(sItemText);
		var eLinkElement = document.createElement('a');
		eLinkElement.appendChild(nText);
		eListElement.appendChild(eLinkElement);

		/* Set ID of H2 node if it doesn't have one */
		if (!this.id) this.id = 't'+index;

		/* Set target of the A tag we are addingto ID of H2 */
		eLinkElement.href = '#' + this.id;
		$tocElement.append(eListElement);
	});
}

function initQuote() {
	// Initializes the "random quote" facility
	
	// <ul class="randomquote"><li> ... </li> etc. </ul>
	//      or
	// <div class="randomquote"><ul><li> ... </li> etc. </ul></div>

	$('ul.randomquote,div.randomquote ul').each( function() {
		pickQuote(this);
	});
	$('ul.randomquote,div.randomquote,div.randomquote ul').show();
}

function pickQuote(eUL) {
	// Hide all but one child (LI) element
	var $listItems = $(eUL).children('li');
	var iIndex = Math.round(Math.random()*($listItems.length-1));
	$listItems.hide();
	$listItems.eq(iIndex).show();
}

function hemlink(part1, part2) {
	var loc = '';

	loc = 'm'+"A"+"i";loc=loc+"l"+"to"+":";
	loc = loc.toLowerCase() + part1+"@"+part2;
	loc = loc+'?SUBJECT='+document.title;
	location.href=loc;
}

function hemlinknc(part1, part2) {
	var loc = '';

	loc = 'm'+"A"+"i";loc=loc+"l"+"to"+":";
	loc = loc.toLowerCase() + part1+"@"+part2;
	location.href=loc;
}

function tip(on_this, on_event, content) {
	return makeTrue(domTT_activate(on_this, on_event, 'content', content));
}

function tipcap(on_this, on_event, content, caption) {
	return makeTrue(domTT_activate(on_this, on_event, 'content', content, 'caption', caption));
}

/*
	parseUri 1.2.1
	(c) 2007 Steven Levithan <stevenlevithan.com>
	MIT License
*/
function parseUri (str) {
	var o = parseUri.options,
		m = o.parser[o.strictMode ? "strict" : "loose"].exec(str),
		uri = {},
		i = 14;

	while (i--) uri[o.key[i]] = m[i] || "";

	uri[o.q.name] = {};
	uri[o.key[12]].replace(o.q.parser, function ($0, $1, $2) {
		if ($1) uri[o.q.name][$1] = $2;
	});

	return uri;
};

parseUri.options = {
	strictMode: false,
	key: ["source","protocol","authority","userInfo","user","password","host","port","relative","path","directory","file","query","anchor"],
	q:   {
		name:   "queryKey",
		parser: /(?:^|&)([^&=]*)=?([^&]*)/g
	},
	parser: {
		strict: /^(?:([^:\/?#]+):)?(?:\/\/((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?))?((((?:[^?#\/]*\/)*)([^?#]*))(?:\?([^#]*))?(?:#(.*))?)/,
		loose:  /^(?:(?![^:@]+:[^:@\/]*@)([^:\/?#.]+):)?(?:\/\/)?((?:(([^:@]*):?([^:@]*))?@)?([^:\/?#]*)(?::(\d*))?)(((\/(?:[^?#](?![^?#\/]*\.[^?#\/.]+(?:[?#]|$)))*\/?)?([^?#\/]*))(?:\?([^#]*))?(?:#(.*))?)/
	}
};

/* Load framed Second Site pages in proper frame */ 

function ssFramer(destFrame) {
	var sDestFrame = destFrame;
	$(document).ready( function() {
		var kFrameset = "index.htm";
		var parentUri = parseUri(parent.location.href);
		var windowUri = parseUri(window.location.href);

		if (windowUri.file == '' ||
				windowUri.file.toLowerCase() == kFrameset) {
			// Handle parent page
			// Argument format: ?framename1=uri;anchor&framename2=uri;anchor...
			// Ex: ?ssmain=p1.htm;i32&ssindex=i1.htm;s37
			// Loads: p1.htm#i32 in frame "ssmain"
			// Loads: i1.htm#s37 in frame "ssindex"

			// Process frame arguments
			for (var sArg in windowUri.queryKey) {
				// Get frame URIs from frame name/anchor arguments
				var parts = windowUri.queryKey[sArg].split(';');
				window.frames[sArg].location.href = parts[0] + 
						(parts.length>1 ? '#'+parts[1] : '');
			}

		} else {
			// Handle child page
			if (window.location.href == parent.location.href) {
				// Not in parent frame; reload parent
				// with arguments set to load child
				var sUrl = kFrameset+'?'+sDestFrame+'='+
						windowUri.file+';'+windowUri.anchor;
				window.location.href=sUrl;
			};
		};
	});
}

var ss = function() {
	var bMapEditor = false;
	var bHaveConsole = false;

	/**
	 * parseColor parses CSS color values. It is based
	 * on RGBColor by Stoyan Stefanov <sstoo@gmail.com>,
	 * rewritten by John Cardinal to improve performance and
	 * make it more compatible with my applications and coding
	 * style.
	 */

	function parseColor(sColor) {
		// Constructor for parseColor object.
		// sColor is optional; if provided,
		// it will be parsed. Otherwise, call the
		// parseColor.parse(sColor) method.

		var self = this;
		this.r = this.g = this.b = 0;
		this.color_names = {
			'aliceblue': 'f0f8ff',
			'antiquewhite': 'faebd7',
			'aqua': '00ffff',
			'aquamarine': '7fffd4',
			'azure': 'f0ffff',
			'beige': 'f5f5dc',
			'bisque': 'ffe4c4',
			'black': '000000',
			'blanchedalmond': 'ffebcd',
			'blue': '0000ff',
			'blueviolet': '8a2be2',
			'brown': 'a52a2a',
			'burlywood': 'deb887',
			'cadetblue': '5f9ea0',
			'chartreuse': '7fff00',
			'chocolate': 'd2691e',
			'coral': 'ff7f50',
			'cornflowerblue': '6495ed',
			'cornsilk': 'fff8dc',
			'crimson': 'dc143c',
			'cyan': '00ffff',
			'darkblue': '00008b',
			'darkcyan': '008b8b',
			'darkgoldenrod': 'b8860b',
			'darkgray': 'a9a9a9',
			'darkgrey': 'a9a9a9',
			'darkgreen': '006400',
			'darkkhaki': 'bdb76b',
			'darkmagenta': '8b008b',
			'darkolivegreen': '556b2f',
			'darkorange': 'ff8c00',
			'darkorchid': '9932cc',
			'darkred': '8b0000',
			'darksalmon': 'e9967a',
			'darkseagreen': '8fbc8b',
			'darkslateblue': '483d8b',
			'darkslategray': '2f4f4f',
			'darkslategrey': '2f4f4f',
			'darkturquoise': '00ced1',
			'darkviolet': '9400d3',
			'deeppink': 'ff1493',
			'deepskyblue': '00bfff',
			'dimgray': '696969',
			'dimgrey': '696969',
			'dodgerblue': '1e90ff',
			'firebrick': 'b22222',
			'floralwhite': 'fffaf0',
			'forestgreen': '228b22',
			'fuchsia': 'ff00ff',
			'gainsboro': 'dcdcdc',
			'ghostwhite': 'f8f8ff',
			'gold': 'ffd700',
			'goldenrod': 'daa520',
			'gray': '808080',
			'grey': '808080',
			'green': '008000',
			'greenyellow': 'adff2f',
			'honeydew': 'f0fff0',
			'hotpink': 'ff69b4',
			'indianred': 'cd5c5c',
			'indigo': '4b0082',
			'ivory': 'fffff0',
			'khaki': 'f0e68c',
			'lavender': 'e6e6fa',
			'lavenderblush': 'fff0f5',
			'lawngreen': '7cfc00',
			'lemonchiffon': 'fffacd',
			'lightblue': 'add8e6',
			'lightcoral': 'f08080',
			'lightcyan': 'e0ffff',
			'lightgoldenrodyellow': 'fafad2',
			'lightgreen': '90ee90',
			'lightgray': 'd3d3d3',
			'lightgrey': 'd3d3d3',
			'lightpink': 'ffb6c1',
			'lightsalmon': 'ffa07a',
			'lightseagreen': '20b2aa',
			'lightskyblue': '87cefa',
			'lightslategray': '778899',
			'lightslategrey': '778899',
			'lightsteelblue': 'b0c4de',
			'lightyellow': 'ffffe0',
			'lime': '00ff00',
			'limegreen': '32cd32',
			'linen': 'faf0e6',
			'magenta': 'ff00ff',
			'maroon': '800000',
			'mediumaquamarine': '66cdaa',
			'mediumblue': '0000cd',
			'mediumorchid': 'ba55d3',
			'mediumpurple': '9370db',
			'mediumseagreen': '3cb371',
			'mediumslateblue': '7b68ee',
			'mediumspringgreen': '00fa9a',
			'mediumturquoise': '48d1cc',
			'mediumvioletred': 'c71585',
			'midnightblue': '191970',
			'mintcream': 'f5fffa',
			'mistyrose': 'ffe4e1',
			'moccasin': 'ffe4b5',
			'navajowhite': 'ffdead',
			'navy': '000080',
			'oldlace': 'fdf5e6',
			'olive': '808000',
			'olivedrab': '6b8e23',
			'orange': 'ffa500',
			'orangered': 'ff4500',
			'orchid': 'da70d6',
			'palegoldenrod': 'eee8aa',
			'palegreen': '98fb98',
			'paleturquoise': 'afeeee',
			'palevioletred': 'db7093',
			'papayawhip': 'ffefd5',
			'peachpuff': 'ffdab9',
			'peru': 'cd853f',
			'pink': 'ffc0cb',
			'plum': 'dda0dd',
			'powderblue': 'b0e0e6',
			'purple': '800080',
			'red': 'ff0000',
			'rosybrown': 'bc8f8f',
			'royalblue': '4169e1',
			'saddlebrown': '8b4513',
			'salmon': 'fa8072',
			'sandybrown': 'f4a460',
			'seagreen': '2e8b57',
			'seashell': 'fff5ee',
			'sienna': 'a0522d',
			'silver': 'c0c0c0',
			'skyblue': '87ceeb',
			'slateblue': '6a5acd',
			'slategray': '708090',
			'slategrey': '708090',
			'snow': 'fffafa',
			'springgreen': '00ff7f',
			'steelblue': '4682b4',
			'tan': 'd2b48c',
			'teal': '008080',
			'thistle': 'd8bfd8',
			'tomato': 'ff6347',
			'turquoise': '40e0d0',
			'violet': 'ee82ee',
			'wheat': 'f5deb3',
			'white': 'ffffff',
			'whitesmoke': 'f5f5f5',
			'yellow': 'ffff00',
			'yellowgreen': '9acd32'
		};

		// Array of functions to parse CSS color strings
		this.parsers = [
			// Handles "ffffff" form
			function(sColor) {
				if (sColor.length==6) {
					self.r = parseInt(sColor.substr(0,2), 16);
					self.g = parseInt(sColor.substr(2,2), 16);
					self.b = parseInt(sColor.substr(4,2), 16);
					return true;
				};
			},
			// Handles "fff" form
			function(sColor) {
				if (sColor.length==3) {
					var c = sColor.charAt(0);
					self.r = parseInt(c+c, 16);
					c = sColor.charAt(1);
					self.g = parseInt(c+c, 16);
					c = sColor.charAt(2);
					self.b = parseInt(c+c, 16);
					return true;
				};
			},
			// Handles "rgb(255,255,255)" form
			function(sColor) {
				var parts = sColor.match(/^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/);
				if (parts) {
					self.r = parseInt(parts[1]);
					self.g = parseInt(parts[2]);
					self.b = parseInt(parts[3]);
					return true;
				};
			},
			// Last variation sets values to 0
			function(sColor) {
				self.r = self.g = self.b = 0;
				return false;
			}
		];

		if (sColor) {
			this.parse(sColor);
		};
	}

	parseColor.prototype.toHex = function() {
		var rX = ('0'+this.r.toString(16)).right(2);
		var gX = ('0'+this.g.toString(16)).right(2);
		var bX = ('0'+this.b.toString(16)).right(2);
		return '#' + rX + gX + bX;
	};

	parseColor.prototype.toRGB = function() {
		return 'rgb('+this.r+','+this.g+','+this.b+')';
	};

	parseColor.prototype.parse = function(sColor) {
		var result = false;

		// Remove #s and spaces
		sColor = sColor.toLowerCase().replace(/[# ]/g,'');

		// Check for named color
		if (this.color_names[sColor]) {
			sColor = this.color_names[sColor];
		}

		// Call the parsers until one indicates success
		for (var i = 0; i < this.parsers.length && !result; i++) {
			result = this.parsers[i](sColor);
		}

		if (result) {
			// validate/cleanup values
			this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r);
			this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g);
			this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b);
		};

		return result;
	};

	return {
		enableMapEditor: function(enable) {	bMapEditor=enable; },
		isMapEditor: function() { return (bMapEditor); },

		extend: function(baseClass, subClass) {
			// Copied from Kevin Lindsey
			// http://www.kevlindev.com/tutorials/javascript/inheritance/index.htm
			function inheritance() {}
			inheritance.prototype = baseClass.prototype;

			subClass.prototype = new inheritance();
			subClass.prototype.constructor = subClass;
			subClass.baseConstructor = baseClass;
			subClass.superClass = baseClass.prototype;
		},

		fpdd: function(float) { return (float.toFixed(8)) },

		dMsg: function(sMessage) {
			if (!bHaveConsole) {
        $("body").append(
            '<div id="ssConsole">'+
            '<div id="ssConsoleHandle">'+
            '<button onclick="$(\'#ssConsoleContents\').empty()">'+
            		'Clear Messages</button>Messages<div style="clear: both;"></div></div>'+
            '<ol id="ssConsoleContents"></ol></div>');
        $("#ssConsole").css(
          { border: '1px solid black',
            background: '#aaa',
            padding: '1px',
            position: 'absolute',
            top: '0px',
            right: '0px',
            width: '25em'
          }
        );
        $("#ssConsole button").css(
        	{	float: 'right'
        	}
        );
        $("#ssConsoleHandle").css(
          { background: '#00f',
            color: '#fff',
            'font-family': 'sans-serif',
            'font-size': 'small',
            'font-weight': 'bold',
            cursor: 'move',
            padding: '2px'
          }
        );
        $("#ssConsoleContents").css(
          { background: '#fff',
          	clear: 'right',
            margin: '1px',
            overflow: 'auto',
            'max-height': '30em'
          }
        );
        $("#ssConsole").draggable(
          { handle: '#ssConsoleHandle',
            dragPrevention: "ol,li"
          }
        );
        bHaveConsole=true;
			};
			$("#ssConsoleContents").append('<li>'+sMessage + '</li>');
		},

		propsToString: function(theObject, prefix, suffix) {
			var sProps = '';
			var sDelim = '';

			for (var prop in theObject) {
				if (typeof(theObject[prop]) != 'function' &&
						typeof(theObject[prop]) != 'object') {
					sProps += '<span title="'+typeof(theObject[prop])+'">'+
							(prefix ? prefix : sDelim) + '&nbsp;' + prop + ':' + theObject[prop] + (suffix ? suffix : '')+
							'</span>';
					sDelim = ', ';
				}
			}
			return sProps;
		},

		parseColor: parseColor
	}
}();