/*
 @Search result filtering script
 @Last modified: 06.10.2008
 ***/
var debug = false;

// DATA STRUCTURES \\
function SearchData() {
	this.mlc = hbx.mlc;
	this.anim =  new Array();
	this.queryObj;
	this.testXml;
	this.keywordsXml; //keyword storage
	this.request;
	this.msgs; 
	this.xmlData;
	this.lastQuery = '';
	this.filters;
	this.queryObj = new Array();
	this.resultFooter; //text used in the bottom of each result

	//combine all categories
	for(var cat in this.categories) {
		var value = this.categories[cat];
		this.categories.viewall += ','+value;
	}

	//search meta data
	this.searchMeta = { totalResults : '', itemsPerPage : '', startIndex : '' , endIndex : '' , numOfPages : ''};

	//generate the query string
	this.makeQuery = function() {
		var params ='';
		for(var param in this.queryObj) {
			//get rid of indexOf function-data in IE URL params
			if(param == 'indexOf') {
				continue;
			}
			var value = this.queryObj[param];
			if(param == "extqt") continue;
			else {
				//URI encode the user query
				if(param == "qt") {
					value = encodeURI(value);
				}
				params += '&'+param + '='+ value;
			}
		}
		//insert a unique stamp to override browser cache bugs
		//jquery does not always add this 
		return 'uniq='+new Date().getTime() + params;
	}

	this.errorMsg = function(msgName) {
		root = $('messages',this.xmlData);
		$("msg",root).each(function() {
		var err = $(this).attr('err')
			if(err == msgName) {
				$('.error-msg').text($(this).text()).show();
				return true;
			}
		});
		return false;
	}

		this.setXMLVars = function() {
			var full = new Array(); 
			var config;
			$.ajax({ 
			type: "GET",  cache:false,
			async:false, 
			dataType : 'xml',
			url: $('#config').val(),
			error:function(){SearchVars.errorMsg('initErr')},
			success:function (tmp) {config = tmp;} 
		});

		 this.xmlData = config;
		 this.request = $('liveresults',this.xmlData).attr('url');
		 this.testXml =$('testresults',this.xmlData).attr('url');
		 //convert strings to numbers ( * 1)

		 this.anim = {tabMin:$('tabmin',this.xmlData).attr('width') * 1, tabMax:$('tabmax',this.xmlData).attr('width') * 1};

		 this.filters = $('filters',this.xmlData);

		 //fetch the result footer captions from the importaed XML object
		 var rfxml = $('resultfooter',this.xmlData);

		 //create an easy to access object with result footer data
		 this.resultFooter = { 
													 readmore: $("text#readmore", rfxml).text(), 
													 category: $("text#category", rfxml).text(),
													 gotopage: $("text#gotopage", rfxml).text() 
												 }

		 $('cat',this.filters).each( function() {
		 if ($(this).attr('fullcontent') !== undefined) {full.push($(this).text() );};
		 });

		 var params = $('param',this.xmlData);
		 var qObj = new Array();
		 for(k=0;k<params.length;k++) {
			 var id =params.get(k).getAttribute('id');
			 var val = params.get(k).getAttribute('val');
			 qObj[id] = val;     

		 }

		 qObj['cat'] = '';
		 qObj['scope'] = '*';
		 qObj['fc'] = $('filter default:first',this.xmlData).parent().attr('id');
		 this.queryObj = qObj;
		 if($('#comp').val() !== undefined) {
			this.queryObj.comp = $('#comp').val();
		 }
		 if($('#wsid').val() !== undefined) {
			this.queryObj.wsid = $('#wsid').val();
		 }
		 this.fullcontent = full.join();


		}

	this.setFilterVars = function (fc) {
			var cats = new Array();
			var scopes = new Array();
			var key;
			fc == 'viewall' ? key = 'filter' : key = '#'+fc ;
			$(key,this.filters).find('cat').each( function(){
				cats.push($(this).text());
			 }).end().find('scp').each( function(){
			 scopes.push($(this).text());
			 });
			this.queryObj.fc= fc;
			this.queryObj.cat= cats.join();
			this.queryObj.scope=scopes.join();

	}
	this.setXMLVars();
}

function capitalize (someString) {
	return someString.charAt(0).toUpperCase() + someString.substr(1).toLowerCase();
}


