if (!this.FAST) {
  this.FAST = {};
  /******************************************************************************
  *******                           CONFIG                                *******
  ******************************************************************************/
  //FAST.var = value;
  FAST.keyPress = false;
  
  // START CODE    
  FAST.createObject = function (type, parent, id, styleName, content) {
    var obj = document.createElement(type);
    
    if (id && !document.getElementById(id)) {
      obj.id = id;
    } else {      
      return null;
    }
    
    if (styleName) obj.className = styleName;
    if (content) obj.innerHTML = content;
    
    parent.appendChild(obj);
    return obj;
  }
  
  FAST.styleObject = function (obj, style) {
    var obj = FAST.getObject(obj);
    var style = style || {}; 
    if (obj)
      for(var i in style)
        obj.style[i] = style[i];
        
    return obj;
  }
  
  FAST.getObject = function (obj) {
    return obj.id ? obj : document.getElementById(obj);
  }
  
  FAST.removeObject = function (obj) {
    var obj = FAST.getObject(obj);
    
    if (obj) {
      var parent = obj.parentNode;
      parent.removeChild(obj); 
      
      return parent;
    }
  }
  
  FAST.toggleObject = function (obj, style, on, off) {
    var obj = FAST.getObject(obj);
    return obj.style[style] = obj.style[style] != off ? off : on;
  }
  
  FAST.popupObject = function(id, style, content, height, width, title) {
    if (!(obj = FAST.getObject(id))) {
      var popup = FAST.createObject("div", document.body, "darkenScreenObject", "", "");  
      var inject = '<div class="popup-header">';
      if (title != null) {
        inject += '<span class="popup-title">' + title + '</span>';
      } 
      inject += '<img src="' + SITE_ROOT + 'common/images/icons/delete.png" alt="Close" onclick="framework_popout(this)" style="cursor: pointer;" /></div><div class="popup-content">';
      
      var content = FAST.createObject("div", document.body, id, style, inject + content + "</div>");

      var scrollPosition = Window.getScrollPosition();
      var windowSize = Window.getWindowSize();
      var height = height || content.offsetHeight;
      var width = width || content.offsetWidth;
      var top = scrollPosition[1] + ((windowSize[1] - height) / 2);
      var left = (windowSize[0] - width) / 2;
  
      // Check to make sure values are greater than zero...
      top = top > 0 ? top : 0;
      left = left > 0 ? left : 0;
      
      FAST.styleObject(content, {
        "position": "absolute",
        "left": left + "px",
        "top": top + "px",
        "width": width + "px"
      });
      
      var pageSize = Window.getPageSize();
      pageSize[0] = pageSize[0] > windowSize[0] ? pageSize[0] + "px" : "100%";
      pageSize[1] = pageSize[1] > windowSize[1] ? pageSize[1] + "px" : "100%";      
      
      FAST.styleObject(popup, {
        "position": "fixed",
        "zIndex": "91",
        "opacity": ".70",
        "MozOpacity": ".70",
        "filter": "alpha(opacity=70)",
        "backgroundColor": "#000",
        "height": pageSize[1],
        "width": pageSize[0],
        "overflow": "hidden",
        "top": "0px",
        "left": "0px",
        "display": "block"
      });
    } else {      
      do {
        var parent = FAST.removeObject(obj);
      } while ((obj = parent) && (parent != document.body));
      
      FAST.removeObject("darkenScreenObject");
    }
      
    return false;
  }
  
  FAST.popupWindow = function (url, name, options) {
    var url = url.href || url.action || url.src || url;
    var name = name || "popup";
    var params = "";
      
    if (options)
      for(var i in options)
        params =  params + i + "=" + options[i] + ",";
  
    var newWindow = window.open(url,name,params);

    if (window.focus)
      newWindow.focus();
    
    if (!newWindow.closed)
      return false;
  }
  
  // TODO Form Controls -- enable/disable fields, check/uncheck all  
  FAST.selectAll = function (obj) {
    var obj = FAST.getObject(obj);
    var form = obj.form;
    
    var test = new Array();
    var collection = form.getElementsByTagName(obj.nodeName);
    for ( i=0; i<collection.length; i++ )
      if (collection[i].type == obj.type && collection[i].name == obj.name)
        collection[i].checked = obj.checked;
  }
  
  FAST.disableObject = function (obj) {
    var obj = FAST.getObject(obj);

    obj.disabled = true;
    
    return obj.disabled;
  }
}

