function loadAd(id, AdData, SearchPack)
{
   var url = '/ajax/displayads.php?'+AdData.toQueryString()+'&'+SearchPack.toQueryString();

   new Ajax.Request(url, {
      method: 'get',
      onSuccess: function(transport){
         var response = transport.responseText || null;
         if(response != null)
         {
            $(id).update(response);
            AdsTracker._trackEvent("ad", getImpressionEventString(AdData));
         }
         else
         {
         }
      },
      onFailure: function(){
      }
   });
}

function getImpressionEventString(AdData)
{
   var AdDataLabels = getAdDataLabels();
   var impression_tracking_string = 'impression';
   AdData.each(function(pair) {
      impression_tracking_string += ' '+AdDataLabels.get(pair.key).get(pair.value);
   });
   return impression_tracking_string;
}

function getAdDataLabels()
{
   var AdTypeLabels = new Hash();
   AdTypeLabels.set('1', 'casalemedia');
   AdTypeLabels.set('2', 'advertising.com');
   AdTypeLabels.set('3', 'intelius');
   AdTypeLabels.set('4', 'creditreportandscore');
   AdTypeLabels.set('5', 'classmates ads');
   AdTypeLabels.set('6', 'classmates api');

   var AdSizeLabels = new Hash();
   AdSizeLabels.set('1', '120x600');
   AdSizeLabels.set('2', '300x250');
   AdSizeLabels.set('3', '468x60');
   AdSizeLabels.set('4', '728x90');
   AdSizeLabels.set('5', '160x600');

   var AdPlacementLabels = new Hash();
   AdPlacementLabels.set('0', 'default');
   AdPlacementLabels.set('1', 'header');
   AdPlacementLabels.set('2', 'footer');
   AdPlacementLabels.set('3', 'tower');
   AdPlacementLabels.set('4', 'logo');

   var AdDataLabels = new Hash();
   AdDataLabels.set('AdType', AdTypeLabels);
   AdDataLabels.set('AdSize', AdSizeLabels);
   AdDataLabels.set('AdPlacement', AdPlacementLabels);

   return AdDataLabels;
}

