$(function() {	// DOM loaded

	// Global variables
	var resultLimit = 10; // How many results are considered to be "page one" results
	var terms;
	var urls;
	var searches;
	var scan;


	// Add social bookmarking
	$("#bookmarks").bookmark({sites: ['delicious',
									  'reddit',
									  'digg',
									  'facebook',
									  'slashdot',
									  'stumbleupon',
									  'tumblr',
									  'twitthis',
									  'yahoo'
									  ],
							  addFavorite: true,
							  addEmail: true
							});
	
	var branding = google.search.Search.getBranding(google.search.Search.HORIZONTAL_BRANDING);
	$("#branding").html(branding);
	
	// Initialize forms
	$("#scan-output>div:not(#intro)").hide();
	$("#loader").hide();
		
	$("#email-results-link").bind( "click", function() {
		$("#email-results").show();
		$("#scan-output>div:not(#email-results)").hide();
	});
		
	// Add validation and submit handler to search form
	$("#search-form").clearValidate();
	$("#search-form").bind( "submit", {form: $(this)}, parseSearchForm );
	$("#search-form").bind( "submit", function() {
		$("#scan-output>div").hide();
		$("#loader").show();	
	});

	// Add validation and submit handler to email form
	$("#email-form").clearValidate();
	$("#email-form").bind( "submit", function( event ) {
		var name  = $("#name").val();
		var email = $("#email").val();
		var emailWithName;

		$("#scan-output>div").hide();
		$("#loader").show();
		
		if ( name == "" || name == undefined ) {
			emailJSON( scan, email );
		}
		else {
			emailWithName = name + " <" + email + ">";
			emailJSON( scan, emailWithName );
		}
	
		event.preventDefault();
			
	});


	
	// Create Google Web Search object, set parameters
	function googleWebSearch( args ) {
		
		// Create search object
		webSearch = new google.search.WebSearch();
		
		// LARGE_RESULTSET = usually 8, SMALL_RESULTSET = usually 4
		webSearch.setResultSetSize(google.search.Search.LARGE_RESULTSET);

		// Set callback for when search completes
		webSearch.setSearchCompleteCallback( webSearch, receiveSearchResults, [args] );
		//webSearch.setSearchCompleteCallback( webSearch, receiveSearchResults );

		// Don't add markup to search results
		webSearch.setNoHtmlGeneration();
		
		// Restrict search to US locale
		var extendedArgs = google.search.Search.RESTRICT_EXTENDED_ARGS;
		webSearch.setRestriction(extendedArgs, {gl: 'us'});

		return webSearch;
	}

	// Parse search form, perform search on terms
	function parseSearchForm( event ) {

		$("#submitSearch").attr('disabled', 'disabled');
		$("#results-container").html("");
		
		var form = event.data.form; // @@TODO: error trapping
		urls = [];
		terms = [];
		searches= [];
	
		// Initialize scan object
		scan = { searchEngine : "google",
				 searches     : []
			   };

		var own; // true = own url, false = competitor url
		var url;
		
		// Collect urls and temrs from search form
		form.find( "input:not('.ignore')[type='text'][value!='']" ).each(function (i) {
			if ( $(this).attr("name") == "domain" ){
			
				// Determine if current url is own or competitor
				own = $(this).hasClass("own");

				// Add values to urls array
				url = getDomain( $(this).val() );
				urls.push( {"url": getDomain( $(this).val() ), "own":own, "posTotal":0 } );			
			}
			else if ( $(this).attr("name") == "term" ) {
				// Add value to terms array
				terms.push( $(this).val() );
			}		
		});
		
		// Must be performed after all terms have been collected from search form due
		// to the asynchrious nature of the google.search.Search.execute() method
		$.each(terms, function (i, val) {
			var googleSearch = new googleWebSearch( [i, val] );

			// Perform search on current term
			googleSearch.execute( val );
		});
		
		// Prevent normal form post
		event.preventDefault();
	}


	// Called every time search for a particular term is completed
	function receiveSearchResults( args ) {
	
		// ------------------------------------------------------------------------------------------
		// Adapted with slight modifications from Jeremy Geerdes's
		// "How to get all the results available from your Google AJAX Search API application"
		// http://jgeerdes.blogspot.com/2008/12/how-to-get-all-results-available-from.html
		//

		var cursor = this.cursor;
		
		// Create new property in webSearch object to store all needed results
		if ( !this.allResults || cursor.currentPageIndex === 0 ){
			this.allResults = [];
		}		
		
		// Add current result set to allResults
		this.allResults = this.allResults.concat(this.results);
		
		// Check that:
		// 1) cursor exists
		// 2) we're not retrieving more results than is specified by resultLimit
		// 3) we're not on the last page of the search results
		if ( cursor && this.allResults.length < resultLimit && cursor.currentPageIndex + 1 < cursor.pages.length ) {
		
			// If so go to the next page of results
			this.gotoPage( cursor.currentPageIndex + 1 );
			
		} else {
		
		// ------------------------------------------------------------------------------------------
		
			var termIdx = args[0];
			var term    = args[1];

			// Otherwise, truncate unnecessary results (i.e. results beyond the resultLimit)
			this.allResults.splice(resultLimit, this.allResults.length - resultLimit);
			
			if ( termIdx != undefined && ( term == terms[termIdx] ) ){
				// Add results to searches array
				searches[termIdx] = this.allResults;
			}
		
		}
		// Search is complete
		if ( searches.length == terms.length ) {
		
			// Parse search results and create scan report
			buildJSON();
			outputJSON( scan, urls );
			//emailJSON( scan );
		}
	}
	
	function buildJSON() {
	
		// Flush all prior searches
		scan.searches = [];
		
		// Loop through searches performed
		$.each(searches, function(i, search){
				
			// Add performed search to scan report
			scan.searches.push( {term: terms[i], results : parseSearchResults( search ) } );						  
		});
	}
	
	
	function parseSearchResults( results ) {
		$("#results-container").html("");
		var parsedResults = [];
		var urlPos = 0;
		
		// Check that there are results
		if ( results && results.length > 0 ) {	
		
			// For each url being scanned for
			$.each(urls, function(i, url){
			
				// Reset url position variable
				urlPos = 0;				
			
				// Loop through results from search engine
				$.each(results, function(j, result){
					
					// Check that current result is of type WebSearch
					if ( result.GsearchResultClass == google.search.WebSearch.RESULT_CLASS &&
						 url.url == getDomain( result.visibleUrl ))
						{		

							// Store position, tally page 1 results for url
							urlPos = j + 1;
							url.posTotal = url.posTotal + 1;
							
							// Exit loop when result found
							return false;
						}
				});
				
				// Add url to report results
				parsedResults.push( { url: url.url, own: url.own, pos: urlPos } );					
			});
		}
		return parsedResults;
	}
	

	// @@ TO DO - add comments ( oh the irony! )
	function outputJSON( scanJSON, urls ) {
	
		if ( scanJSON ) {
			var table = $(document.createElement('table'));
			var rankTally;
			var row = $(document.createElement('tr'));
			var cell = $(document.createElement('th'));
			var curSearch;

			// Construct header
			cell.html( "" );
			cell.attr( "id", "head-0" );
			row.append(cell);
			row.addClass("header");
			
			$.each(urls, function (i, url) {
				
				rankTally= $(document.createElement('p'));
				rankTally.html( url.url + " - Page 1 Results: " + url.posTotal );
				
				if ( url.own ) {
					rankTally.addClass( "own" );
				}
				
				$("#results-container").append( rankTally );
			
				cell = $(document.createElement('th'));
				cell.attr( "id", "head-"+ (i+1) );
				cell.html(url.url);
				row.append( cell );
			});
			
			table.append( row );
			
			if ( scanJSON.searches.length > 0 ) {
				
				$.each( scanJSON.searches, function (i, search) {
					curSearch = search;
					// New row
					row = $(document.createElement('tr'));
					// New cell for keyword
					cell = $(document.createElement('td'));
					cell.addClass( "term" );
					cell.html(search.term);
					row.append( cell );
					
					// Loop through search results
					$.each(curSearch.results, function (j, result) {

						// New cell for term rank
						cell = $(document.createElement('td'));
						if ( result.pos > 0 ) {
							if ( result.own ){
								cell.addClass( "own" );
							}
							
							cell.addClass( "found" );
						}
						else {
							// do stuff
						}
						row.append( cell );
					});

					table.append( row );
				});
			}
			
			$("#results-container").append( table );
			$("#loader").hide();
			$("#report").show();
			$("#scan-output>div:not(#report)").hide();
			$("#submitSearch").removeAttr('disabled');
			
		}
	}
	
	// @@ TO DO - add comments ( oh the irony! )
	function emailJSON( scanJSON, sendTo ){

		var data;
		
		if ( sendTo == "" || sendTo == undefined ){
			data = { urls:   JSON.stringify( urls ),
                     terms:  JSON.stringify( terms ),
                     report: JSON.stringify( scanJSON )
				   };
		}
		else {
			data = { urls:  JSON.stringify( urls ),
                    terms:  JSON.stringify( terms ),
                    report: JSON.stringify( scanJSON ),
                    sendTo: sendTo
				   };
		}

		$.post("scripts/send-results.php", data, function( response ) {
			//@@ TODO - add error handling, progress bar
			$("#loader").hide();
			$("#thanks").show();
			$("#scan-output>div:not(#thanks)").hide();
			//$("#thanks").append( response );
		});

	}
	
	function getDomain( url ) {
		var protocol = "^http://|https://|ftp://";
		var subdomain = "^www.";
		url = url.replace(new RegExp(protocol, 'i'), '');
		url = url.replace(new RegExp(subdomain, 'i'), '');
		url = url.replace(new RegExp('/$', 'i'), '');
		return url.toLowerCase();
	}
	
});