//-----( @Events )---------------------------------------------
var Events = {
	addEvent: function(obj, type, fn, useCapture) {
          if (typeof fn == "function") { // TODO some obscure bug in Menu passes in an object instead
		if ( obj.attachEvent ) {
			obj['e'+type+fn] = fn;
			obj[type+fn] = function() {obj['e'+type+fn]( window.event ); }
			obj.attachEvent( 'on'+type, obj[type+fn] );
		} else {
			obj.addEventListener( type, fn, useCapture );
		}
          }
	},
	removeEvent: function(obj, type, fn, useCapture) {
		if ( obj.detachEvent ) {
			obj.detachEvent( 'on'+type, obj[type+fn] );
			obj[type+fn] = null;
		} else {
			obj.removeEventListener( type, fn, useCapture );
		}
	},
	stopDefaultAction: function(ev) {
		// stop default action of an event
		if (!ev) { ev = window.event; }
		(ev.stopPropagation) ? ev.stopPropagation() : ev.cancelBubble = true;
		(ev.preventDefault) ? ev.preventDefault() : ev.returnValue = false;
		return false;
	},
        stopBubble: function(e) {
          e = e || window.event;
          e.cancelBubble = true;
          if (e.stopPropagation) e.stopPropagation();
        }
}
//-----( END )-------------------------------------------------

//-----( @Cookies )--------------------------------------------
var Cookies = {
  getCookie: function(name) {
    var start = document.cookie.indexOf(name + "=");
    var len = start + name.length + 1;
    if ((!start) && (name != document.cookie.substring(0, name.length))) {
            return null;
    }
    if (start == -1) { return null; }
    var end = document.cookie.indexOf(";", len);
    if (end == -1) { end = document.cookie.length; }
    return unescape(document.cookie.substring(len, end));
  },
  setCookie: function(name, value, expires, path, domain, secure) {
    var today = new Date();
    today.setTime(today.getTime());
    
    if (expires) { expires = expires * 1000 * 60 * 60 * 24; }
    var expires_date = new Date(today.getTime() + (expires));
    
    document.cookie = name + "=" + escape(value)
    + ((expires) ? ";expires="+expires_date.toGMTString() : "")
    + ((path) ? ";path=" + path : "")
    + ((domain) ? ";domain=" + domain : "")
    + ((secure) ? ";secure" : "");
  },
  deleteCookie: function(name, path, domain) {
    if (Cookies.getCookie(name)) document.cookie = name + "="
    + ((path) ? ";path=" + path : "")
    + ((domain) ? ";domain=" + domain : "")
    + ";expires=Thu, 01-Jan-1970 00:00:01 GMT";
  }
}
//-----( END )-------------------------------------------------

//*-----( @Toggle )---------------------------------------------
var FSToggle = {
  toggle: function(obj, event) {
    if (obj) {
      var container = document.getElementById(obj.id + "-container");
      
      if (container) {
        var className = obj.className;
        
        if (className.indexOf('increment') != -1) {
          className = className.replace("increment", "decrement");
          container.style.display = "block";
        } else if (className.indexOf('decrement') != -1) {
          className = className.replace("decrement", "increment");
          container.style.display = "none";
        } else {
          alert("Error: Element does not have class name 'increment' or 'decrement'.");
        }
        
        obj.className = className; // for ie-6
        obj.setAttribute("class", className);
      } else {
        //console.log("Error: Element does not have a child container called '" + obj.id + "-container'.");
      }
    }
  },
  
  init: function() {
    var objs = getElementsByClassName("toggle-js");
    
    for (var i = 0; i < objs.length; i++) {
      Events.addEvent(objs[i],'click', function(event) {
        FSToggle.toggle(this, event);
      });
        
      if (objs[i].className.indexOf('increment') != -1) {
        var container = document.getElementById(objs[i].id + "-container");
        
        if (container) {
          container.style.display = "none";
        } else {
          console.error("Error: Element does not have a child container called '" + objs[i].id + "-container'.");
        }
      }
    }
  }
};