if(typeof Effect != 'undefined') {
   var Autocompleter = { };
   Autocompleter.Base = Class.create({
      baseInitialize: function(element, update, options) {
         element          = $(element);
         this.element     = element;
         this.update      = $(update);
         this.hasFocus    = false;
         this.changed     = false;
         this.active      = false;
         this.index       = 0;
         this.entryCount  = 0;
         this.oldElementValue = this.element.value;

         if(this.setOptions)
         this.setOptions(options);
         else
         this.options = options || { };

         this.options.paramName    = this.options.paramName || this.element.name;
         this.options.tokens       = this.options.tokens || [];
         this.options.frequency    = this.options.frequency || 0.4;
         this.options.minChars     = this.options.minChars || 1;
         this.options.onShow       = this.options.onShow ||
         function(element, update){
            if(!update.style.position || update.style.position=='absolute') {
            update.style.position = 'absolute';
            Position.clone(element, update, {
               setHeight: false,
               offsetTop: element.offsetHeight
            });
            }
            Effect.Appear(update,{duration:0.15});
         };
         this.options.onHide = this.options.onHide ||
         function(element, update){ new Effect.Fade(update,{duration:0.15}) };

         if(typeof(this.options.tokens) == 'string')
         this.options.tokens = new Array(this.options.tokens);
         // Force carriage returns as token delimiters anyway
         if (!this.options.tokens.include('\n'))
         this.options.tokens.push('\n');

         this.observer = null;

         this.element.setAttribute('autocomplete','off');

         Element.hide(this.update);

         Event.observe(this.element, 'blur', this.onBlur.bindAsEventListener(this));
         Event.observe(this.element, 'keydown', this.onKeyPress.bindAsEventListener(this));
         Event.observe(this.element, 'focus', this.onKeyPress.bindAsEventListener(this));
      },

      show: function() {
         try{if(Element.getStyle(this.update, 'display')=='none') this.options.onShow(this.element, this.update);} catch(e) {this.options.onShow(this.element, this.update);}
         if(!this.iefix &&
         (Prototype.Browser.IE) &&
         (Element.getStyle(this.update, 'position')=='absolute')) {
            new Insertion.After(this.update,
            '<iframe id="' + this.update.id + '_iefix" '+
            'style="display:none;position:absolute;filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);" ' +
            'src="javascript:false;" frameborder="0" scrolling="no"></iframe>');
            this.iefix = $(this.update.id+'_iefix');
         }
         if(this.iefix) setTimeout(this.fixIEOverlapping.bind(this), 50);
      },

      fixIEOverlapping: function() {
      Position.clone(this.update, this.iefix, {setTop:(!this.update.style.height)});
      this.iefix.style.zIndex = 1;
      this.update.style.zIndex = 2;
      Element.show(this.iefix);
      },

      hide: function() {
      this.stopIndicator();
      if(Element.getStyle(this.update, 'display')!='none') this.options.onHide(this.element, this.update);
      if(this.iefix) Element.hide(this.iefix);
      },

      startIndicator: function() {
      if(this.options.indicator) Element.show(this.options.indicator);
      },

      stopIndicator: function() {
      if(this.options.indicator) Element.hide(this.options.indicator);
      },

      onKeyPress: function(event) {
      if(this.active)
      switch(event.keyCode) {
      case Event.KEY_TAB:
      case Event.KEY_RETURN:
      this.selectEntry();
      Event.stop(event);
      case Event.KEY_ESC:
      this.hide();
      this.active = false;
      Event.stop(event);
      return;
      case Event.KEY_LEFT:
      case Event.KEY_RIGHT:
      return;
      case Event.KEY_UP:
      this.markPrevious();
      this.render();
      Event.stop(event);
      return;
      case Event.KEY_DOWN:
      this.markNext();
      this.render();
      Event.stop(event);
      return;
      }
      else
      if(event.keyCode==Event.KEY_TAB || event.keyCode==Event.KEY_RETURN ||
      (Prototype.Browser.WebKit > 0 && event.keyCode == 0)) return;

      this.changed = true;
      this.hasFocus = true;

      if(this.observer) clearTimeout(this.observer);
      this.observer =
      setTimeout(this.onObserverEvent.bind(this), this.options.frequency*1000);
      },

      activate: function() {
      this.changed = false;
      this.hasFocus = true;
      this.getUpdatedChoices();
      },

      onHover: function(event) {
      var element = Event.findElement(event, 'LI');
      if(this.index != element.autocompleteIndex)
      {
      this.index = element.autocompleteIndex;
      this.render();
      }
      Event.stop(event);
      },

      onClick: function(event) {
      var element = Event.findElement(event, 'LI');
      this.index = element.autocompleteIndex;
      this.selectEntry();
      this.hide();
      },

      onBlur: function(event) {
      // needed to make click events working
      setTimeout(this.hide.bind(this), 250);
      this.hasFocus = false;
      this.active = false;
      },

      render: function() {
      if(this.entryCount > 0) {
      for (var i = 0; i < this.entryCount; i++)
      this.index==i ?
      Element.addClassName(this.getEntry(i),"selected") :
      Element.removeClassName(this.getEntry(i),"selected");
      if(this.hasFocus) {
      this.show();
      this.active = true;
      }
      } else {
      this.active = false;
      this.hide();
      }
      },

      markPrevious: function() {
      if(this.index > 0) this.index--;
      else this.index = this.entryCount-1;
      this.getEntry(this.index).scrollIntoView(true);
      },

      markNext: function() {
      if(this.index < this.entryCount-1) this.index++;
      else this.index = 0;
      this.getEntry(this.index).scrollIntoView(false);
      },

      getEntry: function(index) {
      return this.update.firstChild.childNodes[index];
      },

      getCurrentEntry: function() {
      return this.getEntry(this.index);
      },

      selectEntry: function() {
      this.active = false;
      this.updateElement(this.getCurrentEntry());
      },

      updateElement: function(selectedElement) {
      if (this.options.updateElement) {
      this.options.updateElement(selectedElement);
      return;
      }
      var value = '';
      if (this.options.select) {
      var nodes = $(selectedElement).select('.' + this.options.select) || [];
      if(nodes.length>0) value = Element.collectTextNodes(nodes[0], this.options.select);
      } else
      value = Element.collectTextNodesIgnoreClass(selectedElement, 'informal');

      var bounds = this.getTokenBounds();
      if (bounds[0] != -1) {
      var newValue = this.element.value.substr(0, bounds[0]);
      var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/);
      if (whitespace)
      newValue += whitespace[0];
      this.element.value = newValue + value + this.element.value.substr(bounds[1]);
      } else {
      this.element.value = value;
      }
      this.oldElementValue = this.element.value;
      this.element.focus();

      if (this.options.afterUpdateElement)
      this.options.afterUpdateElement(this.element, selectedElement);
      },

      updateChoices: function(choices) {
      if(!this.changed && this.hasFocus) {
      this.update.innerHTML = choices;
      Element.cleanWhitespace(this.update);
      Element.cleanWhitespace(this.update.down());

      if(this.update.firstChild && this.update.down().childNodes) {
      this.entryCount =
      this.update.down().childNodes.length;
      for (var i = 0; i < this.entryCount; i++) {
      var entry = this.getEntry(i);
      entry.autocompleteIndex = i;
      this.addObservers(entry);
      }
      } else {
      this.entryCount = 0;
      }

      this.stopIndicator();
      this.index = 0;

      if(this.entryCount==1 && this.options.autoSelect) {
      this.selectEntry();
      this.hide();
      } else {
      this.render();
      }
      }
      },

      addObservers: function(element) {
      Event.observe(element, "mouseover", this.onHover.bindAsEventListener(this));
      Event.observe(element, "click", this.onClick.bindAsEventListener(this));
      },

      onObserverEvent: function() {
      this.changed = false;
      this.tokenBounds = null;
      if(this.getToken().length>=this.options.minChars) {
      this.getUpdatedChoices();
      } else {
      this.active = false;
      this.hide();
      }
      this.oldElementValue = this.element.value;
      },

      getToken: function() {
      var bounds = this.getTokenBounds();
      return this.element.value.substring(bounds[0], bounds[1]).strip();
      },

      getTokenBounds: function() {
      if (null != this.tokenBounds) return this.tokenBounds;
      var value = this.element.value;
      if (value.strip().empty()) return [-1, 0];
      var diff = arguments.callee.getFirstDifferencePos(value, this.oldElementValue);
      var offset = (diff == this.oldElementValue.length ? 1 : 0);
      var prevTokenPos = -1, nextTokenPos = value.length;
      var tp;
      for (var index = 0, l = this.options.tokens.length; index < l; ++index) {
      tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1);
      if (tp > prevTokenPos) prevTokenPos = tp;
      tp = value.indexOf(this.options.tokens[index], diff + offset);
      if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp;
      }
      return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]);
      }
   });

   Autocompleter.Base.prototype.getTokenBounds.getFirstDifferencePos = function(newS, oldS) {
      var boundary = Math.min(newS.length, oldS.length);
      for (var index = 0; index < boundary; ++index)
      if (newS[index] != oldS[index])
      return index;
      return boundary;
   };

   Ajax.Autocompleter = Class.create(Autocompleter.Base, {
      initialize: function(element, update, url, options) {
         this.baseInitialize(element, update, options);
         this.options.asynchronous  = true;
         this.options.onComplete    = this.onComplete.bind(this);
         this.options.defaultParams = this.options.parameters || null;
         this.url                   = url;
      },

      getUpdatedChoices: function() {
         this.startIndicator();

         var entry = encodeURIComponent(this.options.paramName) + '=' +
         encodeURIComponent(this.getToken());

         this.options.parameters = this.options.callback ?
         this.options.callback(this.element, entry) : entry;

         if(this.options.defaultParams)
         this.options.parameters += '&' + this.options.defaultParams;

         new Ajax.Request(this.url, this.options);
      },

      onComplete: function(request) {
         this.updateChoices(request.responseText);
      }
   });

   Ajax.Autocompleter.prototype.markPrevious = function() {
      if(this.index > 0) this.index--;
      else this.index = this.entryCount-1;
      if((document.viewport.getHeight() + document.viewport.getScrollOffsets().top) < this.getEntry(this.index).cumulativeOffset().top) this.getEntry(this.index).scrollIntoView(false);
   }

   Ajax.Autocompleter.prototype.markNext = function() {
      if(this.index < this.entryCount-1) this.index++;
      else this.index = 0;
      if((document.viewport.getHeight() + document.viewport.getScrollOffsets().top) < this.getEntry(this.index).cumulativeOffset().top) this.getEntry(this.index).scrollIntoView(false);
   }

   var autocomplete_type = {
       firstname: 1,
       lastname: 2,
       us_location: 3,
       yp_keyword: 4,
       split_us_location: 5
   }

   var autocomplete_css = "div.autocomplete {display: inline; position:absolute;width:250px;background-color:white;border:1px solid #888;margin:0;padding:0;z-index:200;}div.autocomplete ul {list-style-type:none;margin:0;padding:0;}div.autocomplete ul li.selected { background-color: #ffb;}div.autocomplete ul li {list-style-type:none;display:block;margin:0;padding:2px;cursor:pointer;}";

   document.write('<style type="text/css">'+autocomplete_css+'</style>')

   function splitLocationElementsUpdate() {
       var input_element = this
       var select_element = arguments[0]
       var string_elements = arguments[1].innerHTML.split(',')
       input_element.setValue(string_elements[0].strip())
       select_element.childElements().each(function(ele){if(ele.value.toLowerCase() == string_elements[1].strip().toLowerCase()){ele.selected = true}else{ele.selected = false}})
   }

   function Autocomplete (dom_element, data_type, secondary_dom_element) {
       var target_script = '/inc/ajax/autocomplete.php'
       var input_length_threshold = 3
       var max_results = 10
       var autocomplete_choices_container_id = dom_element.id+"_autocomplete_choices"
       var log_level = 0
       var parameters = 'type='+escape(data_type)+'&max='+escape(max_results)
       var paramName = "term";
       var freq = 0.2

       dom_element.insert({"after" : "<div id=\""+autocomplete_choices_container_id+"\" class=\"autocomplete\"></div>"})
       var options = {paramName: paramName, minChars: input_length_threshold, parameters: parameters, frequency: freq}
       if(data_type == autocomplete_type.split_us_location) {
           if(secondary_dom_element) {
               options.updateElement = splitLocationElementsUpdate.bind(dom_element, secondary_dom_element)
           }
           else {
               if(log_level >= 1) {
                   console.error("need to specify secondary_dom_element for split_us_location searches")
               }
           }
       }
       new Ajax.Autocompleter(dom_element.id, autocomplete_choices_container_id, target_script, options)
   };
}