function GetHashVars() {
	var query, qs = top.location.hash.substring(1);
	//decodes the escaped Unicode strings
	qs = decodeURI(qs);
	var queries = qs.split(/\&/);
	for (var i=0; i<queries.length; i++) {
		query = queries[i].split(/\=/);
		this[query[0]] = (typeof query[1] == 'undefined') ? null : unescape(query[1]).replace(/\+/g," ");
	}
}

//helper object for transforming XML data to XHTML 
function ResultItem(pd,ct,lk,tl,dc,rn,full) {
	//item container object
	this.pubDate = pd;
	this.cat = ct;
	this.linkToPage = lk;
	this.title = tl;
	this.desc = dc;
	this.full = full;
	this.rf = SearchVars.resultFooter;  //result footer (an object with three text fields)

	//other vars
	this.tClass = 'rLink';
	//convert to html
	this.toXHTML = function() {
		var resultParts = new Array();
		if(this.full) { this.tClass += ' full-content';}

		//title
		resultParts.push('<div class="result"><a class="'+this.tClass+'" href="'+ this.linkToPage+'">'+ this.title + "</a>\n\r");

		//description
		resultParts.push('<div class="rDesc">' + this.desc + "</div>\n\r");
		//content

		//footer
		var footer = '<div class="rFooter">' + this.rf.category;

		footer += '<span class="rCat">'+this.cat+'</span> ';
		footer += ' <a class="'+this.tClass+'" href="'+this.linkToPage+'"';
		this.full ? footer += ' class="full-content"> | ' + this.rf.readmore + '</a>' : footer += '> | ' + this.rf.gotopage + '</a>';
		if(this.cat == 'discussions'){footer += '<span class="rPub">'+this.pubDate+'</span>';}
		footer +='</div>'; // close footer
		resultParts.push(footer);
		resultParts.push('</div>'); //close result container
		return resultParts.join('');
	}
}

 //FUNCTIONS FOR BROWSER QUIRKS \\
 function FF3() { 
	 if(navigator.userAgent.match("rv:1\.9")) {
		 return true;
	 } else {
		 return false;
	 }
 }

 function IE() { return navigator.appName == "Microsoft Internet Explorer";}
 function IE6() {
	if(navigator.appName == "Microsoft Internet Explorer" &&  navigator.appVersion.match('MSIE 6.0')) {
	return true; ;} else {return false;}
 }
 function Opera(){return window.opera !== undefined;
 }


function handleEnterKey(evt) {
	var evt = (evt) ? evt : ((event) ? event : null);
	var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
	if ((evt.keyCode == 13) && (node.type=="text"))  {
	runSearch('solutions');
	return false; 
	}
} 

//ANIMATION & AJAX\\

function fadeTextIn(results) {
	if( IE() || Opera() || FF3() ) {    $('.result-inner').empty().append(results).slideDown('fast',attachLinkEvents);}
	else { $('.result-inner').empty().append(results).fadeIn('normal',attachLinkEvents);}
}

// function fadeTextOut() {
//   if( IE() || Opera()) {    $('.result-inner').empty().slideUp('fast');}
//   else { $('.result-inner').empty().fadeOut('normal');}
// }

function enableTabs() {
 //add event listener to all closed tabs
 $('ul.tab-list li').click(function() {
	$('#tabTip').empty();
	if(!this.id.match('open')) {runSearch(this.className);}
 }).hover(
	function () {$('#tabTip').text($('.top-control span.'+this.className ).text());},
	function () {$('#tabTip').empty();}
 );
}

function attachLinkEvents() {
	//add toggle function to result headers
	$('.full-content').click(thisResult);
}

function saveSearch() {top.location.hash = SearchVars.lastQuery;}

function reloadSearch() {

	hashVars.qt === undefined ? 
		hashVars.extqt === undefined ? $('#qt').val('') : $('#qt').val(hashVars.extqt): 
	$('#qt').val(hashVars.qt);
	$('#page').val(hashVars.page);
	SearchVars.queryObj.fc = hashVars.fc;
	runSearch(SearchVars.queryObj.fc);
}