Events.addEvent(window, "load", FSToggle.init);
//-----( END )-------------------------------------------------*/

var Forms = {
  confirm: function(obj, url, msg) {
    if (obj)
      if (confirm(msg)) {
        obj.action = url;
        obj.submit();
      }
  },
  required: function (obj, msg) {
    obj = document.getElementById(obj) || obj;
    form = obj.form;
    
    if (obj && form) {
      Events.addEvent(form,"submit", function(e) {
        if ((obj.value.toLowerCase() == msg.toLowerCase()) || (obj.value == ""))
          Events.stopDefaultAction(e);
      });
    }
  },
  validate: function(obj, type) {
    obj = document.getElementById(obj) || obj;
    
    if (obj) {
      Events.addEvent(obj,"keyup", function(event) {
        var e = event || window.event;
        var target = e.target || e.srcElement;

        if (typeof (target.value) != "string") {
          target.className = "error";
          target.valid = false;
        } else {
          target.className = "success";
          target.valid = true;
        }
      });
    }
  },
  
  fixSubmit: function(aForm) {
    for (var i=0;i<aForm.length;i++) {
      if (aForm[i].type == 'submit') {
          if (aForm[i].disabled == true) {
              aForm[i].disabled = false;
          } else {
              aForm[i].disabled = true;
          }
      }
    }
  },

  submit: function (event, form) {
    var e = event || window.event;
    for (i=0; i<form.required.length; i++) {
      if ((form[i].value <= 0) || form[i].valid) {
        e.preventDefault();
        return false;
      }
    }
    
    return true;
  },
  
  handleOnClick: function(form,string) {   
    for (i = 0; i < form.elements.length; i++)
      if (form.elements[i].value == string) form.elements[i].value = "";
  },
  
  serialize: function (form) {
    var obj = new Object();
    
    for (i = 0; i<form.elements.length; i++)
      if (form.elements[i].name) obj[form.elements[i].name] = form.elements[i].value;
      
    return obj;
  }
}

var Window = {
  getWindowSize:  function(w) {
    w = w ? w : window;
    var width = w.innerWidth || (w.document.documentElement.clientWidth || w.document.body.clientWidth);
    var height = w.innerHeight || (w.document.documentElement.clientHeight || w.document.body.clientHeight);
    return [width, height];
  },
  
  getScrollPosition: function (w) {
    w = w ? w : window;
    var scrOfX = 0, scrOfY = 0;
    if( typeof( w.pageYOffset ) == 'number' ) {
      scrOfY = w.pageYOffset;
      scrOfX = w.pageXOffset;
    } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
      scrOfY = w.document.body.scrollTop;
      scrOfX = w.document.body.scrollLeft;
    } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
      scrOfY = w.document.documentElement.scrollTop;
      scrOfX = w.document.documentElement.scrollLeft;
    }
    return [ scrOfX, scrOfY ];
  },
  
  getElementPosition: function (obj, checkCSS) {
    obj = document.getElementById(obj) || obj;
    var curleft = curtop = 0;
    if (obj.offsetParent) {
      do {
        if (checkCSS && (Window.getStyle(obj,"position") == "relative")) break;
        curleft += obj.offsetLeft;
        curtop += obj.offsetTop;
      } while (obj = obj.offsetParent);
      return [curleft,curtop];
    }
  },
  
  getStyle: function (el,styleProp) {
    var x = document.getElementById(el) || el;
    if (x.currentStyle)
      var y = x.currentStyle[styleProp];
    else if (window.getComputedStyle)
      var y = document.defaultView.getComputedStyle(x,null).getPropertyValue(styleProp);
    return y;
  },
  
  getPageSize: function (w){
    w = w ? w : window;
    // TODO - fix width bug in Firefox
    if (window.innerHeight && window.scrollMaxY) {// Firefox
      yWithScroll = w.innerHeight + window.scrollMaxY;
      xWithScroll = w.innerWidth + window.scrollMaxX;
    } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac
      yWithScroll = w.document.body.scrollHeight;
      xWithScroll = w.document.body.scrollWidth;
    } else { // works in Explorer 6 Strict, Mozilla (not FF) and Safari
      yWithScroll = w.document.body.offsetHeight;
      xWithScroll = w.document.body.offsetWidth;
    }
    return [ xWithScroll , yWithScroll ];
  }
}

