/*
	This is based on the Google results numbering script from;
	Adam Langley <agl@imperialviolet.org>
	A Firefox Greasemonkey script,

	Released under the GPL.
	Mark Langenhoven 2005/05/20

*/

/* Version history
0.2.1 2005/05/26 "Fade" negative searches into the background
0.2   2005/05/26 Expand script to work on Searchhistory as well
0.1.1 2005/05/23 Refresh page after the rating has been clicked to
                 display the new value.
0.1   2005/05/20 Original version.
*/


// ==UserScript==
// @name 		Google Search Ratings
// @namespace 		http://www.langenhoven.com/
// @description 	Adds ratings to search results
// @include 		http://www.google.*/search*
// ==/UserScript==

(function() {

	//Check if we are on the results page or the search history 
	//page as the links are displayed differently
	rexp = /searchhistory/;
	locstr = window.location.href;

	if ( locstr.search(rexp) > 0 ) {
	  //We are on the search history page
	  var searchpage = true;

          var results = document.evaluate('//td[@valign="top"]', document, null, 
			XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
	  

        } else {
	  //We are on the regular results page
	  var searchpage = false;
	
 	  // Search results are in p elements with a class of 'g'
	  // This uses XPath to find all such elements and returns a 
	  // snapshot. (A snapshot doesnt become invalid after changing
	  // the DOM)
		
	  var results = document.evaluate("//p[@class='g']", document, null, 
			XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

	}


	for (var i = 0; i < results.snapshotLength; ++i) {
		var result = results.snapshotItem(i);

		//We want to rate by domain, so chop the text down to the domain.
		//First get the plain url
		try {
			if (searchpage == true ) {
				//History page handling
				var urlname = '';
				try 
				{

                                  if (result.firstChild.firstChild.nodeName.toUpperCase() == "A") {
					urlname = result.firstChild.firstChild.getAttribute("href");
				  } else {
					urlname = '';
				  }

				} catch (e) {
					urlname = '';
				}
	
				//Catch links pointing to tables
				if ( urlname == 'undefined' ) {
					urlname = '';
				}
				//Catch other links on the page
				rexp = /:///;
				if ( urlname.search(rexp)  < 0 ) {
					urlname = '';
				}


			} else {
				//Regular search handling
		  		var urlname = result.firstChild.nextSibling.getAttribute("href");
			}


		//If you want to rate by URL instead of domainname then simply
		//comment out the following section
		var domname = urlname;

		if ( urlname != '' ) {
			var domarr = urlname.split("/");
			//We grab section 0 which is the "http" part and section 2
			//because section 1 is just the second / and will be blank
			urlname = domarr[0] + "//" + domarr[2] + "/";
		}

		domname = urlname;

                 
		} catch (error) {
			//simply skip to the next entry
			domname = '';
			GM_log('gsearchrate Error: ' + error)
                }

		if (domname != '') {
			//Remember to add in the items you want in the reverse order
			//that they should appear on the page

  			//Put a space between our rating modifiers and the actual link
			var newspan = document.createTextNode("  ");
			result.insertBefore(newspan, result.firstChild);


		// We put the negative rating box in a small-caps red span
		var newspan = document.createElement("a");
                newspan.setAttribute("href", domname + "#negrate");
		newspan.setAttribute("name", "negrate");
		newspan.setAttribute("style", "color:red; font-variant: small-caps; font-weight: bold; text-decoration: none;");
		newspan.appendChild(document.createTextNode('[-]'));
		result.insertBefore(newspan, result.firstChild);

		// We put the positive rating box in a small-caps green span
		var newspan = document.createElement("a");
                newspan.setAttribute("href", domname + "#posrate");
		newspan.setAttribute("name", "posrate");
		newspan.setAttribute("style", "color:green; font-variant: small-caps; font-weight: bold; text-decoration: none");
		newspan.appendChild(document.createTextNode('[+]'));
		result.insertBefore(newspan, result.firstChild);


		
		//Take a look to see if this link has been rated before
		var rating = GM_getValue(domname, 0);
		if (rating > 0) {
			//We found a positive rating so display it with the link
			var colspan = document.createElement("span");
			colspan.setAttribute("style", "color:green; font-weight: bold;");
			colspan.appendChild(document.createTextNode('[' + rating + '] '));

			//Highlight the general text
			result.setAttribute("style", "background-color:Cornsilk !important;");

			result.insertBefore(colspan, result.firstChild);
			
		} //positive rating

		if (rating < 0) {
			//Negative rating - display with the link
			//This is deliberately handled separately so that we could 
			//possibly delete this domain later on if we felt like it
			var colspan = document.createElement("span");
			colspan.setAttribute("style", "color:red; font-weight: bold;");
			colspan.appendChild(document.createTextNode('[' + rating + '] '));

			//Fade the general text
			result.setAttribute("style", "color:DarkGray !important;");
			//Fade the actual link
			if (searchpage == true) {
				result.firstChild.nextSibling.nextSibling.nextSibling.firstChild.setAttribute("style", "color:DarkGray !important;");
			} else {
				result.firstChild.nextSibling.nextSibling.nextSibling.nextSibling.setAttribute("style", "color:DarkGray !important;");
			}

			result.insertBefore(colspan, result.firstChild);

			//Possibly delete links completely after a certain threshold
			//result.parentNode.removeChild(result);


		} //negative rating

		} //error checking
	} //loop through the results links


	results = null;


	//Add an event listener to trap the mouse clicks so that we can grab our
	//ratings if they come through
	document.addEventListener('click', function(event) {
		// event.target is the element that was clicked

		//Split the name on our divider to see if it is 
		//one of our special clicks. Hopefully I find a
		//better way to do this through the name value
		var click_val = '' + event.target;
		try {
		var click_arr = click_val.split("#");

		if (click_arr.length > 1) {
			//click_arr[0] will contain our domain to check for


			if (click_arr[click_arr.length - 1] == "posrate" ) {
				var rating_count = GM_getValue(click_arr[0], 0);

				//Increment the counter
				rating_count += 1;

				//Save the value
				GM_setValue(click_arr[0], rating_count);

				//Refresh the window so that the results are
				//immediately displayed
				window.location.reload(true);

				//Prevent the click from going through 
				event.stopPropagation();
				event.preventDefault();
		  	} //positive rating

			if (click_arr[click_arr.length - 1] == "negrate" ) {
				var rating_count = GM_getValue(click_arr[0], 0);

				//Decrement the counter
				rating_count -= 1;

				//Save the value
				GM_setValue(click_arr[0], rating_count);


				//Refresh the window so that the results are
				//immediately displayed
				window.location.reload(true);

				//Prevent the click from going through 
				event.stopPropagation();
				event.preventDefault();

		  	} //negative rating

  		} //found a rating link

		} catch (error) {
			//Shoot straight past on errors
		}

	}, true);


})();





