
function sh_toggle_filter(toggle) {

  var node = toggle.parentNode.parentNode.parentNode;
  var is_expanded = node.className == 'sh_filter sh_expanded';
  node.className = is_expanded ? 'sh_filter' : 'sh_filter sh_expanded';
  toggle.innerHTML = is_expanded ? 'See More &raquo;' : '&laquo; See Less';

  return false;
}

function sh_toggle_filters(toggle) {

  var node = toggle.parentNode.parentNode.parentNode;
  var is_expanded = node.className == 'sh_filters sh_filters_expanded';
  node.className = is_expanded ? 'sh_filters' : 'sh_filters sh_filters_expanded';
  toggle.innerHTML = is_expanded ? 'See More Filters &raquo;' : '&laquo; See Less Filters';

  return false;
}

function sh_toggle_description (position) {
  if (document.getElementById('sh_description_'+ position).style.display == 'none') {
    document.getElementById('sh_description_'+ position).style.display = 'block';
    document.getElementById('sh_details_toggle_'+ position).innerHTML = '(hide details)';
  } else {
    document.getElementById('sh_description_'+ position).style.display = 'none';
    document.getElementById('sh_details_toggle_'+ position).innerHTML = '(details)';
  }
}

//callback invoked by google
function google_afs_request_done(googleAds) {
  //if (googleAds.length) new shGoogleAds(googleAds,'sh_google_ads');
  var tAds = [];
  var bAds = [];
  var rAds = [];
  
  while (googleAds.length) {
    var ad = googleAds.shift();
    if (tAds.length < sh_afs_top) tAds.push(ad);
    else if (rAds.length < sh_afs_rail) rAds.push(ad);
    else bAds.push(ad);
  }
  
  /*while (googleAds.length) {
    var ad = googleAds.shift();
    if (ad.type == 'text/wide') bAds.push(ad);
    else if (ad.type == 'text/narrow') rAds.push(ad);
  }
  if (bAds.length && sh_afs_top) {
    tAds = bAds.splice(0,sh_afs_top);
    }*/
  if (tAds.length) new shGoogleAds(tAds,'sh_google_ads_top'); //search results
  if (rAds.length) new shGoogleAds(rAds,'sh_google_ads_rail'); //right rail
  if (bAds.length) new shGoogleAds(bAds,'sh_google_ads_bottom'); //search results
    

}

function shGoogleAds(ads,node) {

  this.ads          = ads;
  this.node         = document.getElementById(node); //ads node

  this.keywords     = sh_afs_highlight ? this.parse_keywords(sh_afs_keywords) : false;

  this.heading      = sh_afs_heading;
  this.feedback_url = sh_afs_feedback;

  if (!this.node) return;

  if (this.ads.length && this.node) {
    this.render_heading();
    this.render_ads();
  } else if (this.node) { //no ads
    var parent = this.node.parentNode;
    parent.removeChild(this.node);
    this.node = null;
  }

}

shGoogleAds.prototype.render_heading = function() {

  if (this.node.getElementsByTagName('H4').length) return;

  var h4 = document.createElement('H4');
  h4.innerHTML = this.feedback_url ? '<a href="'+this.feedback_url+'">'+this.heading+'</a>' : this.heading;

  this.node.appendChild(h4);

}

shGoogleAds.prototype.render_ads = function() {

  var ul = document.createElement('UL');
  ul.className = '_'+this.ads.length;
  this.node.appendChild(ul);

  for (var i=0, n=this.ads.length; i<n; i++) {

    var ad = this.ads[i];

    var li = document.createElement('LI');
    li.className = 'link';
    li.innerHTML = this.get_ad_html(ad,i);

    ul.appendChild(li);
  }

}

shGoogleAds.prototype.get_ad_html = function(ad,n) {

  var html = '<a class="title" href="{{url}}" onmouseover="window.status=\'{{visible_url}}\';return true" onmouseout="window.status=\'{{visible_url}}\';return true">{{heading}}</a><p class="text">{{description}}</p><a class="site" href="{{url}}" onmouseover="window.status=\'{{visible_url}}\';return true" onmouseout="window.status=\'{{visible_url}}\';return true">{{visible_url}}</a>';

  html = html.replace(/{{heading}}/g,this.highlight_keywords(ad.line1));
  html = html.replace(/{{description}}/g,this.highlight_keywords(ad.line3?ad.line2+' '+ad.line3:ad.line2));
  html = html.replace(/{{visible_url}}/g,this.highlight_keywords(ad.visible_url));
  html = html.replace(/{{url}}/g,ad.url);
  html = html.replace(/{{n}}/g,n);

  return html;
}

shGoogleAds.prototype.highlight_keywords = function(string) {

  if (!this.keywords) return string;

  for (var i=0, n=this.keywords.length; i<n; i++) {
    var keyword = this.keywords[i];
    var regex = new RegExp('(\\b'+keyword+'\\b)','gi');
    string = string.replace(regex,'<strong>$1</strong>');
  }

  return string;
}

shGoogleAds.prototype.parse_keywords = function(keywords_string) {

  if (!keywords_string) return false;

  keywords_string = keywords_string.replace(/\s+/g,' '); //trim
  keywords_string = keywords_string.replace(/^\s+|\s+$/g,''); //trim
  keywords_string = keywords_string.replace(/(^|\W)\w+\s*:\s*\(?(.+?)\)?/,'$2'); //remove filter
  keywords_string = keywords_string.replace(/(\^|\$|\*|\+|\?|\=|\!|\:|\||\\|\/|\(|\)|\[|\]|\{|\})/g,'\\$1'); //bug 17476

  var parser = new shParser(keywords_string);
  var keywords = parser.parse();

  return keywords;
}


function shParser(raw_string) {

  this.raw_string = raw_string;

}

shParser.prototype.parse = function() {

  var keywords = [];

  while (this.has_token()) {
    var token = this.next_token();
    if (token.length > 0) keywords.push(token);
  }

  return keywords;
}

shParser.prototype.next_token = function() {

  var index = this.raw_string.indexOf('"');  
  var token = '';

  if (index == 0) {
    index = this.raw_string.indexOf('"',1) + 1;
  } else {
    index = this.raw_string.indexOf(' ');
  }  

  if (index > -1) {
    token = this.raw_string.substr(0,index);
  } else {
    token = this.raw_string;
    this.raw_string = '';
  }

  this.raw_string = this.raw_string.substr(index + 1);

  if (/^AND$|^OR$/.exec(token)) {
    token = this.next_token();      
  } else if (/\bNOT\b/.exec(token)) {
    this.next_token();
    token = ''; //ignore token
  } else if(/^".+?"$/.exec(token)) {
    token = token.replace(/^"(.+?)"$/,'$1');
  } else if(/^\W+$/.exec(token)) {
    token = ''; //ignore token
  } else if(/^\W*.+?\W*$/.exec(token)) { //garbage in the end
    token = token.replace(/^\W*(.+?)\W*$/, '$1');
  }

  return token;
}

shParser.prototype.has_token = function() {

  return this.raw_string.length > 0;
}
