if (!sb_portableSearch) { var sb_portableSearch = new Object(); };

sb_portableSearch.options = {
  host: '', // address of the web server that will handle the search requests - no default, without a supplied argument the form will not function - no http:// and no trialing slashes
  page: 'MySearch.aspx', // filename of the search application that will be run by this form
  showLabel: 'true', // show the text label? anything other than 'false' will cause the label to show
  showLabel2: 'true', // show the text label? anything other than 'false' will cause the label to show
  showTypeList: 'true', // show the type dropdown list? anything other than 'false' will cause the list to show
  labelText: 'Search Ads', // default text for the label
  labelText2: 'Keyword Search', // default text for the label
  searchText: '', // default text for the search box
  categoriesText: 'Entire Marketplace', // default text for the catagories list
  buttonText: 'Go!', // text for the search button
  targetDiv: 'portablesearch', // id of the div to insert the form into
  buttonImage: '', // source of the button image - if a source is not supplied the button will be drawn as a regular submit button
  insertPoint: 'top', // the position to inject the search form within the targetDiv -- can either be 'top' or 'bottom'
  sortOrder: 'all,rop,ss,class,as,fsi', // sort string, dropdown list entries will be sorted in this order (must be lowercase)
  showCats: 'true', // show product categories, true or false
  alertOnError: 'false', // show message box when there is an error
  redirectOnEmpty: 'true'
};