function runSearch(fc) {

	var q = $('#qt').val();
	if(q == '') {
	 SearchVars.errorMsg('empty');
	 return false;
	}

	$('#resultsContainer').show();
	SearchVars.queryObj.qt = q;
	SearchVars.setFilterVars(fc);
	SearchVars.queryObj.page = parseInt($('#page').val());
//show result UI if it was hidden and add the filtering class to change background image
$('#resultsContainer').css('display','block').attr('class','').addClass(fc);
//hide current text and possible error messages
 $('.result-inner').empty();
	$('.show-list').hide(); //hide "show list -button if it was visible" 
	$('#searchContainer .intro').show();

	//animate tabs
	$('ul.tab-list').find('li').unbind().end().find('li#open').attr('id','').animate(
		{ paddingRight: SearchVars.anim.tabMin , paddingLeft:SearchVars.anim.tabMin }, 
		{ duration: 'slow', easing: 'swing'}).end().find('.'+fc).attr('id','open').animate(
		{ paddingRight: SearchVars.anim.tabMax, paddingLeft: SearchVars.anim.tabMax }, 
		{ duration: 'normal', easing:'swing',complete:getResults });
}

function getResults(){
$('.error-msg').empty().hide();
var q;
debug == true ?  q = SearchVars.testXml :  q = SearchVars.request;
	//send ajax query
	$.ajax({ //no caching, apply error handling, expect XML data, enable tabs when request is completed
		type: "GET",  cache:false,  
		error:function(){SearchVars.errorMsg('searchErr');},
		url: q,  dataType: "xml",
		async:false,
		data:SearchVars.makeQuery(),
		complete: enableTabs ,  
		success:function(data) {parseData(data);}
	});
}//end of function

function parseData(data) {
	
	// * Query recording code * //
	//Variables for storing search and solve queries
	var keywords = SearchVars.queryObj.qt;
	if( $('#comp').val() !== undefined) {
		var phonemodel = $('#comp').val();
	} else {
	  var phonemodel = SearchVars.queryObj.comp;
	}
	var site = SearchVars.queryObj.wsid;
	var firstmatchlink='';
	var firstmatchheader='';
	// * End Query recording code * //

  //if request is succesful, process the data
  SearchVars.lastQuery = SearchVars.makeQuery();  
  var hbxFc = capitalize(SearchVars.queryObj.fc); 
  var itemCount= $('item',data).size();
  //if there are no items, show error message and hide page numbers
  if(itemCount < 1 ) {
 	  SearchVars.errorMsg('noResults')
		fadeTextIn('');
		if(!debug)  _hbPageView(SearchVars.queryObj.qt , SearchVars.mlc + '/Ajax+Search+Page/'+hbxFc+'/Failure'); 
		$('.total-results-container').hide();
		$('.num-of-pages-container').hide();
		return;
	} 
	var formatted = new Array();  //container array for XHTML;
	if(!debug)  _hbPageView(SearchVars.queryObj.qt , SearchVars.mlc + '/Ajax+Search+Page/'+hbxFc+'/Success'); 
	
	$('item',data).each(function(counter){
		var content;
		var categories;
		var category=[];
		var title = $('title',this).text();
		var pubDate = $('pubDate',this).text();
		var description = $('description',this).text();
		var linkToPage = $('link',this).text();
		var full = 0;
		var catName ;

		// * Query recording code * //
		//search and solve first matches
		if ( counter == 0 ) {
			firstmatchlink=title;
			firstmatchheader=linkToPage;
			counter++;
			//Storing the search - requires storeSearch.js
			try {
			//do nothing if storeSearch() is not found
				storeSearch(keywords,phonemodel,site,firstmatchlink,firstmatchheader,description);
		  } catch(e) { }
		}
		// * End Query recording code * //

		(IE() || FF3()) ? categories = $('ncsearch\\:categories > *',this) :  categories = $('categories > *',this) ;

		categories.each(function(){
			if(SearchVars.fullcontent.indexOf($(this).text()) != -1 ){
							full = 1;
			};
			category.push($(this).text());

			$('categorytitles tag',SearchVars.xmlData).each( function() {
			 for(c=0;c<category.length;c++) {
				 if($(this).attr('names').indexOf(category[c]) != -1 ) {
				   catName = $(this).text();
				 }
				 break;
			 }
		  });
	  });

	 var result = new ResultItem(pubDate,catName,linkToPage,title,description,itemCount,full)
	 formatted.push(result.toXHTML());   

	}) ;
	 //get search metadata
	 //in case of IE or Firefox 3 being used prepend the tag names from the XML file with "opensearch :"
	 (IE() || FF3()) ? ns = 'opensearch:': ns = '';
	 SearchVars.searchMeta.totalResults = parseInt(data.getElementsByTagName(ns+'totalResults')[0].firstChild.nodeValue);
	 SearchVars.searchMeta.startIndex = parseInt(data.getElementsByTagName(ns+'startIndex')[0].firstChild.nodeValue);
	 SearchVars.searchMeta.itemsPerPage = parseInt(data.getElementsByTagName(ns+'itemsPerPage')[0].firstChild.nodeValue);
	 SearchVars.searchMeta.numOfPages = Math.ceil(parseInt(SearchVars.searchMeta.totalResults)/parseInt(SearchVars.searchMeta.itemsPerPage)); // round up
	 SearchVars.searchMeta.endIndex = ( SearchVars.searchMeta.startIndex + $('item',data).size() ) -1;

	//put values to the page
	$('.start-index').text(SearchVars.searchMeta.startIndex);
	$('.end-index').text(SearchVars.searchMeta.endIndex);
	$('.total-results').text(SearchVars.searchMeta.totalResults);
	$('.num-of-pages').text(SearchVars.searchMeta.numOfPages);
	$('.page-num').text(SearchVars.queryObj.page);
 //get all item nodes

	fadeTextIn( formatted.join("\n\r") );
	toggleControls(); 
	saveSearch();
}

