/*
GC Forums Fix - v1.3 2006-08-03
(c) 2006, Prime Suspect Software

Greasemonkey user script: see http://greasemonkey.mozdev.org

Function:
 Adds links next to user name, to show all owned and found caches.
 Also makes the profile more "Firefox friendly" by changing the 
 link target to open the profile in a new tab/window.
 
 Topic threads now automatically open in a new tab/window.
 
 Changes the "Posted Topic" icons to show their status better. 
 Instead of the small white strip in the lower right corner, it
 now shows a large yellow square in the middle of the icon.
 
 Changes the small "Go To New Post" icon to a bigger version.
 
 Add a "Favorites" quick access drop-down. To add a forum to the
 list, click the "Fav" link next to the forum name on the main
 forum page. Forums will be shown in the drop-down list in the same
 order that they are selected. To clear the list, there is a new
 link at the bottom right corner of the main forum page.
 
Change Log:

* (v1.3) Added replacement icons for polls.

* (v1.2) Option to remove/restore highlighting on search text.

* (v1.2) Minor change to put Favorites List on the bottom of the page,
  as well as the top.

* (v1.1) Bug fix. Page buttons were opening in a new tab. Changing the
  page in a topic now opens in the same tab.

* (v1.1) Icon replacement changed to also work on View New Posts page.

* (v1.1) Added option to turn on/off the opening of topics in new tabs.
  Option now defaults to Off.

* (v1.0) Initial release.

// ==UserScript==
// @name            GC Forums Fix
// @description     (v1.3) GC Forums Fix & Enhancements
// @namespace       http://gmscripts.locusprime.net/
// @include         http://forums.groundspeak.com/GC/*
// @include         http://forums.groundspeak.com/gc/*
// ==/UserScript==

*/