sb_portableSearch.system = {
  // the INIT method is used to run everything else
  init: function() {
    if(!document.getElementById) return;
    // parse the arguments passed to this script via the javascript call
    sb_portableSearch.system.parseJavascriptCall();
    // if there is no targetDiv then there is no point in trying to run this script
    if(!document.getElementById(sb_portableSearch.options.targetDiv)) return;
    // when the user leaves this page remove all events attached to any of the targetDivs child nodes
    sb_portableSearch.tools.addEvent(window, 'unload', sb_portableSearch.tools.purgeEvents);
    // load the script containing the JSON object
    sb_portableSearch.system.loadScript('http://' + sb_portableSearch.options.host + '/ROP/JsonCategories.aspx?callback=sb_portableSearch.system.loadJSON');
  },

  // the PARSEJAVASCRIPTCALL method is used to read the name/value pairs in the arguments used against this script
  // it then sets that information in the global variables for the rest of the script to interpret
  parseJavascriptCall: function() {
    var args = new Object;
    var scriptTags = document.getElementsByTagName('script');
    var i, x;
    var found = false;
    // loop through all of the script elements on this page
    for(i=(scriptTags.length-1);i>=0;i--) {
      // if this tag is the one that called this script
      if(/portablesearch.js/i.test(scriptTags[i].src)) {
        found = true;
        var firstSplit = new Array();
        var secondSplit = new Array();
        // split the source information by question-mark, then by ampersands
        firstSplit = scriptTags[i].src.split('?');
        secondSplit = firstSplit[1].split('&');
        var pair = new Array();
        // loop through all of th name/value pairs returned from the ampersand split
        for(x=0;x<secondSplit.length;x++) {
          // plug this data into the argNames and argValues arrays
          pair = secondSplit[x].split('=');
          args[pair[0]] = unescape(pair[1]);
        };
        break;
      };
    };
    // to help debuggers recognize a problem caused by changing the file name
    if(!found) {
      if (sb_portableSearch.options.alertOnError === 'true') {
        alert('Portable Search: Could not locate script reference "portablesearch.js". Did the administrator change the name of this file?');
      };
      return;
    };
    // attempt to match script arguments to our global variables
    if(args.host) sb_portableSearch.options.host = args.host;
    if(args.page) sb_portableSearch.options.page = args.page;
    if(args.showlabel) sb_portableSearch.options.showLabel = args.showlabel;
    if(args.showlabel2) sb_portableSearch.options.showLabel2 = args.showlabel2;
    if(args.showtypelist) sb_portableSearch.options.showTypeList = args.showtypelist;
    if(args.labeltext) sb_portableSearch.options.labelText = args.labeltext;
    if(args.labeltext2) sb_portableSearch.options.labelText2 = args.labeltext2;
    if(args.searchtext) sb_portableSearch.options.searchText = args.searchtext;
    if(args.categoriestext) sb_portableSearch.options.categoriesText = args.categoriestext;
    if(args.buttontext) sb_portableSearch.options.buttonText = args.buttontext;
    if(args.buttonimage) sb_portableSearch.options.buttonImage = args.buttonimage;
    if(args.targetdiv) sb_portableSearch.options.targetDiv = args.targetdiv;
    if(args.insertpoint) sb_portableSearch.options.insertPoint = args.insertpoint;
    if(args.sortorder) sb_portableSearch.options.sortOrder = args.sortorder;
    if(args.showcats) sb_portableSearch.options.showCats = args.showcats;
    if(args.alertonerror) sb_portableSearch.options.alertOnError = args.alertonerror;
    if(args.redirectonempty) sb_portableSearch.options.redirectOnEmpty = args.redirectonempty;
  },

  // the LOADSCRIPT method is used to attach another javascript to the document via the DOM
  loadScript: function(scriptUri) {
    // append a new script element to the head
    var script = document.createElement('script');
    script.type = "text/javascript";
    script.src = scriptUri;
    document.getElementsByTagName('head')[0].appendChild(script);
  },

  // the LOADJSON method is used as a callback for a JSON script to tell this script to proceed
  loadJSON: function(jsonObject) {
		this.json = jsonObject;
    // build the search form and all of the elements
    sb_portableSearch.system.buildSearchForm();
  },

  // the BUILDSEARCHFORM method, as its name implys is used to create the form elements and draw them to the screen
  buildSearchForm: function() {
    var i;
    var targetDiv = document.getElementById(sb_portableSearch.options.targetDiv);
    var divElement = document.createElement('div');
    divElement.id = 'pSearch';
    // create the form elements
    var formElement = document.createElement('form');
    var advidElement = document.createElement('input');
    var locElement = document.createElement('input');
    // set the attributes for the form elements
    formElement.action = 'http://' + sb_portableSearch.options.host + '/Shared/' + sb_portableSearch.options.page;
    formElement.method = 'get';
    formElement.onsubmit = function() { return sb_portableSearch.handlers.submitForm(); }
    formElement.id = 'pSearchForm';
    // add the hidden elements and set their values
    advidElement.type = 'hidden';
    advidElement.value = '0';
    advidElement.name = 'advid';
    locElement.type = 'hidden';
    locElement.value = '0';
    locElement.name = 'loc';
    // append the hidden elements to the form
    formElement.appendChild(advidElement);
    formElement.appendChild(locElement);
    // add the label text, unless we are told otherwise
    if(sb_portableSearch.options.showLabel !== 'false' && sb_portableSearch.options.labelText) {
      var label = document.createElement('label');
      label.id = 'pSearchCatLabel';
      label.setAttribute('for','pSearchCat');
      label.appendChild(document.createTextNode(sb_portableSearch.options.labelText));
      formElement.appendChild(label);
    };
    var products = new Object;
    products.rop = false;
    products.ss = false;
    products.cl = false;
    products.as = false;
    products.fsi = false;
    // setup the category list, unless we are told otherwise
    if(sb_portableSearch.options.showTypeList !== 'false') {
      // create and setup the category list drop down list
      var catlist = document.createElement('select');
      catlist.id = 'pSearchCat';
      catlist.name = 'type';
      catlist.size = '1';
      var c = this.json.products;
      // loop through all of the top-level products in the JSON data
      for(i=c.product.length-1;i>=0;i--) {
        // and detect which ones are present
        switch(c.product[i].name) {
          case 'ROP' :
            products.rop = c.product[i].disp;
            break;
          case 'SS' :
            products.ss = c.product[i].disp;
            break;
          case 'CLASS' :
            products.cl = c.product[i].disp;
            break;
          case 'AS' :
            products.as = c.product[i].disp;
            break;
          case 'FSI' :
            products.fsi = c.product[i].disp;
            break;
        };
      };
      var sortArray = sb_portableSearch.options.sortOrder.split(',');
      // show the main products, sorted by the sort string
      for(var i=0;i<sortArray.length;i++) {
        switch(sortArray[i]) {
          case 'all' :
            // create the all category list entry
            var firstOpt = document.createElement('option');
            firstOpt.className = 'title-dd';
            firstOpt.appendChild(document.createTextNode(sb_portableSearch.options.categoriesText));
            firstOpt.value = '';
            catlist.appendChild(firstOpt);
            break;
          case 'rop' :
            // if we have detected rop, add the category item
            if(products.rop) {
              var ropT = document.createElement('option');
              ropT.value = 'rop';
              ropT.className = 'prodall-dd';
              ropT.appendChild(document.createTextNode(products.rop));
              catlist.appendChild(ropT);
            };
            break;
          case 'ss' :
            // if we have detected ss, add the category item
            if(products.ss) {
              var ssT = document.createElement('option');
              ssT.value = 'ss';
              ssT.className = 'prodall-dd';
              ssT.appendChild(document.createTextNode(products.ss));
              catlist.appendChild(ssT);
            };
            break;
          case 'class' :
            // if we have detected class, add the category item
            if(products.cl) {
              var classT = document.createElement('option');
              classT.value = 'class';
              classT.className = 'prodall-dd';
              classT.appendChild(document.createTextNode(products.cl));
              catlist.appendChild(classT);
            };
            break;
          case 'as' :
            // if we have detected class, add the category item
            if(products.as) {
              var asT = document.createElement('option');
              asT.value = 'as';
              asT.className = 'prodall-dd';
              asT.appendChild(document.createTextNode(products.as));
              catlist.appendChild(asT);
            };
            break;
          case 'fsi' :
            // if we have detected class, add the category item
            if(products.fsi) {
              var fsiT = document.createElement('option');
              fsiT.value = 'fsi';
              fsiT.className = 'prodall-dd';
              fsiT.appendChild(document.createTextNode(products.fsi));
              catlist.appendChild(fsiT);
            };
            break;
        };
      };
      if(sb_portableSearch.options.showCats === 'true') {
        // show the product subcategories, sorted by the sort string
        for(var i=0;i<sortArray.length;i++) {
          switch(sortArray[i]) {
            case 'rop' :
              // if we have detected rop, add the subcategories items
              if(products.rop) {
                var a = document.createElement('option');
                a.className = 'blank-dd';
                catlist.appendChild(a);
                var rop = document.createElement('option');
                rop.value = 'rop';
                rop.className = 'prodtitle-dd';
                rop.appendChild(document.createTextNode('-- '+c.ropcats.name+' --'));
                catlist.appendChild(rop);
                var listItem;
                // cycle through the subcatagories for rop
                for(x=0;x<c.ropcats.cat.length;x++) {
                  // create, set and append an option element for this entry
                  listItem = document.createElement('option');
                  listItem.value = 'rop-' + c.ropcats.cat[x].rid;
                  listItem.className = 'subcat-dd';
                  listItem.appendChild(document.createTextNode(c.ropcats.cat[x].name));
                  catlist.appendChild(listItem);
                };
              };
              break;
            case 'class' :
              // if we have detected class, add the subcategories items
              if(products.cl) {
                var b = document.createElement('option');
                b.className = 'blank-dd';
                catlist.appendChild(b);
                var cl = document.createElement('option');
                cl.value = 'classifieds';
                cl.className = 'prodtitle-dd';
                cl.appendChild(document.createTextNode('-- '+c.classcats.name+' --'));
                catlist.appendChild(cl);
                var listItem2;
                // cycle through the subcatagories for classifieds
                for(x=0;x<c.classcats.cat.length;x++) {
                  // create, set and append an option element for this entry
                  listItem2 = document.createElement('option');
                  listItem2.value = 'class-' + c.classcats.cat[x].scid;
                  listItem2.className = 'classcat-dd';
                  listItem2.appendChild(document.createTextNode(c.classcats.cat[x].name));
                  catlist.appendChild(listItem2);
                };
              };
              break;
          };                           
        };
      };
    };
    // create and set the attributes of our search box
if(sb_portableSearch.options.showLabel2 !== 'false' && sb_portableSearch.options.labelText2) {
      var label2 = document.createElement('label');
      label2.id = 'pSearchBoxLabel';
      label2.setAttribute('for','pSearchBox');
      label2.appendChild(document.createTextNode(sb_portableSearch.options.labelText2));
    };
    
    var searchBox = document.createElement('input');
    searchBox.type = 'text';
    searchBox.id = 'pSearchBox';
    searchBox.name = 's';
    searchBox.value = sb_portableSearch.options.searchText;
    searchBox.onfocus = sb_portableSearch.handlers.clearText;
    searchBox.onblur = sb_portableSearch.handlers.resetText;
    // create and set the atributes of our search button
    var searchButton = document.createElement('input');
    if(sb_portableSearch.options.buttonImage) {
      searchButton.type = 'image';
      searchButton.src = sb_portableSearch.options.buttonImage;
      searchButton.alt = sb_portableSearch.options.buttonText;
    } else {
      searchButton.type = 'submit';
      searchButton.value = sb_portableSearch.options.buttonText;
    };
    searchButton.id = 'pSearchButton';
    // append the search elements to the form
    if(sb_portableSearch.options.showTypeList !== 'false') {
      formElement.appendChild(catlist);
    };
    formElement.appendChild(label2);
    formElement.appendChild(searchBox);
    formElement.appendChild(searchButton);
    divElement.appendChild(formElement);
    // insert the form into the target div
    if(sb_portableSearch.options.insertPoint === 'top' && targetDiv.hasChildNodes()) {
      targetDiv.insertBefore(divElement, targetDiv.firstChild);
    } else {
      targetDiv.appendChild(divElement);
    };
  }
};