var Menu = {
  timer: null,
  elCurrentTarget: null,
  elInitialTarget: null,
  toolbar: null,
  elCurrentTarget: null,
  setCurrentTarget: function (e) {
    e = e || window.event;
    var el = e.target || e.srcElement; 
    if (el) Menu.elCurrentTarget = el;
  },
  show: function (e) {  
    if (obj = this.getElementsByTagName('ul').item(0))
      obj.style.display = "block";
  },
  hide: function (e) {
    e = e || window.event;
    obj = e.relatedTarget || e.toElement;   
    
    if (!contains(this,obj) && (this != obj)) {
      clearTimeout(Menu.timer); Menu.elInitialTarget = null;
      
      if (element = this.getElementsByTagName('ul').item(0))
        element.style.display = "none";
    }
  },
  trigger: function(e) {
    e = e || window.event;

    Menu.elInitialTarget = this;
    Menu.elCurrentTarget = this;
    
    Menu.timer = setTimeout("Menu.show()",250);
  },
  show: function() {
    var cont = contains(Menu.elCurrentTarget, Menu.elInitialTarget) || contains(Menu.elInitialTarget, Menu.elCurrentTarget) || (Menu.elInitialTarget == Menu.elCurrentTarget);

    if (cont) {
      var el = Menu.elInitialTarget ;
      if (el) var list = el.getElementsByTagName('ul');
      if (list && list[0] && (list[0].style.display != "block")) {
        list[0].style.display = "block";
      }
    }
  },
  init: function(el) {
    try {
      Menu.toolbar = document.getElementById(el) || el;
      var obj = Menu.toolbar.getElementsByTagName("li");
      for (i = 0; i < obj.length; i++) {
        if (Menu.toolbar == obj[i].parentNode) {
          Events.addEvent(obj[i],"mouseover", Menu.trigger);
          Events.addEvent(obj[i],"mouseout", Menu.hide);
        }
      }
    } catch (e) {
    }
  }
}

var Mouse = {
  getPosition: function(e) {
	if (!e) var e = window.event;
	if (e.pageX || e.pageY) 	{
		return [e.pageX, e.pageY];
	}
	else if (e.clientX || e.clientY) 	{
		var x = e.clientX + document.body.scrollLeft
			+ document.documentElement.scrollLeft;
		var y = e.clientY + document.body.scrollTop
			+ document.documentElement.scrollTop;
                return [x,y];
	}
        return null;
  }
}

var Tooltip = {
  show: function(obj, target) {
    var obj = document.getElementById(obj) || obj;
  
    var posMouse = Mouse.getPosition(window.event);
    var posObj = Window.getElementPosition(obj, false);
    
    if (typeof (target = (document.getElementById(target) || target)) == "object") {
      target.style.display = "block";
      target.style.top = (posMouse[1] - posObj[1] + 5) + "px";
      target.style.left = (posMouse[0] - posObj[0] + 5) + "px";
    }
  },
  hide: function(target) {
    if (typeof (target = (document.getElementById(target) || target)) == "object") {
      target.style.display = "none";
    }
  },
  init: function (obj, popup) {
    Events.addEvent(obj,"mousemove",Tooltip.show);
  }
}

var Stylesheet = {
	setActive: function(title) {
		var linkTags = document.getElementsByTagName("link");
		for (var i=0; i<linkTags[i]; i++) {
			var linkTag = linkTags[i];
			if (linkTag.getAttribute("rel").indexOf("style") != -1 
			&& linkTag.getAttribute("title")) {
				linkTag.disabled = true;
				if (linkTag.getAttribute("title") == title) {
					linkTag.disabled = false;
				}
			}
		}
	},
	getActive: function() {
		var linkTags = document.getElementsByTagName("link");
		for (var i=0; i<linkTags; i++) {
			var linkTag = linkTags[i];
			if (linkTag.getAttribute("rel").indexOf("style") != -1 
			&& linkTag.getAttribute("title") 
			&& !linkTag.disabled) {
				return linkTag.getAttribute("title");
			}
		}
		return null;
	},
	getPreferred: function() {
		var linkTags = document.getElementsByTagName("link");
		for (var i=0; i<linkTags; i++) {
			var linkTag = linkTags[i];
			if (linkTag.getAttribute("rel").indexOf("style") != -1
			&& linkTag.getAttribute("rel").indexOf("alt") == -1
			&& linkTag.getAttribute("title")) {
				return linkTag.getAttribute("title");
			}
		}
		return null;
	},
	init: function() {
		var cookie = getCookie("style");
		var title = cookie ? cookie : getPreferredStyleSheet();
		Stylesheet.setActive(title);
	},
	uninit: function() {
		var title = Stylesheet.getActive();
		setCookie("style", title, 365, "", "", "");
	}
};

