//Search result filtering script - Satama Interactive
//Author: Satama Interactive 
// Sakari Laaksonen - Naviatech Solutions
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();
      
  //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 : ''};
   this.makeQuery = function() {
    var params ='';
    for(var param in this.queryObj) {
        var value = this.queryObj[param];
        if(param == "extqt") continue;
        else 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);
     $('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);
  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;
      //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">Category: ';
      footer += '<span class="rCat">'+this.cat+'</span> ';
     footer += ' <a class="'+this.tClass+'" href="'+this.linkToPage+'"';
     this.full ? footer += ' class="full-content"> | Read more...</a>' : footer += '> | Go to this page</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()) {    $('.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) {

   //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(){
    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 ;
    IE() ? 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);
  }
  
  
 });