sb_portableSearch.handlers = {
  // the SUBMITFORM method is the event handler for the search form
  submitForm: function() {
    var query = document.getElementById('pSearchBox');
    if(query.value === '' || query.value === sb_portableSearch.options.searchText) {
      if (sb_portableSearch.options.redirectOnEmpty === 'false') {
        if(sb_portableSearch.options.alertOnError === 'true') {
          alert('Please enter search keywords');
          query.focus();
        };
      } else {
        var cat = document.getElementById('pSearchCat');
        if(cat.value !== '') {
          var split = cat.value.split('-');
          if(!split[1]) {
            window.location = 'http://' + sb_portableSearch.options.host + '/' + cat.value;
          } else {
            switch(split[0]) {
              case 'rop' :
                window.location = 'http://' + sb_portableSearch.options.host + '/rop/Subcat.aspx?cat=' + split[1].split(',')[0];
                break;
            };
          };
        };
      };
      return false;
    };
  },

  // the CLEARTEXT method is the event handler for the search box onfocus event
  clearText: function() {
    if(this.value === sb_portableSearch.options.searchText) this.value = '';
  },

  // the RESETTEXT method is the event handler for the searchbox onblur event
  resetText: function() {
    if(this.value === '') this.value = sb_portableSearch.options.searchText;
  }
};