String.prototype.trim = function(){ return this.replace(/(^\s*)|(\s*$)/g, ""); }

/* Smooth scrolling
   Changes links that link to other parts of this page to scroll
   smoothly to those links rather than jump to them directly, which
   can be a little disorienting.
   
   sil, http://www.kryogenix.org/
   
   v1.0 2003-11-11
   v1.1 2005-06-16 wrap it up in an object
*/

var ss = {
  fixAllLinks: function() {
    // Get a list of all links in the page
    var allLinks = document.getElementsByTagName('a');
    // Walk through the list
    for (var i=0;i<allLinks.length;i++) {
      var lnk = allLinks[i];
      if ((lnk.href && lnk.href.indexOf('#') != -1) && 
          ( (lnk.pathname == location.pathname) ||
        ('/'+lnk.pathname == location.pathname) ) && 
          (lnk.search == location.search)) {
        // If the link is internal to the page (begins in #)
        // then attach the smoothScroll function as an onclick
        // event handler
        ss.addEvent(lnk,'click',ss.smoothScroll);
      }
    }
  },

  smoothScroll: function(e) {
    // This is an event handler; get the clicked on element,
    // in a cross-browser fashion
    if (window.event) {
      target = window.event.srcElement;
    } else if (e) {
      target = e.target;
    } else return;

    // Make sure that the target is an element, not a text node
    // within an element
    if (target.nodeName.toLowerCase() != 'a') {
      target = target.parentNode;
    }
  
    // Paranoia; check this is an A tag
    if (target.nodeName.toLowerCase() != 'a') return;
  
    // Find the <a name> tag corresponding to this href
    // First strip off the hash (first character)
    anchor = target.hash.substr(1);
    // Now loop all A tags until we find one with that name
    var allLinks = document.getElementsByTagName('a');
    var destinationLink = null;
    for (var i=0;i<allLinks.length;i++) {
      var lnk = allLinks[i];
      if (lnk.name && (lnk.name == anchor)) {
        destinationLink = lnk;
        break;
      }
    }
  
    // If we didn't find a destination, give up and let the browser do
    // its thing
    if (!destinationLink) return true;
  
    // Find the destination's position
    var destx = destinationLink.offsetLeft; 
    var desty = destinationLink.offsetTop;
    var thisNode = destinationLink;
    while (thisNode.offsetParent && 
          (thisNode.offsetParent != document.body)) {
      thisNode = thisNode.offsetParent;
      destx += thisNode.offsetLeft;
      desty += thisNode.offsetTop;
    }
  
    // Stop any current scrolling
    clearInterval(ss.INTERVAL);
  
    cypos = ss.getCurrentYPos();
  
    ss_stepsize = parseInt((desty-cypos)/ss.STEPS);
    ss.INTERVAL =
setInterval('ss.scrollWindow('+ss_stepsize+','+desty+',"'+anchor+'")',10);
  
    // And stop the actual click happening
    if (window.event) {
      window.event.cancelBubble = true;
      window.event.returnValue = false;
    }
    if (e && e.preventDefault && e.stopPropagation) {
      e.preventDefault();
      e.stopPropagation();
    }
  },

  scrollWindow: function(scramount,dest,anchor) {
    wascypos = ss.getCurrentYPos();
    isAbove = (wascypos < dest);
    window.scrollTo(0,wascypos + scramount);
    iscypos = ss.getCurrentYPos();
    isAboveNow = (iscypos < dest);
    if ((isAbove != isAboveNow) || (wascypos == iscypos)) {
      // if we've just scrolled past the destination, or
      // we haven't moved from the last scroll (i.e., we're at the
      // bottom of the page) then scroll exactly to the link
      window.scrollTo(0,dest);
      // cancel the repeating timer
      clearInterval(ss.INTERVAL);
      // and jump to the link directly so the URL's right
      location.hash = anchor;
    }
  },

  getCurrentYPos: function() {
    if (document.body && document.body.scrollTop)
      return document.body.scrollTop;
    if (document.documentElement && document.documentElement.scrollTop)
      return document.documentElement.scrollTop;
    if (window.pageYOffset)
      return window.pageYOffset;
    return 0;
  },

  addEvent: function(elm, evType, fn, useCapture) {
    // addEvent and removeEvent
    // cross-browser event handling for IE5+,  NS6 and Mozilla
    // By Scott Andrew
    if (elm.addEventListener){
      elm.addEventListener(evType, fn, useCapture);
      return true;
    } else if (elm.attachEvent){
      var r = elm.attachEvent("on"+evType, fn);
      return r;
    } else {
      alert("Handler could not be removed");
    }
  } 
}
ss.STEPS = 25;
ss.addEvent(window,"load",ss.fixAllLinks);

