// our document is ready 
$(document).ready(function() {

// set focus to search box
$("input#searchbox").focus();

// init Bing API variables
var AppId = "AppId=A38322A0EF268EB68C5DA83576798D03D2537737";	// bing API ID
var Query = "Query=";
var Sources = "Sources=Web+RelatedSearch";
var Version = "Version=2.2";
var Market = "Market=en-IN";
var WebCount = "Web.Count=40";
var WebOffset = "Web.Offset=0";
var ImgCount = "Image.Count=40";
var ImgOffset = "Image.Offset=0";
var VideoCount = "Video.Count=40";
var VideoOffset = "Video.Offset=0";

// temp
var lastSearch = '';
var lastResult = '';
var lastSuggestSearch = '';
var lastSuggestResult = '';

// perform search   
function doSearch(search,suggest,validate){
  
  	if (suggest==null) {suggest=true;}
  	if (validate==null) {validate=false;}
  
	// if our search is not blank AND is not what we last searched for
	if ((search!='') && (search!=lastSearch))
		{

		  lastSearch = search;

		  // encode our search query to send to Bing
		  searchEnc = encodeURIComponent(search);
		  
		  // set our HTTP GET path
		  var arr = [AppId, Query + searchEnc, Sources, Version, WebCount, WebOffset, ImgCount, ImgOffset, VideoCount, VideoOffset, "JsonType=callback", "JsonCallback=?"];
		  var requestStr = "http://api.bing.net/json.aspx?" + arr.join("&");
	
		  // add a throbber
		  $("#searchbox").addClass('throbber');
	
		  // make the call
		  $.ajax({
			  type: "GET",
			  url: requestStr,
			  dataType: "jsonp",
			  cache: true,
			  timeout: 5,
			  success: function(msg) {
					  if((lastSearch!='')&&(validate!=true))
					  {
						  // process the search result
						  SearchCompleted(msg, search);
					  }else if (lastSearch==search){
						  SearchCompleted(msg, search);
					  }
			  },
			  error: function(msg) {
				  alert("Something hasn't worked\n" + msg.d);
			  },
			  complete: function() {
					  // remove the throbber from the search box
					  if(lastSearch==lastResult)
					  {
					  	$("#searchbox").removeClass('throbber');
					  }else{
						doSearch(lastSearch);
					  }
			  }
		  });
		  
		  if (suggest==true)
		  {
			  
			  lastSuggestSearch = search;
			  
			  // add a throbber
		  	  $("#suggest").addClass('throbber');
		  
			  // do our search suggestion too        
			  var suggest_arr = [Query + searchEnc, "Market=en-IN", "JsonType=callback", "JsonCallback=?"];
			  var suggest_requestStr = "http://api.bing.net/qson.aspx?" + suggest_arr.join("&");
			  
			  $.ajax({
				  type: "GET",
				  url: suggest_requestStr,
				  dataType: "jsonp",
				  cache: true,
				  timeout: 5,
				  success: function(msg) {
						if(lastSearch!='')
						{
							SuggestCompleted(msg, search);
						}
				  },
				  error: function(msg) {
					  alert("Something hasn't worked\n" + msg.d);
				  },
				  complete: function() {
				  	  // remove the throbber from the search box
					  if(lastSuggestSearch==lastSuggestResult)
					  {
					  	$("#suggest").removeClass('throbber');
					  }
				  }
			  });
		  
		  }
		  
	}

}

// search is complete
function SearchCompleted(response, search) {

	lastResult = search;
	
	var errors = response.SearchResponse.Errors;
	if (errors != null) {
		// There are errors in the response. Display error details.
		DisplayErrors(errors);
	}else {
		// There were no errors in the response. Display the Web results.
		DisplayResults(response);
	}
}
  
// whoops we had some errors
function DisplayErrors(response) {
	
	var output = ['<p>' , response , '</p>'].join();
	$("div#results").html(output);
	
}
  
function DisplayResults(response) {
		
	// get web results
	var webResultOutput = webResults(response);	
	$("div#txtresults").html(webResultOutput);

	// get image results
	var imgResultOutput = imgResults(response);	
	$("div#imgresults").html(imgResultOutput);
	
	// get image results
	var videoResultOutput = videoResults(response);	
	$("div#videoresults").html(videoResultOutput);

	// get related searches
	var relatedOutput = relatedResults(response);
	$("div#related").html(relatedOutput);

}

function clearResults()
{	
	$("div#txtresults").html('');
	$("div#imgresults").html('');
	$("div#videoresults").html('');
	$("div#related").html('');
	$("div#suggest").html('');
}



// process web results
function webResults(response)
{
	if(response.SearchResponse.Web != null)
	{
		var searchResults = response.SearchResponse.Web.Results;
	}else{
		var searchResults = null;
	}
	var webResultOutput = [];
	
	if (searchResults != null) {
		
		webResultTotal = response.SearchResponse.Web.Total;
		if (webResultTotal > 40)
		{
			webResultShow = 40;
		}else{
			webResultShow = webResultTotal;
		}

		webResultOutput.push('<ul>');
		webResultOutput.push('<br><span class="thdr" style="float:left"><b>Web Search Results</b></span><span class="suggestions" style="float:right">Found <b>' , webResultTotal , '</b> results for <b><i>' , response.SearchResponse.Query.SearchTerms , '</i></b></span></span><div style="clear:both"></div>');
		webResultOutput.push('<hr noshade size=1 width="100%">');
		webResultOutput.push('<div align="right"><a href="index.html#' , response.SearchResponse.Query.SearchTerms , '" class="myButton">Web</a>&nbsp;<a href="images.html#' , response.SearchResponse.Query.SearchTerms , '" class="myButton">Images</a>&nbsp;<a href="videos.html#' , response.SearchResponse.Query.SearchTerms , '" class="myButton">Videos</a></div>');


		$.each(searchResults, function(i,searchResult){
		
			if (searchResult.Description == null){searchResult.Description = '';}
		
			webResultOutput.push( 
					  '<a href="' , searchResult.Url , '" class="lnkhdr"><b>' , searchResult.Title , '</b></a>' ,
					 '<p class="desc">' , searchResult.Description , '</p>' ,
					 '<p class="url">' , searchResult.DisplayUrl , '</p><br>' 
					  );
		});
		
		webResultOutput.push('</ul><p align="right"><b><a href="http://www.bing.com/search?q=', urlencode(response.SearchResponse.Query.SearchTerms) ,'&first=41" class="suggestionslink">More Results</a></b></p>');

	}
		
	return webResultOutput.join('');
}

// process image results
function imgResults(response)
{
	if(response.SearchResponse.Image != null)
	{
		var imgResults = response.SearchResponse.Image.Results;
	}else{
		var imgResults = null;
	}
	var imgResultOutput = [];
	   
	if (imgResults != null) {

		imgResultOutput.push('<table border=0 width="93%"><tr><td align="left" class="thdr" width="50%"><b>Images:</b></td><td width="50%" align="right"><b><a href="http://www.bing.com/images/search?q=', urlencode(response.SearchResponse.Query.SearchTerms) ,'" class="suggestionslink">More Results</a></b></td><td></td></tr></table><ul>');
		
		$.each(imgResults, function(i,imgResult){

			imgResultOutput.push( 
					 '<li>' , 
					 '<a href="' , imgResult.MediaUrl , '">' , '<img src="' , imgResult.Thumbnail.Url , '" title="' , imgResult.Title , '" alt="' , imgResult.Title , '" /></a></p>' ,
					 '</li>'
					 );
		
		});
		
		imgResultOutput.push('</ul>');
	}
	
	return imgResultOutput.join('');
}

// process video results
function videoResults(response)
{
	if(response.SearchResponse.Video != null)
	{
		var videoResults = response.SearchResponse.Video.Results;
	}else{
		var videoResults = null;
	}
	var videoResultOutput = [];
	   
	if (videoResults != null) {
		videoResultOutput.push('<table border=0 width="93%"><tr><td align="left" class="thdr" width="50%"><b>Videos:</b></td><td width="50%" align="right"><b><a href="http://www.bing.com/videos/search?q=', urlencode(response.SearchResponse.Query.SearchTerms) ,'" class="suggestionslink">More Results</a></b></td><td></td></tr></table><ul>');
		
		$.each(videoResults, function(i,videoResult){

			videoResultOutput.push(
					 '<li>' , 
					 '<p><a href="' , videoResult.PlayUrl , '">' , '<img src="' , videoResult.StaticThumbnail.Url , '" title="' , videoResult.Title , '" alt="' , videoResult.Title , '" /></a></p>' ,
					 '</li>'
					 );
		
		});
		
		videoResultOutput.push('</ul>');
	}
	
	return videoResultOutput.join('');
}

function relatedResults(response)
{
	if(response.SearchResponse.RelatedSearch != null)
	{
		var relatedResults = response.SearchResponse.RelatedSearch.Results;
	}else{
		var relatedResults = null;
	}
	var relatedOutput = [];
	   
	if (relatedResults != null) {
		
		relatedOutput.push('<br><p class="thdr">Suggestions:</p>');

		$.each(relatedResults, function(i,relatedResult){

			relatedOutput.push(
					 ' <a href="#' , urlencode(relatedResult.Title) , '" class="suggestionslink">' , relatedResult.Title , '</a><br> ' 
					 );
		
		});
		
		relatedOutput.push('<br><br><P class="suggestions"><small>Results provided by Bing™</small></p> ');
	}
	
	return relatedOutput.join('');
}

function SuggestCompleted(response, search) {
	
	lastSuggestResult = search;

	var suggestResults = response.SearchSuggestion.Section;

	var suggestOutput = [];
	
	if (suggestResults != null)
	{
	
		suggestOutput.push('<ul>');

		$.each(suggestResults, function(i,suggestResult){
			
			suggestOutput.push(
					 '<li>' ,
					 '<p><a href="#' , urlencode(suggestResult.Text) , '">' , suggestResult.Text , '</a></p>' ,
					 '</li>'
					 );
		
		});
		
		suggestOutput.push('</ul>');
		
	}
	
	$("#suggest").html(suggestOutput.join(''));

}
  
function checkHash()
{
  if (doCheckHash == true)
  {
	  var hashQuery = getHash();
	  if (hashQuery!=getSearch()){
		  defineSearch(hashQuery);
	  }
  }
}  

function getHash()
{
	var hash = location.hash;
	hash = urldecode(hash.replace("#",""));
	
	return hash;
}

function setHash(query)
{
	var hash = urlencode(query);
	location.hash = hash;
}

function checkSuggest()
{
	if (doCheckHash != true)
	  {
		if ($('#suggest').html()!='')
		{
			$('#suggest').slideDown();
		}else{
			$('#suggest').slideUp();
		}
	  }else{
		  $('#suggest').slideUp();
	  }
}

function getSearch()
{
	return trimQuery($('#searchbox').val());
}

function trimQuery(query)
{
	return jQuery.trim(query);
}

function defineSearch(query)
{
	$('#searchbox').val(query);
	if (query != '')
	{
		doSearch(query);
	}else{
		lastSearch = '';
		lastResult = '';
		clearResults();
	}
}

$("input#searchbox").click(function(){
	doCheckHash = false; 
});

$("input#searchbox").focus(function(){
	doCheckHash = false;
});

// every time we press a key in the search box
$("input#searchbox").keyup(function() {
			
	var searchTerms = getSearch();
	if (searchTerms != '')
	{
		  doSearch(searchTerms);
	}else{
		  lastSearch = '';
 		  lastResult = '';
		  clearResults();
	}	  
	
}); 

// if we exit the textbox and it's changed
$("input#searchbox").change(function() {
			
	var searchTerms = getSearch();
	doSearch(searchTerms,null,true);
	
	setHash(searchTerms);
	
}); 

$("input#searchbox").blur(function(){
	
	setHash(getSearch());
	
	doCheckHash = true;
	
});

$("div#related a").live("click",function(){

	defineSearch($(this).text());

});

$("div#suggest a").live("click",function(){
	defineSearch($(this).text());

});

$("div#suggest a").live("mouseover",function(){

	doSearch($(this).text(), false, true);

});

$("div#suggest").mouseleave(function(){

	doSearch(getSearch());

});


// we don't want to check hash yet
var doCheckHash = false;

// just loaded our page, lets check the hash
var startHash = getHash();
if(startHash!='')
{
	defineSearch(startHash);
}

// set timers to do automatic hash checking and suggestions checking
setInterval(checkHash,500);
setInterval(checkSuggest,500);

});