sb_portableSearch.tools = {
  // the ADDEVENT method is used to add a new event handler
  addEvent: function(obj, evType, fn, useCapture) {
    if(obj.addEventListener) {
      obj.addEventListener(evType, fn, useCapture);
      return true;
    } else if(obj.attachEvent) {
      var r = obj.attachEvent('on' + evType, fn);
      return r;
    } else {
      obj['on' + evType] = fn;
    };
  },

  // the PURGEEVENTS method is a work-around fix for potential memory leaks in internet exporer
  // this function will loop through all attributes of the element and its child nodes, removing any functions it finds
  purgeEvents: function(elem) {
    var i;
    if(!elem) elem = document.getElementById(sb_portableSearch.options.targetDiv);
    // cycle through the attributes for this element
    var attr = elem.attributes;
    if(attr) {
      var n;
      for(i=attr.length-1;i>=0;i--) {
        n = attr[i].name;
        // if this attribute is a function then remove it
        if(typeof elem[n] === 'function')  elem[n] = null;
      };
    };
    // and purgeEvents on all child nodes
    var children = elem.childNodes;
    if(children) {
      for(i=(children.length-1);i>=0;i--) {
        sb_portableSearch.tools.purgeEvents(elem.childNodes[i]);
      };
    };
  }
};

sb_portableSearch.tools.addEvent(window, 'load', sb_portableSearch.system.init);