(function() {

	var e_navstrip = document.getElementById("navstrip");
	if (! e_navstrip) { return; }

	//  Get log-on name.
	e_userlinks = document.getElementById("userlinks");
	if (e_userlinks) {
		var SignedInAs = e_userlinks.childNodes[1].firstChild.childNodes[1].firstChild.data;
		SignedInAs = SignedInAs.replace(/<\&amp;>/g, '&');
	} else { return; }

	var UseTabs = GM_getValue("UseTab_" + SignedInAs, false);

	if ((e_navstrip.childNodes.length == 7) || (e_navstrip.childNodes.length == 4)) {
		//  Get current topic number.
		var topicUrl = e_navstrip.lastChild.href;
		curForum = UrlParm('showforum', false, topicUrl);
		
		//  Get handle to button for drop-down placement.
		var xPathSearch = "//img[@alt='Start new topic']";
		var tList = document.evaluate(
			xPathSearch,
			document,
			null,
			XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,
			null);
		var ic = tList.snapshotLength;
		for (var i = 0; i < ic; i++) {
			sntLnk = tList.snapshotItem(i).parentNode.parentNode.firstChild;	
			var curList = GM_getValue("FavList_" + SignedInAs, '');
			if (curList.length > 0) {
				//  Create drop-down selector.
				var favDropdown = document.createElement("select");
				favDropdown.id = 'favDropdown' + i;
				favDropdown.style.borderStyle = 'solid';
				favDropdown.style.borderWidth = 'thin';
				favDropdown.style.borderColor = 'rgb(7, 42, 102)';
				favDropdown.style.backgroundColor = 'rgb(240, 245, 250)';
				//  Create drop-down.
				var favOption = document.createElement("option");
				favOption.value = -1;
				favOption.appendChild(document.createTextNode('--- Favorites ---'));
				favOption.style.fontWeight = 'bold';
				favOption.style.textAlign = 'center';
				favOption.style.fontStyle = 'italic';
				favDropdown.appendChild(favOption);
				//  Parse out current list.
				var favList = curList.split('#:#');
				//  Add to drop-down.
				for (var j = 0; j < favList.length; j++) {
					var favListX = favList[j].split('%:%');
					favOption = document.createElement("option");
					favOption.value = favListX[0];
					favOption.appendChild(document.createTextNode(favListX[1]));
					favDropdown.appendChild(favOption);
					if (favOption.value == curForum) { favOption.selected = true; }			
				}
				//  Add drop-down to page.
				sntLnk.parentNode.insertBefore(favDropdown, sntLnk);
				sntLnk.parentNode.insertBefore(document.createTextNode(' \u00A0 '), sntLnk);
				favDropdown.addEventListener("change", ForumJump, true);
			}
		}
	

		//  Replacement icons.
		var f_hot_dot = 
			"data:image/gif,GIF89a%13%00%0F%00%B3%00%00c%00%00%A5%B5%CE%B" +
			"5%00%00%C6%00%00%C6%CE%DE%CE%00%00%CEJJ%CE%D6%E7%DE%00%00%DE" +
			"ZZ%DE%E7%EF%E7%EF%F7%EF%00%00%EF%D6%D6%F7%00%00%FF%FF%00%2C%" +
			"00%00%00%00%13%00%0F%00%00%04%5BPIBk%958%13%C0%7B'%99%064d%D" +
			"9%00%60%A8%10%C1h%92%40%60%81%9Bg%DF%E8%96%EC%7C%EF%E7%00%83" +
			"%10%C7%11%1A%80%82%24%E0%C1l%3E%00I%01p%40%5D%3A%99%00%EA%00" +
			"X%E8Z%AF%80n%01%88(%7F%9D%802%02%C8h%13%01m%06%D0A%AF%DB%EF%" +
			"C07%8E6%EB%CF%14%11%00%3B";
	
		var f_hot_no_dot = 
			'data:image/gif,GIF89a%13%00%0F%00%B3%00%00%A5%7B%7B%C6%CE%DE' +
			'%CEs%7B%D6s%7B%D6%94%94%D6%94%9C%D6%DE%E7%D6%DE%EF%DEs%7B%DE' +
			'%E7%EF%E7s%7B%E7%EF%F7%EFs%7B%EF%E7%E7%FF%FF%00%FF%FF%FF%2C%' +
			'00%00%00%00%13%00%0F%00%00%04Y0ICk%958%1B%C0%7B7%99%064d%D9%' +
			'00%60%98%18%C1h%92%40%60%81%9Bg%DF%E8V%EC%7C%EF%E7%00%82%10%' +
			'C7%11%12%80%82%24%C0%C1l%3A%00I%01R%E9lB%95%14%C0%60%BB%AC%3' +
			'E%B7%03%20b%DC%AD%02%C6%08%A0bM%04%AC%15%EA%B7%7C%CE%CE%B6q%' +
			'B4%99~%96%88%00%00%3B';
	
		var f_norm_dot = 
			'data:image/gif,GIF89a%13%00%0F%00%B3%00%00%00)cZ%84%C6Z%8C%C' +
			'Ec%94%D6k%9C%D6k%9C%DEs%A5%E7s%AD%EF%84%BD%F7%A5%B5%CE%C6%CE' +
			'%DE%CE%D6%E7%D6%DE%EF%DE%E7%EF%E7%EF%F7%FF%FF%00%2C%00%00%00' +
			'%00%13%00%0F%00%00%04%5B%B0IEk%958%2B%C0%7BW%99%060d%C9%00%6' +
			'0%D8(%C9h%92%40b%81%9Bg%DF%E8%86%EC%7C%EF%E7%00%82%10%C7%11%' +
			'12%80%81%24%E0%C1l%3E%00%C9%00P%40%5D%3A%99%00%AA%008%E8Z%AF' +
			'%80%EE%00X(%7F%9D%80r%01hh%13%01m%03%F0%40%AF%DB%EF%C07%8E6%' +
			'EB%CF%1A%11%00%3B';
	
		var f_norm_no_dot = 
			"data:image/gif,GIF89a%13%00%0F%00%B3%00%00s%8C%AD%9C%B5%DE%A" +
			"5%BD%DE%A5%BD%E7%A5%C6%E7%AD%C6%E7%AD%C6%EF%AD%CE%F7%B5%D6%F" +
			"7%C6%CE%DE%D6%DE%E7%D6%DE%EF%DE%E7%EF%E7%EF%F7%FF%FF%00%FF%F" +
			"F%FF%2C%00%00%00%00%13%00%0F%00%00%04U%90IEk%958%2B%C0%7BW%9" +
			"9%06%84%12%00%92J2%92%40b%81%9B'%CF%E6%86%DCx%AE%D7%C0%E0%D3" +
			"%1C%DF%80%17(%02%1C%C8%A4%03P%0C%F0%04%D0%A3%12%09%80%0AxB%E" +
			"9%B4%F7%A3%00%08%60%AD%F2%1B%F6%1A%CE%40%C0%D9%C0%5B%BB%DFk%" +
			"5E%9A%06%7B%D9_%8C%08%00%3B";

		var f_poll_dot = 
			"data:image/gif,GIF89a%13%00%0F%00%B3%00%00R%00c%A5Z%C6%A5%B5" +
			"%CE%ADZ%CE%BDc%D6%C6k%DE%C6%CE%DE%CEk%D6%CEs%E7%CE%D6%E7%D6s" +
			"%EF%DE%E7%EF%E7%84%F7%E7%D6%EF%E7%EF%F7%FF%FF%00%2C%00%00%00" +
			"%00%13%00%0F%00%00%04%5BpICk%958%1B%C0%7B7%99%064d%D9%00%60%" +
			"B8%18%C2h%92%80%60%81%9Bg%DF%E8%C6%EC%7C%EF%E7%80%83%10%C7%1" +
			"1%1E%80%81%24%E0%C1l%3E%00%C9%00p%40%5D%3A%99%00%EA%00H%E8Z%" +
			"AF%80.%01X(%7F%9D%80r%01%88h%13%01m%04PA%AF%DB%EF%C07%8E6%EB" +
			"%CF%16%11%00%3B";
		
		var f_poll_no_dot = 
			"data:image/gif,GIF89a%13%00%0F%00%B3%00%00%9C%7B%AD%C6%A5%DE" +
			"%C6%CE%DE%CE%A5%DE%CE%A5%E7%D6%AD%E7%D6%DE%E7%D6%DE%EF%DE%AD" +
			"%EF%DE%AD%F7%DE%E7%EF%E7%B5%F7%E7%E7%EF%E7%EF%F7%FF%FF%00%FF" +
			"%FF%FF%2C%00%00%00%00%13%00%0F%00%00%04V%901e%AA%B5Jjm%80%FF" +
			"%9F%B1m%DD(%01%E2H%09%80%C9%00%C2eP%60m%7B%15%B0%EC%7C%EF%A3" +
			"%9D%82%F0%E6%11%16%80%80%80%12%E0h%3A%1D%C9eN%19%60%3E%9B%D1" +
			"j%8E%C0%B5%5E%01%5C%02%D2%E8%7D%02%C892%11%DDA%B8%DF%F08%92H" +
			"%9C%C9%EEwE%04%00%3B";
			
		var newpost = 
			"data:image/gif,GIF89a%0A%00%0A%00%B3%00%00%FF%AAq%FF%9E%5D%F" +
			"F%91G%FF%831%FFw%1D%FFm%0C%FF%FF%FF%B3N%04%00%00%00%00%00%00" +
			"%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%00%2C%00" +
			"%00%00%00%0A%00%0A%00%00%04!%F0%C8IO%B9%F8%CA%9C%25%F9%201%0" +
			"Ddy%18%92%A0%AA'z%04p%D0%BA%40%3D%D3%C0%EDVT%04%00%3B";	

		//  Get icon list.
		xPathSearch = "//img[((starts-with(@src, 'style_images/1/')) and " +
				"(contains(@src, 'dot.gif'))) or " +
				"(@src='style_images/1/newpost.gif')]";
		tList = document.evaluate(
			xPathSearch,
			document,
			null,
			XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
			null);
		ic = tList.snapshotLength;
		//  Replace icons.
		for (var i = 0; i < ic; i++) {
			var tImg = tList.snapshotItem(i);
			var imgSrc = tImg.src;
			if (imgSrc.match('f_hot_dot')) {
				tImg.src = f_hot_dot;
			} else if (imgSrc.match('f_hot_no_dot')) {
				tImg.src = f_hot_no_dot;
			} else if (imgSrc.match('f_norm_dot')) {
				tImg.src = f_norm_dot;
			} else if (imgSrc.match('f_norm_no_dot')) {
				tImg.src = f_norm_no_dot;
			} else if (imgSrc.match('f_poll_dot')) {
				tImg.src = f_poll_dot;
			} else if (imgSrc.match('f_poll_no_dot')) {
				tImg.src = f_poll_no_dot;
			} else if (imgSrc.match('newpost')) {
				tImg.src = newpost;
				if (UseTabs) { tImg.parentNode.target = '_blank'; }
			}
		}
	
		//  Change topic links to open in a new tab/window.
		if (UseTabs) {
			xPathSearch = "//a[(contains(@href, '/index.php?showtopic='))]";
			tList = document.evaluate(
				xPathSearch,
				document,
				null,
				XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
				null);
			ic = tList.snapshotLength;
			for (var i = 0; i < ic; i++) {
				if (tList.snapshotItem(i).parentNode.nodeName != 'SPAN') {
					tList.snapshotItem(i).target = '_blank';
				}
			}
		}
	}

	//  Add Found/Owned icons.
	if (UrlParm('showtopic') != '') {

		var ImgSrcOwned =
			"data:image/gif,GIF89a%0F%00%0B%00%B3%00%00%00%00%00%08%08%08%0C%" +
			"10%0C%25%2B%1E%2BB%22Ls4%60g%5Br~m%FF%00%FF%84%84%88%A4%C2%91%C1" +
			"%C0%C1%E2%E4%E9%EC%EF%F1%F3%F7%FB%FF%FF%FF!%F9%04%01%00%00%08%00" +
			"%2C%00%00%00%00%0F%00%0B%00%40%04Y%10I%C9Z%028%03%0A%9E%7F%C7b%1" +
			"8%0D31%D7Q%18j%B1%3C%CCF1%C7p%10x%BD%C8%0D%86%0B%01%85%E31r%9C4%" +
			"80Di%C2d%D0%08%8Aht%20s%26%A0%85l%01%BA%08Hz%02Ca%20%200%86%84%C" +
			"3%17%B08%24%16%84%04%91dB%C4%18%9FK%C2)%89%00%00%3B";
	
		var ImgSrcFound =
			"data:image/gif,GIF89a%0D%00%0B%00%B3%00%00%00%00%00%BD%AD%00%C6%" +
			"AD%00%FF%00%FF%FF%E7%00%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%F" +
			"F%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF%FF!%F9%0" +
			"4%01%00%00%03%00%2C%00%00%00%00%0D%00%0B%00%40%04%2FpH%09j%9D%13" +
			"%90%CD%09%C8%9B%A0%01%C2%F6Q%1Dw%0E%9A%A7%9A%18k%AD%18%10p%01m%1" +
			"3%A2W%E6%A8%94%8Ar%F3T6%C0L%91%90%8C%00%00%3B";
		
		//  Snapshot list of user name links.
		var UserSpanList = document.evaluate(
			"//span[@class='normalname']",
			document,
			null,
			XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
			null);
	
		//  Loop through all profile name links.
		if (UserSpanList.snapshotLength > 0) {
			for (var i = 0; i < UserSpanList.snapshotLength; i++) {
				
				//  Get handles to span and link nodes.
				var ThisUserSpan = UserSpanList.snapshotItem(i);
				var UserLink = ThisUserSpan.childNodes[0];
				
				//  Change profile link to open in a new tab/window.
				UserLink.target = '_blank';
				
				//  Get user name.
				var UserName = UserLink.innerHTML;
				UserName = UserName.replace(/&amp;/g,'&');
				
				//  Create URL-safe user name.
				UserNameURL = encodeURIComponent(UserName);
				
				//  Create link to user's owned caches list.
				var CacheLinkOwned = document.createElement('a');
				CacheLinkOwned.href = 'http://www.geocaching.com/seek/nearest.aspx?u=' + 
						UserNameURL;
				CacheLinkOwned.target = '_blank';
	
				//  Create cache-box image.
				var LinkImgOwned = document.createElement('img');
				LinkImgOwned.src = ImgSrcOwned;
				LinkImgOwned.height = 11;
				LinkImgOwned.width = 15;
				LinkImgOwned.border = 0;
				LinkImgOwned.title = 'Show caches owned by ' + UserName;
	
				//  Add image to link.
				CacheLinkOwned.appendChild(LinkImgOwned);
	
				//  Create link to user's found caches list.
				var CacheLinkFound = document.createElement('a');
				CacheLinkFound.href = 'http://www.geocaching.com/seek/nearest.aspx?ul=' + 
						UserNameURL;
				CacheLinkFound.target = '_blank';
	
				//  Create cache-box image.
				var LinkImgFound = document.createElement('img');
				LinkImgFound.src = ImgSrcFound;
				LinkImgFound.height = 11;
				LinkImgFound.width = 13;
				LinkImgFound.border = 0;
				LinkImgFound.title = 'Show caches found by ' + UserName;
	
				//  Add image to link.
				CacheLinkFound.appendChild(LinkImgFound);
	
				//  Add links to span.
				ThisUserSpan.insertBefore(CacheLinkOwned, UserLink.nextSibling);
				ThisUserSpan.insertBefore(CacheLinkFound, CacheLinkOwned.nextSibling);
			}
		}
		
	}
	
	
	//  If hilighted page.
	if (UrlParm('hl') != '') {
		var hiliteOn = true;
		ulp = e_userlinks.childNodes[3];
		ulp.appendChild(document.createTextNode('\u00b7\u00A0'));
		var lnkClrHL = document.createElement('a');
		lnkClrHL.title = 'Remove search result highlighting';
		lnkClrHL.href = "javascript:void(0)";
		lnkClrHL.appendChild(document.createTextNode('Remove\u00A0HiLite'));
		ulp.appendChild(lnkClrHL);
		ulp.addEventListener("click", HiliteOff, true);
	}


	//  If at initial forum page.
	if (e_navstrip.childNodes.length == 3) {
		//  Add 'Fav' links to all forums.
		xPathSearch = "//a[(contains(@href, 'showforum='))]";
		tList = document.evaluate(
			xPathSearch,
			document,
			null,
			XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
			null);
		ic = tList.snapshotLength;
		for (var i = 0; i < ic; i++) {
			tLnk = tList.snapshotItem(i);
			if (tLnk.parentNode.nodeName == 'B') {				
				tLnk.parentNode.appendChild(document.createTextNode(' \u00A0 '));
				var addfavSpan = document.createElement("span");
				addfavSpan.setAttribute('class', 'minipagelink');
				addfavSpan.style.fontSize = '7pt';
				var addfavLnk = document.createElement("a");
				addfavLnk.href = "javascript:void(0)";
				addfavLnk.setAttribute('forumID', tLnk.href);
				addfavLnk.setAttribute('forumName', tLnk.firstChild.data);
				addfavLnk.title = 'Add to Favorites list';
				addfavLnk.appendChild(document.createTextNode('Fav'));
				addfavSpan.appendChild(addfavLnk);
				tLnk.parentNode.parentNode.insertBefore(addfavSpan, 
						tLnk.parentNode.nextSibling);
				addfavLnk.addEventListener("click", AddFav, true);
			}
		}
		
		//  Add 'Clear favorites' link to bottom of page.
		var e_fc_stat = document.getElementById("fc_stat");
		var e_ctrlSpan = e_fc_stat.previousSibling.previousSibling.firstChild;
		e_ctrlSpan.appendChild(document.createTextNode(' \u00b7 '));
		var clrfavLnk = document.createElement("a");
		clrfavLnk.appendChild(document.createTextNode('Clear favorites'));
		clrfavLnk.href = "javascript:void(0)";
		clrfavLnk.title = "Clear all favorites";
		e_ctrlSpan.appendChild(clrfavLnk);
		clrfavLnk.addEventListener("click", ClrFav, true);
		
		//  Add 'Use Tabs' link to bottom of page.
		e_ctrlSpan.appendChild(document.createTextNode(' \u00b7 '));
		var usetabLnk = document.createElement("a");
		usetabLnk.appendChild(document.createTextNode('Use Tabs?'));
		usetabLnk.href = "javascript:void(0)";
		usetabLnk.title = "Open topics in new tabs?";
		e_ctrlSpan.appendChild(usetabLnk);
		usetabLnk.addEventListener("click", UseTab, true);
	}


// -------------------- Functions -------------------- //


	//  Jump to selected forum.
	function ForumJump() {
		newForum = this.value - 0;
		if ((newForum != -1) && (newForum != curForum)) {
			var newUrl = 'http://forums.groundspeak.com/GC/index.php?showforum=' + newForum;
			document.location.href = newUrl;
		}
	}

	
	//  Add favorite to list.
	function AddFav() {
		var addID = UrlParm('showforum', false, this.getAttribute('forumID'));
		var addName = this.getAttribute('forumName');
		var curList = GM_getValue("FavList_" + SignedInAs, '');
		//  Check for duplicate.
		var RegEx1 = new RegExp('(^|#:#)' + addID + '%:%');
		if (curList.match(RegEx1)) {
			alert('NOTICE: You have already added \n' +
			addName + ' to your favorites. \n\n' +
			'Operation ignored.');
		} else {		
			if (curList.length > 0) { curList += '#:#'; }
			var q = curList + addID + '%:%' + addName;
			GM_setValue("FavList_" + SignedInAs, q);
			alert(addName + ' added to your Favorites list.');
		}
	}

	
	//  Clear all favorites.
	function ClrFav() {
		var Resp = confirm('This will clear all entries from the \n' +
				'Favorites drop-down list. Are you sure?');
		if (Resp) {
			GM_setValue("FavList_" + SignedInAs, '');
		}
	}

	
	//  Set Use Tabs.
	function UseTab() {
		var Resp = confirm('Click OK to open topics in new tabs. \n' +
				'Click CANCEL to open topics in the current tab.');
		if (Resp) {
			GM_setValue("UseTab_" + SignedInAs, true);
		} else {
			GM_setValue("UseTab_" + SignedInAs, false);			
		}
	}


	//  Turn search highlighting off.
	function HiliteOff() {
		if (hiliteOn) {
			lnkClrHL.firstChild.data = 'Restore HiLite';
			lnkClrHL.title = 'Restore search result highlighting';
			var a_class = 'searchlite';
			var b_class = 'searchlite_off';
		} else {
			lnkClrHL.firstChild.data = 'Remove HiLite';
			lnkClrHL.title = 'Remove search result highlighting';
			a_class = 'searchlite_off';
			b_class = 'searchlite';
		}
		//  Snapshot list of user name links.
		var hlSpanList = document.evaluate(
			"//span[@class='" + a_class + "']",
			document,
			null,
			XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,
			null);
		var hlc = hlSpanList.snapshotLength;
		for (var i = 0; i < hlc; i++) {				
			var hlSpan = hlSpanList.snapshotItem(i);
			hlSpan.setAttribute('class', b_class);
		}
		hiliteOn = !hiliteOn;
	}
	

	//  Returns a URL parameter.
	//    ParmName - Parameter name to look for.
	//    IgnoreCase - (optional) *false, true. Ignore parmeter name case.
	//    UrlString - (optional) String to search. If omitted, document URL is used.
	function UrlParm(ParmName, IgnoreCase, UrlString) {
		var RegRslt, sc = '', RtnVal = '';
		if (IgnoreCase) {sc = 'i'}
		if(UrlString) {
			var PageUrl = UrlString;
		} else {
			PageUrl = document.location + '';
		}
		var ParmString = PageUrl.substring(PageUrl.indexOf('?') + 1);
		var RegEx1 = new RegExp('(^|&)' + ParmName + '=(.*?)(&|#|$)', sc);
		RegRslt = RegEx1.exec(ParmString);
		if (RegRslt) {RtnVal = RegRslt[2]}
		return RtnVal;
	}


})();