function toggleControls( ) {
		$('.total-results-container').show();
		$('.num-of-pages-container').show();
	//show next-button if there are more than one page, otherwise hide it
		SearchVars.searchMeta.numOfPages > 1 ? 
			SearchVars.searchMeta.numOfPages == SearchVars.queryObj.page ?
				$('.next').hide() : $('.next').show() : $('.next').hide();
	 //show prev-button if the current page is not first, otherwise hide it.
		SearchVars.searchMeta.startIndex > 1 ? $('.prev').show() : $('.prev').hide();             
}

function nextPage() {
	SearchVars.queryObj.page < SearchVars.searchMeta.numOfPages ?  SearchVars.queryObj.page++ : SearchVars.queryObj.page = SearchVars.searchMeta.numOfPages;
	getResults();
}

function prevPage() {
	SearchVars.queryObj.page > 1 ? SearchVars.queryObj.page--  : SearchVars.queryObj.page = 1;
	getResults();
}


function thisResult() {
var html;
var url
var $result = $(this).parent();
	//choose the right element depending whether header or footer was clicked
if( !$result.hasClass('result') ) {$result = $result.parent()}
if($result.hasClass('show-this-result')) { return false;}
	debug == true ? url = 'assets/data/htmlcontent.html' : url = this.href + '&format=portlet';

	$.ajax({ 
		type: "GET",  cache:false,
		url: url,
		error:function(){SearchVars.errorMsg('searchErr')},
		success:function (r) {
			html = r;

			$result.addClass('show-this-result').siblings().css('display','none');
			$result.find('.rDesc').after('<div class="rContent">'+html+'</div>').end().find('.rCat').addClass('show-this-result');
			$('.show-list').show();
			$('.prev').hide();
			$('.next').hide();
			window.scrollBy(0,-5000);
		} 
	});

	return false;
	//add show-this-result class, hide footer link and all other results 
}

function externalResult() {
	var url = location.hash.substr(location.hash.indexOf('=')+1 );
	var html;
	var $rc  = $('.result-inner');
	var portlet = 'format=portlet';
	$('#resultsContainer').show();

	$rc.empty();
	if(url.match(portlet) == null ){ 
		url.indexOf('?') == -1 ?    url += '?'+portlet : url += '&'+portlet;
	}
	$.ajax({ 
		type: "GET",  cache:false,
		url: url,
		error:function(){SearchVars.errorMsg('searchErr')},
		success:function (r) {
			fadeTextIn('<div class="result show-this-result"><div class="rContent">'+r+'</div></div>');
			var linktext = $rc.find('h2').text();     
			$rc.find('.result').prepend('<a href="'+url+'" class="rLink full-content">'+linktext+'</a>');
			$('.show-list').hide();
			$('.prev').hide();
			$('.next').hide();
			$('#resultsContainer').addClass('solutions');
			window.scrollBy(0,-5000);
		} 
	});
	return false;
}