function urlencode (str) {
  // http://kevin.vanzonneveld.net
  // +   original by: Philip Peterson
  // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // +      input by: AJ
  // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // +   improved by: Brett Zamir (http://brett-zamir.me)
  // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // +      input by: travc
  // +      input by: Brett Zamir (http://brett-zamir.me)
  // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // +   improved by: Lars Fischer
  // +      input by: Ratheous
  // +      reimplemented by: Brett Zamir (http://brett-zamir.me)
  // %          note 1: This reflects PHP 5.3/6.0+ behavior
  // *     example 1: urlencode('Kevin van Zonneveld!');
  // *     returns 1: 'Kevin+van+Zonneveld%21'
  // *     example 2: urlencode('http://kevin.vanzonneveld.net/');
  // *     returns 2: 'http%3A%2F%2Fkevin.vanzonneveld.net%2F'
  // *     example 3: urlencode('http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a');
  // *     returns 3: 'http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a'

  var hexStr = function (dec) {
	  return '%' + dec.toString(16).toUpperCase();
  };

  var ret = '',
		  unreserved = /[\w.-]/; // A-Za-z0-9_.- // Tilde is not here for historical reasons; to preserve it, use rawurlencode instead
  str = (str+'').toString();

  for (var i = 0, dl = str.length; i < dl; i++) {
	  var ch = str.charAt(i);
	  if (unreserved.test(ch)) {
		  ret += ch;
	  }
	  else {
		  var code = str.charCodeAt(i);
		  // Reserved assumed to be in UTF-8, as in PHP
		  if (code === 32) {
			  ret += '+'; // %20 in rawurlencode
		  }
		  else if (code < 128) { // 1 byte
			  ret += hexStr(code);
		  }
		  else if (code >= 128 && code < 2048) { // 2 bytes
			  ret += hexStr((code >> 6) | 0xC0);
			  ret += hexStr((code & 0x3F) | 0x80);
		  }
		  else if (code >= 2048 && code < 65536) { // 3 bytes
			  ret += hexStr((code >> 12) | 0xE0);
			  ret += hexStr(((code >> 6) & 0x3F) | 0x80);
			  ret += hexStr((code & 0x3F) | 0x80);
		  }
		  else if (code >= 65536) { // 4 bytes
			  ret += hexStr((code >> 18) | 0xF0);
			  ret += hexStr(((code >> 12) & 0x3F) | 0x80);
			  ret += hexStr(((code >> 6) & 0x3F) | 0x80);
			  ret += hexStr((code & 0x3F) | 0x80);
		  }
	  }
  }
  return ret;
}