(function () {
  function Initialize (argObj, argPath, argAction) {
    var objSearchBox = document.getElementById(argObj) || argObj;    
    
    if ((typeof objSearchBox == "object")) {
      var frmAutocomplete = objSearchBox.form;
      
      frmAutocomplete.path = argPath;
      frmAutocomplete.tAction = argAction;
      
      Events.addEvent(objSearchBox, "keyup", CheckKeys);
    }
  }
  
  function CheckKeys (e) {
    try {
      e = e || window.event;
      
      var code = e.keyCode || e.which,
          obj = e.target || e.srcElement,
          frm = obj.form,
          loc = frm.path,
          sLastVal= obj.value;
          
      if (!e.ctrlKey && !e.altKey) {
        if ( code == 40) { // DOWN ARROW
          if (this.current++ >= this.tags.length - 1) {
            this.current = 0;
          }
          highlight(this.tags[this.current], this);      
        } else if (code == 38) { // UP ARROW      
          if (this.current-- <= 0) {
            this.current = this.tags.length - 1;
          }
          
          highlight(this.tags[this.current],this);
        } else if (code == 13) { // ENTER
          if (this.current >= 0) {
            if ((typeof this.tags[this.current] == "object") && (this.value == this.tags[this.current].title)) {
              fastenal.gotoUrl(this.tags[this.current].href);
            } // We need to compare the selected field before going through the loop in the event of links with the same title
          }
          
          var count = 0;
          for (i in this.tags) {
            if (this.tags[i].title && (this.value.toLowerCase() == this.tags[i].title.toLowerCase())) {
              loc = this.tags[i].href;
              count++;
            }
          }

          if (count == 1) {
            fastenal.gotoUrl(loc);
            Events.stopDefaultAction(e);
            return;
          }
        } else if (code == 33) { // PAGE UP
          if (this.current < 0) this.current = 0;
          var obj = this.tags[this.current] || this.tags[0];
          if (obj) {
            var newHeight = obj.offsetTop - this.popup.offsetHeight;
            for (i = this.tags.length - 1; i > 0; i--) {
              if (this.tags[i].offsetTop + this.tags[i].offsetHeight < newHeight) {
                this.current = i;
                highlight(this.tags[this.current],this); 
                return;
              }
            }
            
            this.current = 0;
            highlight(this.tags[this.current],this);
          }
        } else if (code == 34) { // PAGE DOWN
          if (this.current < 0) this.current = 0;
          var obj = this.tags[this.current];
          if (obj) {
            var newHeight = obj.offsetTop + this.popup.offsetHeight;
            for (i=0; i<this.tags.length; i++) {
              if (this.tags[i].offsetTop + this.tags[i].offsetHeight > newHeight) {
                this.current = i;
                highlight(this.tags[this.current],this); 
                return;
              }
            }
            
            this.current = this.tags.length - 1;
            highlight(this.tags[this.current],this);
          }
        } else if (code == 35 && !e.shiftKey) { // END
          this.current = this.tags.length - 1;
          highlight(this.tags[this.current],this);      
        } else if (code == 36 && !e.shiftKey) { // HOME
          this.current = 0;
          highlight(this.tags[this.current],this); 
        } else if (code == 27) { // ESC
          if (this.popup) this.popup.style.display = "none";
        } else {
          if (sLastVal.length > 2) {
            setTimeout(function(){
              var newobj = obj;
              loc = SetNewPath(loc, frm);
              
              var curVal = obj.value;
              if (curVal == sLastVal) doAjaxCall(loc,newobj);
            }, 500);  //wait for user to pause/stop typing before submitting
          }
        }
      }
    } catch(error) {
      //console.log(error);
    }
  }
  
  function highlight (obj,test) {
    for (i=0; i<test.tags.length; i++) {
      if (test.tags[i] == obj) {
        test.value = test.tags[i].title;
        test.tags[i].className = "active";
        
        if (test.tags[i].offsetTop + test.tags[i].offsetHeight > test.popup.scrollTop + test.popup.offsetHeight) {
          test.popup.scrollTop = test.tags[i].offsetTop - test.popup.offsetHeight + test.tags[i].offsetHeight;
        } else if (test.tags[i].offsetTop < test.popup.scrollTop) {
          test.popup.scrollTop = test.tags[i].offsetTop;      
        }
      } else {
        test.tags[i].className = ""; 
      }
    }
  }
  
  function doAjaxCall (loc,obj) {
    if (!obj.processing) {
      obj.processing = true;
      jQuery.ajax({
        url: loc,
        success: function(response, textStatus) {
          if (response.trim().length > 0) {
            obj.current = -1;
            Popup.AutoComplete('autocomplete' + obj.id,obj.id,response,true);
            obj.popup = document.getElementById("autocomplete" + obj.id);
            obj.popup.className="autocomplete";
            if (obj.popup) {
              obj.tags = obj.popup.getElementsByTagName("a");
              obj.popup.scrollTop = 0;
            }
          } else {
            if (obj.popup) {
              obj.popup.style.display = "none";
            }
          }
          obj.processing = false;
          return response;
        },
        error: function(response, textStatus, errorThrown) {
          console.error("HTTP status code:", textStatus);
          obj.processing = false;
          return response;
        }
      });
      
    }
  }
  
  function SetNewPath (argLoc, argForm) {
    var strPath = SITE_ROOT + argLoc + "?action=" + argForm.tAction
    
    for(var i=0; i<argForm.length; i++) {
      if ((argForm[i].name != 'action') && ((argForm[i].name != '') && (argForm[i].value != ''))) {
        if ((argForm[i].type == 'text') || (argForm[i].type == 'hidden')) {
          strPath += "&" + argForm[i].name + "=" + argForm[i].value;
        } else if (argForm[i].checked == true) {
          strPath += "&" + argForm[i].name + "=" + argForm[i].value;
        }
      }
    }
    
    return strPath;
  }
  
  window.Autocomplete = {
    Initialize: Initialize
  }
})();

function getElementsByClassName(strClass, strTag, objContElm) {
  strTag = strTag || "*";
  objContElm = objContElm || document;    
  var objColl = objContElm.getElementsByTagName(strTag);
  if (!objColl.length &&  strTag == "*" &&  objContElm.all) objColl = objContElm.all;
  var arr = new Array();                              
  var delim = strClass.indexOf('|') != -1  ? '|' : ' ';   
  var arrClass = strClass.split(delim);    
  for (var i = 0, j = objColl.length; i < j; i++) {
    if (objColl[i].className) {
      var arrObjClass = objColl[i].className.toString().split(' ');   
      if (delim == ' ' && arrClass.length > arrObjClass.length) continue;
      var c = 0;
      comparisonLoop:
      for (var k = 0, l = arrObjClass.length; k < l; k++) {
        for (var m = 0, n = arrClass.length; m < n; m++) {
          if (arrClass[m] == arrObjClass[k]) c++;
          if ((delim == '|' && c == 1) || (delim == ' ' && c == arrClass.length)) {
            arr.push(objColl[i]); 
            break comparisonLoop;
          }
        }
      }
    }
  }
  return arr; 
}