function isValidURL(url){
		var RegExp = /^(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?$/;
		if(RegExp.test(url)){
				return true;
		}else{
				return false;
		}
} 


function showListBtn() {
	$('.rContent').remove();
	$('.show-list').hide();
	$('.result').css('display','block');
 	$('.show-this-result').removeClass('show-this-result');
	toggleControls();
}

/** keyword code **/

//Shows the list of the synonyms or correct spellings - aka suggested keywords
function listSimilarWords(q) {
	var synonyms = $(SearchVars.keywordsXml).find('#keywords #'+q).text().split(',');
	var altSpellings = $(SearchVars.keywordsXml).find('#misspelled #'+q).text().split(',');

	$('#suggestedQueries').empty();

	var foundSynonyms = false;
	var foundAltSpellings = false;

	//split returns empty string as the first element even if nothing was done, so this must be accounted for
	if (synonyms[0] !== '') {
		foundSynonyms = true;
	}
	if (altSpellings[0] !=='') {
		foundAltSpellings = true;
	}

	//list all the synonyms
	for (var i = 0; i < synonyms.length; i++) {
		$('#suggestedQueries').append('<a href="javascript:useWord('+ "'" + synonyms[i] + "'" + '); void(0);">' + synonyms[i] + '</a>');
		if (i < synonyms.length-1) {
			$('#suggestedQueries').append(', ');
		}
	}

	//avoid looking up the same word twice. assume that the alternative spelling is already listed among synonyms!
	if (!foundSynonyms) {
		//list all the alternative spellings
		for (var i = 0; i < altSpellings.length; i++) {
			$('#suggestedQueries').append('<a href="javascript:useWord('+ "'" + altSpellings[i] + "'" + '); void(0);">' + altSpellings[i] + '</a>');
			if (i < altSpellings.length-1) {
				$('#suggestedQueries').append(', ');
			}
		}
	}

	//toggle showing of the related keywords box
	if (foundSynonyms || foundAltSpellings) {
		$('#relatedSearchBox').show();
	} else {
		$('#relatedSearchBox').hide();
	}
}

//Handles clicking on the suggested keywords
function useWord(q) {
	$('#qt').val(q);
	$('#search').submit();
}
/** end keyword code **/

//********* ONLOAD EVENT *******************\\

$(document).ready(function() {
	SearchVars = new SearchData();

/** keyword code **/
	$.ajax({
		type: "GET",
		timeout: 10000,
		cache: false,
		url: keywordsXML,
		error:function() {},
		success:function(xml) {
			SearchVars.keywordsXml = xml;
			listSimilarWords($('#qt').val());
		}
	});
/** end keyword code **/

	 //SearchVars.setFilterVars('solutions'); 
	 //get all hash variables in one JSON object
	 hashVars = new GetHashVars();
	$('#searchContainer span.intro').hide();
	$('.prev').mouseup(prevPage);
	$('.next').mouseup(nextPage);
	$('.show-list').click(showListBtn);

	//attach search functions to tabs
	 enableTabs();
	//run AJAX call

	//replaced attr('disabled','') with removeAttr('disabled') 
	 $('#search').submit(function(){
		 /** keyword code **/
		 //This assumes that that both GETed and user-inputed query value are shown in the input-box
		 listSimilarWords($('#qt').val());
		 /** end keyword code **/
		 runSearch(SearchVars.queryObj.fc); return false;}
	 ).removeAttr('disabled');
	 //modified focus behavior
	 //$('#qt').removeAttr('disabled').val('').focus(function(){this.select()}).focus();
	 $('#qt').removeAttr('disabled').val('');
	 $('#gosearch').removeAttr('disabled');

	if(hashVars.uniq !== undefined) { 
		reloadSearch();
	}
	else if(hashVars.extresult !== undefined) { //load the last search upon reload (does not work with back button :( )
		externalResult();
	}
	else if(hashVars.extqt !== undefined){
		$('#qt').val(hashVars.extqt);      
		/** keyword code **/
		//This assumes that that both GETed and user-inputed query value are shown in the input-box
		listSimilarWords($('#qt').val());
		/** end keyword code **/
		runSearch(SearchVars.queryObj.fc);
	}


 });