function urldecode (str) {
  // http://kevin.vanzonneveld.net
  // +   original by: Philip Peterson
  // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // +      input by: AJ
  // +   improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // +   improved by: Brett Zamir (http://brett-zamir.me)
  // +      input by: travc
  // +      input by: Brett Zamir (http://brett-zamir.me)
  // +   bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
  // +   improved by: Lars Fischer
  // +      input by: Ratheous
  // +   improved by: Orlando
  // %        note 1: info on what encoding functions to use from: http://xkr.us/articles/javascript/encode-compare/
  // *     example 1: urldecode('Kevin+van+Zonneveld%21');
  // *     returns 1: 'Kevin van Zonneveld!'
  // *     example 2: urldecode('http%3A%2F%2Fkevin.vanzonneveld.net%2F');
  // *     returns 2: 'http://kevin.vanzonneveld.net/'
  // *     example 3: urldecode('http%3A%2F%2Fwww.google.nl%2Fsearch%3Fq%3Dphp.js%26ie%3Dutf-8%26oe%3Dutf-8%26aq%3Dt%26rls%3Dcom.ubuntu%3Aen-US%3Aunofficial%26client%3Dfirefox-a');
  // *     returns 3: 'http://www.google.nl/search?q=php.js&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:en-US:unofficial&client=firefox-a'
  
  var hash_map = {}, ret = str.toString(), unicodeStr='', hexEscStr='';
  
  var replacer = function (search, replace, str) {
	  var tmp_arr = [];
	  tmp_arr = str.split(search);
	  return tmp_arr.join(replace);
  };
  
  // The hash_map is identical to the one in urlencode.
  hash_map["'"]   = '%27';
  hash_map['(']   = '%28';
  hash_map[')']   = '%29';
  hash_map['*']   = '%2A';
  hash_map['~']   = '%7E';
  hash_map['!']   = '%21';
  hash_map['%20'] = '+';
  hash_map['\u00DC'] = '%DC';
  hash_map['\u00FC'] = '%FC';
  hash_map['\u00C4'] = '%D4';
  hash_map['\u00E4'] = '%E4';
  hash_map['\u00D6'] = '%D6';
  hash_map['\u00F6'] = '%F6';
  hash_map['\u00DF'] = '%DF';
  hash_map['\u20AC'] = '%80';
  hash_map['\u0081'] = '%81';
  hash_map['\u201A'] = '%82';
  hash_map['\u0192'] = '%83';
  hash_map['\u201E'] = '%84';
  hash_map['\u2026'] = '%85';
  hash_map['\u2020'] = '%86';
  hash_map['\u2021'] = '%87';
  hash_map['\u02C6'] = '%88';
  hash_map['\u2030'] = '%89';
  hash_map['\u0160'] = '%8A';
  hash_map['\u2039'] = '%8B';
  hash_map['\u0152'] = '%8C';
  hash_map['\u008D'] = '%8D';
  hash_map['\u017D'] = '%8E';
  hash_map['\u008F'] = '%8F';
  hash_map['\u0090'] = '%90';
  hash_map['\u2018'] = '%91';
  hash_map['\u2019'] = '%92';
  hash_map['\u201C'] = '%93';
  hash_map['\u201D'] = '%94';
  hash_map['\u2022'] = '%95';
  hash_map['\u2013'] = '%96';
  hash_map['\u2014'] = '%97';
  hash_map['\u02DC'] = '%98';
  hash_map['\u2122'] = '%99';
  hash_map['\u0161'] = '%9A';
  hash_map['\u203A'] = '%9B';
  hash_map['\u0153'] = '%9C';
  hash_map['\u009D'] = '%9D';
  hash_map['\u017E'] = '%9E';
  hash_map['\u0178'] = '%9F';
  hash_map['\u00C6'] = '%C3%86';
  hash_map['\u00D8'] = '%C3%98';
  hash_map['\u00C5'] = '%C3%85';

  for (unicodeStr in hash_map) {
	  hexEscStr = hash_map[unicodeStr]; // Switch order when decoding
	  ret = replacer(hexEscStr, unicodeStr, ret); // Custom replace. No regexing
  }
  
  // End with decodeURIComponent, which most resembles PHP's encoding functions
  ret = decodeURIComponent(ret);

  return ret;
}