/**
 * selectEnterSubmit()
 *
 * Sets an event listener on each <select> tag to submit the form if the enter key is pressed
 * while focus is on the select. Works cross-browser.
 */
function selectEnterSubmit() {
   for ( var j = 0; j < document.forms.length; j++ ) {
      var selectInputs = document.forms[j].getElementsByTagName('select');
      for ( var i = 0; i < selectInputs.length; i++ ) {
         if ( selectInputs[i].addEventListener ) {
            selectInputs[i].addEventListener("keypress",function(evt){
               if ( evt.keyCode == 13 ) {
                  evt.target.form.submit();
               }
            }, false);
         } else if ( selectInputs[i].attachEvent ) {
            selectInputs[i].attachEvent("onkeypress",function(evt){
               if ( evt.keyCode == 13 ) {
                  evt.srcElement.form.submit();
               }
            });
         }
      }
   }
}

/* code to fire selectEnterSubmit() on dom loaded event (or browser equivalent) */
if (document.addEventListener) {
   if (/WebKit/i.test(navigator.userAgent)) {
      var stimer = window.setInterval(function() {
         if (/loaded|complete/.test(document.readyState))
            if (stimer) window.clearInterval(stimer);
            selectEnterSubmit();
      }, 0);
   } else {
      document.addEventListener("DOMContentLoaded",
         selectEnterSubmit, false);
   }
} else {
   document.write("<script id=__onDOMContentLoaded_s defer src=//:><\/script>");
   document.getElementById("__onDOMContentLoaded_s").onreadystatechange = function() {
      if (this.readyState == "complete") {
         this.onreadystatechange = null;
         selectEnterSubmit();
      }
   };
}
