
// ajax support code for shopping cart
// Copyright 2009-2010 A Main Hobbies

var _ConfirmDialogCallbackObj = null;
var _SearchAssistTimer = -1;

(function($) {
  jQuery.fn.delay = function(delay) {
    var obj = $(this);
    obj.queue(function() {
      setTimeout(function() { obj.dequeue(); }, delay); });
      return this;
    }
  })(jQuery);

function AJAXRequest(request_type, data_type, data_value, async, url, timeout, success, error, complete) {
    if (typeof success == 'undefined' || success == null) {
        success = function () { };
    }
    if (typeof error == 'undefined' || error == null) {
        error = function () { };
    }
    if (typeof complete == 'undefined' || complete == null) {
        complete = function () { };
    }
    return $.ajax({
        url: url,
        type: request_type,
        data: data_value,
        dataType: data_type,
        timeout: timeout,
        async: async,
        traditional: true
    })
    .success(function (data, textStatus, jqXHR) { success(data, textStatus, jqXHR); })
    .error(function (jqXHR, textStatus, errorThrown) { error(jqXHR, textStatus, errorThrown); })
    .complete(function (jqXHR, textStatus) { complete(jqXHR, textStatus); });
}

function JSONRequest(url, data, timeout, success, error, complete) {
    // note: we use 'text json' instead of 'json' due to a bug in the jQuery Validation plugin
    // (see http://bugs.jquery.com/ticket/8064). the additional type works around the bug.
    return AJAXRequest('POST', 'text json', data, false, url, timeout, success, error, complete);
}

function AsyncJSONRequest(url, data, timeout, success, error, complete) {
    // note: we use 'text json' instead of 'json' due to a bug in the jQuery Validation plugin
    // (see http://bugs.jquery.com/ticket/8064). the additional type works around the bug.
    return AJAXRequest('POST', 'text json', data, true, url, timeout, success, error, complete);
}

function POSTRequest(url, data, timeout, success, error, complete) {
    return AJAXRequest('POST', 'text', data, false, url, timeout, success, error, complete);
}

function AsyncPOSTRequest(url, data, timeout, success, error, complete) {
    return AJAXRequest('POST', 'text', data, true, url, timeout, success, error, complete);
}

function GETRequest(url, timeout, success, error, complete) {
    return AJAXRequest('GET', 'text', {}, false, url, timeout, success, error, complete);
}

function AsyncGETRequest(url, timeout, success, error, complete) {
    return AJAXRequest('GET', 'text', {}, true, url, timeout, success, error, complete);
}

// NOTE: once we give the span a layout, :active doesn't work on the containing anchor
function IETextShadow(obj, radius)
{
  if ($.browser.msie)
  {
    $(obj).children("span.IEshadow").remove();

    // inspired by example from Kilian Valkhof
    $(obj).css({ position: "relative", zoom: 1 }).append("<span class='IEshadow'>" + $(obj).text() + "</span>");
    $(obj).children("span.IEshadow").css({position: "absolute", zIndex: -1, zoom: 1, left: -2, top: -2, color: '#202020', filter: "progid:DXImageTransform.Microsoft.Glow(Color=#202020,Strength=0.5) progid:DXImageTransform.Microsoft.Blur(pixelradius=" + radius + ", enabled='true') progid:DXImageTransform.Microsoft.Alpha(opacity=50)", "-ms-filter":"\"progid:DXImageTransform.Microsoft.Glow(Color=#202020,Strength=0.5) progid:DXImageTransform.Microsoft.Blur(pixelradius=" + radius + ", enabled='true') progid:DXImageTransform.Microsoft.Alpha(opacity=50)\""});
  }
}

function BindButtonEvents(obj)
{
  $('a.button20', obj).bind('keydown', function(e) {
      if (e.keyCode == 0x20 || e.keyCode == 0x0d) {
        if (!$(e.target).hasClass('button20-disabled'))
          $(e.target).addClass('button20-active');
        return false;
      }
      return e.ctrlKey || e.ctrlKey || (e.keyCode < 0x20);
    })
    .bind('keyup', function(e) {
      if (e.keyCode == 0x20 || e.keyCode == 0x0d) {
        $(e.target).removeClass('button20-active');
        if (!$(e.target).hasClass('button20-disabled') && $(e.target).click() && $(e.target).attr('href'))
          document.location = $(e.target).attr('href');
        return false;
      }
      return e.ctrlKey || e.ctrlKey || (e.keyCode < 0x20);
    });
  $('a.button25', obj).bind('keydown', function(e) {
      if (e.keyCode == 0x20 || e.keyCode == 0x0d) {
        if (!$(e.target).hasClass('button25-disabled'))
          $(e.target).addClass('button25-active');
        return false;
      }
      return e.ctrlKey || e.ctrlKey || (e.keyCode < 0x20);
    })
    .bind('keyup', function(e) {
      if (e.keyCode == 0x20 || e.keyCode == 0x0d) {
        $(e.target).removeClass('button25-active');
        if (!$(e.target).hasClass('button25-disabled') && $(e.target).click() && $(e.target).attr('href'))
          document.location = $(e.target).attr('href');
        return false;
      }
      return e.ctrlKey || e.ctrlKey || (e.keyCode < 0x20);
    });
}

function AddToShoppingCartComplete(result, obj)
{
  var product_id = $(obj).attr('product_id');
  var buttons = $('.buy-now-button[product_id="' + product_id + '"]');

  if (result.substr(0, 3) == 'OK ')
  {
    var lines = result.substr(3).split("\n");
    if (lines.length >= 3)
    {
      var node = document.createElement('div');
      var quantity = lines[1];
      var message = lines[2];
      $(node).html(lines.slice(3).join('\n'));
      var contents = $(node).find('#shopping_cart_quicklist').children();
      var size = 0;
      $('#shopping_cart_quicklist').empty();
      $('#shopping_cart_quicklist').append(contents);
      $(buttons).each(function() {
        if ($(this).hasClass('button20'))
        {
          $(this).removeClass('button20-blue').removeClass('button20-green').removeClass('button20-red').removeClass('button20-gray');
          $(this).addClass('button20-gray');
          size = 1.0;
        }
        else
        {
          $(this).removeClass('button25-blue').removeClass('button25-green').removeClass('button25-red').removeClass('button25-gray');
          $(this).addClass('button25-gray');
          size = 1.5;
        }
        var contents = $(this).children('span');
        var icon = $(contents).children('b.button-icon');
        $(contents).text(quantity + ' In Cart!').prepend(icon);
        if ($.browser.msie)
          $(contents).each(function() { IETextShadow(this, size); });

        if (message != '')
        {
          $('#cartmsg').remove();
          $('body').append('<div class="checkpointSubhead checkpointSubheadWarning" id="cartmsg"><p>' + message + '</p></div>');
          $('#cartmsg').css('left', $(obj).offset().left).css('top', $(obj).offset().top - 60);
          $('#cartmsg').fadeIn(1000).delay(2500).fadeOut(1500, function() { $(this).remove(); });
        }
      });
    }
  }
}

function preFillQuantity(products_id) {
  qtyElem = document.getElementById(products_id);
  if (qtyElem.value == '') {
    qtyElem.value = 1;
  }
  document.add_to_cart.submit();
}

function AddToShoppingCart(obj, id)
{
  var qty = 1;
  var input = new Array();
  var dp = $(obj).hasClass('button20') ? 'button20-disabled' : 'button25-disabled';

  if (isNaN(id) || $(obj).hasClass(dp))
    return false;

  if ($(obj).closest('.wlproduct').length)
    input = $(obj).closest('.wlproduct').find('td:last').find('input.wlpl_quantity[type=text]');
  else
    input = $(obj).closest('form').find('input[type=text][name=cart_quantity]');
  if (input.length)
    qty = parseInt($(input).attr('value'));

  if (isNaN(qty))
    return false;

  $("body").css("cursor", "progress");
  $(obj).css("cursor", "progress").addClass(dp);
  POSTRequest(
    'http://www.amainhobbies.com/product_info.php',
    { ajax: 1, action: 'add_product_to_cart', product_id: id, product_quantity: qty },
    2500,
    function(result) {
      AddToShoppingCartComplete(result, obj);
    },
    function(result) {
    },
    function(result) {
      $("body").css("cursor", "auto");
      $(obj).css("cursor", "pointer");
      setTimeout(function() { $(obj).removeClass(dp); }, 250);
    });
  return false;
}

function AddToWishListComplete(result, obj)
{
  var product_id = $(obj).attr('product-id');
  var buttons = $('.wish-list-button[product-id="' + product_id + '"]');

  if (result.substr(0, 3) == 'OK ')
  {
    var lines = result.substr(3).split("\n");
    if (lines.length >= 2)
    {
      var productID = parseInt(lines[0]);
      var quantity = parseInt(lines[1]);
      var size = 0;
      if (!isNaN(productID) && !isNaN(quantity))
      {
        $('#wish_list_quicklist').load('http://www.amainhobbies.com/wish_list.php/action/quick_list/ticks/' + new Date().getTime() + ' div#wish_list_quicklist > table', function() { $('#wish_list_quicklist').show(); });
        $(buttons).each(function() {
          if ($(this).hasClass('button20'))
          {
            $(this).removeClass('button20-blue').removeClass('button20-green').removeClass('button20-red').removeClass('button20-gray');
            $(this).addClass('button20-gray');
            size = 1.0;
          }
          else
          {
            $(this).removeClass('button25-blue').removeClass('button25-green').removeClass('button25-red').removeClass('button25-gray');
            $(this).addClass('button25-gray');
            size = 1.5;
          }
          var contents = $(this).children('span');
          var icon = $(contents).children('b.button-icon');
          $(contents).text(quantity + ' In Wish List!').prepend(icon);
          if ($.browser.msie)
            $(contents).each(function() { IETextShadow(this, size); });
        });
      }
    }
  }
}

function AddToWishList(obj, id)
{
  var dp = $(obj).hasClass('button20') ? 'button20-disabled' : 'button25-disabled';
  var qtyobj = $(obj).closest('tr').children('td').find('input[name="cart_quantity"]');
  var qty = 1;

  if (isNaN(id) || $(obj).hasClass(dp))
    return false;

  if (qtyobj.length > 0) {
    var v = $(qtyobj).val();

    if (isNaN(parseFloat(v)) || !isFinite(v) || v <= 0 || v > 99) {
      return;
    }
    qty = v;
  }

  $("body").css("cursor", "progress");
  $(obj).css("cursor", "progress").addClass(dp);
  POSTRequest(
    'http://www.amainhobbies.com/wish_list.php',
    { ajax: 1, action: 'add_product_to_wishlist', product_id: id, product_quantity: qty },
    2500,
    function(result) {
      AddToWishListComplete(result, obj);
    },
    function(result) {
    },
    function(result) {
      $("body").css("cursor", "auto");
      $(obj).css("cursor", "pointer");
      setTimeout(function() { $(obj).removeClass(dp); }, 250);
    });
  return false;
}

// Default button click function; doesn't do anything and cancels event
function ButtonClick()
{
  return false;
}

function _ResizeDialog(obj, cw, ch)
{
  var content = $(obj).find('div.dialog-content');

  if (content == null) {
    return;
  }

  if (cw < 150)
    cw = 150;

  // add 2 pixels (actually 1 is enough, but to be safe ...) to compensate for
  // apparent bug in Gecko appearing at least in Firefox 4.0, where setting the
  // size to the same width as it currently is (where that width is exactly the
  // size needed to encompass the text) will cause the text to wrap to the next
  // line.
  cw += 2;

  var w = cw + 28;
  var h = ch + 39;
  var buttons = $(obj).find('div.dialog-button-row');
  if (buttons.length)
  {
    $(buttons).width(cw);
    ch += 22;
    h += 22;
  }

  $(obj).width(w).height(h);
  $(obj).find('div.dialog-caption, div.dialog-bottom-content').width(w - 60);
  $(obj).find('div.dialog-middle').height(ch);

  // we set text-align to center to ensure that if the content is narrower than
  // the dialog, it will be centered. note however that this alignment however needs
  // to be removed when measuring the content size for dialog sizing purposes.
  $(content).width(cw).height(ch).css('text-align', 'center');
  $(obj).position({ my: "center bottom", at: "center center", of: window, collision: "fit" });
}

function _ModalOpen(obj)
{
  obj.container.show();
  obj.overlay.show();
  obj.data.show();

  // get the size of the content, excluding any standard buttons
  // first, we re-size the content to a default size
  // we also need to remove the 'text-align: center' attribute from the container
  $(obj.container).find('div.dialog-content').css('text-align', 'left').width(500).height(500);

  var content = $(obj.data).find('span.dialog-inner-content');
  var cw = $(content).width();
  var ch = $(content).height();

  _ResizeDialog(obj.data, cw, ch);
  var target = $(obj.data).find('input:visible:first');
  if (target.length == 0)
    target = $(obj.data).find('a.submit-button:last');
  if (target.length == 0)
    target = $(obj.data).find('a.cancel-button:last');
  if (target.length == 0)
    target = $(obj.data).find('a:visible:last');
  if (target.length == 0)
    target = $(obj.data);
  $(target).focus();
}

function _ModalClose(obj)
{
  $(window).unbind('.modalDialog');
  obj.data.hide();
  obj.container.hide();
  obj.overlay.hide();
  $.modal.close();
}

function ModalDialog(obj)
{
  $(window).unbind('.modalDialog');
  if (obj !== null)
  {
    // find any input elements that don't have a tabindex (or which are 0) and set them to '1'
    $(obj).find('input:enabled, textarea:enabled').each(function() { var t = $(this).attr('tabindex'); if (t == undefined || t == 0) $(this).attr('tabindex', 1); });

    // find any buttons that don't have a tabindex (or which are 0) and set them to '10000'
    $(obj).find('a.button20, a.button25').each(function() { var t = $(this).attr('tabindex'); if (t == undefined || t == 0) $(this).attr('tabindex', 10000); });

    $(obj).draggable({ cancel: 'input, textarea, button, a, .dialog-close-button', delay: 0 } );
    $(obj).modal();
  }
  else
  {
    $.modal.close();
  }
  return obj;
}

function ErrorDialog(message)
{
  var html = "<div id='generic-error-dialog' class='dialog-container' tabindex='-1'><div class='dialog-top'><div class='amdialog dialog-top-left'></div><div class='amdialog dialog-caption'><span>Error</span></div><div class='amdialog dialog-top-right dialog-close-button'></div></div><div class='dialog-middle'><div class='amdialog dialog-content-left'></div><div class='amdialog dialog-content'><span class='dialog-inner-content'><div class='dialog-content-spacer-before'></div><table border='0' cellpadding='0' cellspacing='0'><tr><td valign='top'></td><td valign='top' class='message-placeholder'></td></tr></table><div class='dialog-content-spacer-after'></div></span><div class='dialog-button-row'><span class='button-separator'></span><a tabindex='10000' onclick='ModalDialog(null)' alt='Ok' unselectable='on' onselectstart='return false' ondragstart='return false' class='button-h button20 button20-blue fix-ie-hover-focus  hasicon'><span class='hasicon'><b class='button-icon button-icon-update'></b>Ok</span><sup></sup></a></div></div><div class='amdialog dialog-content-right'></div></div><div class='dialog-bottom'><div class='amdialog dialog-bottom-left'></div><div class='amdialog dialog-bottom-content'></div><div class='amdialog dialog-bottom-right'></div></div></div>";

  ModalDialog(null);
  $('#generic-error-dialog').remove();
  $('body').append(html);
  var dialog = $('#generic-error-dialog');
  $(dialog).find('.message-placeholder').append(message.replace(/\*/gm, '<li>'));
  BindButtonEvents(dialog);
  ModalDialog(dialog);
  return false;
}

function ConfirmDialogCallback(obj)
{
  ModalDialog(null);
  if (typeof(_ConfirmDialogCallbackObj) == "object")
    $(_ConfirmDialogCallbackObj).click();
  else if (typeof(_ConfirmDialogCallbackObj) == "string")
    document.location = _ConfirmDialogCallbackObj;
}

function ConfirmDialog(caption, message, objToSendClickTo)
{
  var html = "<div id='generic-confirmation-dialog' class='dialog-container' tabindex='-1'><div class='dialog-top'><div class='amdialog dialog-top-left'></div><div class='amdialog dialog-caption'><span></span></div><div class='amdialog dialog-top-right dialog-close-button'></div></div><div class='dialog-middle'><div class='amdialog dialog-content-left'></div><div class='amdialog dialog-content'><span class='dialog-inner-content'><div class='dialog-content-spacer-before'></div><table border='0' cellpadding='0' cellspacing='0'><tr><td valign='top'></td><td valign='top' class='message-placeholder'></td></tr></table><div class='dialog-content-spacer-after'></div></span><div class='dialog-button-row'><span class='button-separator'></span><a tabindex='10000' onclick='ModalDialog(null)' alt='No' unselectable='on' onselectstart='return false' ondragstart='return false' class='button-h button20 button20-blue fix-ie-hover-focus cancel-button hasicon'><span class='hasicon'><b class='button-icon button-icon-delete'></b>No</span><sup></sup></a><span class='button-separator'></span><a tabindex='10000' onclick='ConfirmDialogCallback(this)' alt='Yes' unselectable='on' onselectstart='return false' ondragstart='return false' class='button-h button20 button20-blue fix-ie-hover-focus submit-button hasicon'><span class='hasicon'><b class='button-icon button-icon-confirm-action'></b>Yes</span><sup></sup></a></div></div><div class='amdialog dialog-content-right'></div></div><div class='dialog-bottom'><div class='amdialog dialog-bottom-left'></div><div class='amdialog dialog-bottom-content'></div><div class='amdialog dialog-bottom-right'></div></div></div>";

  ModalDialog(null);
  _ConfirmDialogCallbackObj = objToSendClickTo;
  $('#generic-confirmation-dialog').remove();
  $('body').append(html);
  var dialog = $('#generic-confirmation-dialog');
  $(dialog).find('.dialog-caption span').text(caption);
  $(dialog).find('.message-placeholder').append(message);
  BindButtonEvents(dialog);
  ModalDialog(dialog);
  return false;
}

function TableSortCookieWidget(table)
{
  var cookieName = $(table).attr('sortCookie');
  if (cookieName)
  {
    // If the existing sortList isn't empty, set it into the cookie, unless
    // the sort order is 2 (unsorted), in which case we delete the cookie
    if (table.config.sortList.length > 0)
    {
      data = table.config.sortList[0][1] != 2 ? table.config.sortList[0].join() : null;
      $.cookie(cookieName, data, {path: '/', expires: 365});
      $('table.sortable-product-listing[sortCookie=' + cookieName + ']').each(function() { if (this != table) $(this).trigger("clone", table); });
    }
  }
}

function RestoreTableSort(table)
{
  var cookieName = $(table).attr('sortCookie');
  if (cookieName)
  {
    var cookie = $.cookie(cookieName);
    if (typeof cookie == "string")
    {
      data = cookie.split(',', 2);
      if (data.length == 2 && !isNaN(data[0]) && data[0] >= 0 && !isNaN(data[1]) && data[1] >= 0 && data[1] < 3)
      {
        table.config.sortList = [data];
        $(table).trigger("sorton", [table.config.sortList]);
      }
    }
  }
}

function SetupAjaxButtons()
{
  if ($.browser.msie)
  {
    $('a.button25 span').each(function() { IETextShadow(this, "1.5") });
    $('a.button20 span, .button-bar a span.button-label').each(function() { IETextShadow(this, "1.0") });
    $('div.dialog-close-button')
      .hover(function(){ $(this).addClass('ie-button-hover'); }, function(){ $(this).removeClass('ie-button-hover'); })
      .focus(function(){ this.hideFocus=true; $(this).addClass('ie-button-focus'); })
      .blur(function(){ $(this).removeClass('ie-button-focus'); });
    $('.button25.fix-ie-hover-focus')
      .hover(function(){ $(this).addClass('ie-button25-hover'); }, function(){ $(this).removeClass('ie-button25-hover'); })
      .mousedown(function() { if (!$(this).hasClass('button25-disabled')) $(this).addClass('ie-button25-active'); })
      .mouseup(function() { $(this).removeClass('ie-button25-active'); });
    $('.button20.fix-ie-hover-focus')
      .hover(function(){ $(this).addClass('ie-button20-hover'); }, function(){ $(this).removeClass('ie-button20-hover'); })
      .mousedown(function() { if (!$(this).hasClass('button20-disabled')) $(this).addClass('ie-button20-active'); })
      .mouseup(function() { $(this).removeClass('ie-button20-active'); });
    $('span.button-bar a.fix-ie-hover-focus')
      .hover(function(){ $(this).addClass('ie-button-bar-hover'); }, function(){ $(this).removeClass('ie-button-bar-hover'); })
      .mousedown(function() { $(this).addClass('ie-button-bar-active'); })
      .mouseup(function() { $(this).removeClass('ie-button-bar-active'); });
  }

  if (!$.browser.mozilla)
    $('input').keydown(function(e) { if (e.keyCode == 13) { var t = $(e.target).closest('form').find('a.submit-button:first'); if (t.length) { $(t).click(); return false; } return true; } });

  $.modal.defaults.closeClass = "dialog-close-button";
  $.modal.defaults.opacity = 20;
  $.modal.defaults.persist = true;
  $.modal.defaults.minHeight = 100;
  $.modal.defaults.minWidth = 100;
  $.modal.defaults.onOpen = _ModalOpen;
  $.modal.defaults.onClose = _ModalClose;
  $('.ui-button').hover(function() { $(this).addClass('ui-state-hover'); }, function() { $(this).removeClass('ui-state-hover'); });

  var checkbox_rows = $('tr.checkbox-row');
  $(checkbox_rows).hover(function() { $(this).addClass('checkbox-row-hover'); }, function() { $(this).removeClass('checkbox-row-hover'); });
  $(checkbox_rows).css('cursor', 'pointer');
  $(checkbox_rows).mousedown(function() { return false; });

  $(checkbox_rows).click(function() { var checkbox = $(this).find('input[type=checkbox]'); $(checkbox).attr('checked', !$(checkbox).attr('checked')); return false; });
  $(checkbox_rows).find('input[type=checkbox]').mousedown(function() { $(this).attr('checked', !$(this).attr('checked')); return false; });

  $('.ajax-buy-now-button').each(function() {
    var o = this;

    // make sure the submit callback is only bound once.
    $(this).closest('form').unbind('submit').submit(function(e) {
      $(o).click();
      return false;
    });
  });
  $('.dialog-container').find('input[type=text]').addClass('submit-on-enter');
  $('.submit-on-enter').bind('keydown', function(e) { if (e.keyCode == 13) { $(e.target).closest('.dialog-container').find('a.submit-button:first').click(); return false; } });

  $.simpletablesorter.addWidget({ id: "sortPersist", format: TableSortCookieWidget });
  $('table.sortable-product-listing').simpletablesorter({ sortMultiSortKey: false, textExtraction: "complex", headers: { 0: { sorter: false }, 3: { sorter: false } }, widgets: ['sortPersist'] }).each(function() { RestoreTableSort(this); });

  BindButtonEvents($('body'));
}

// return the number of pixels needed to scroll the element into full visibility.
// positive values mean move the element down.
function ElementVisibilityOffset(obj)
{
  var ot = $(obj).offset().top;
  var ob = ot + $(obj).height();
  var wt = $(window).scrollTop();
  var wb = wt + $(window).height();

  if ((ot >= wt && ob <= wb) || (ot < wt && ob > wb)) {
    return 0;
  }
  return wt - ot;
}

function SearchAssistShown() {
  $.cookie('searchassist_triggered', 'true', { path: '/' });
}

function ShowSearchAssist() {
  var qs = $('input[id=quick_find]');
  var qsp = $('#search_container');

  _SearchAssistTimer = -1;
  if ($(qs).length != 1) {
    // either we've already been triggered once, or there is no search box: either case, we should not be here.
    return;
  }

  if ($(qs).get(0) === document.activeElement) {
    // input has focus, but nothing's been typed. avoid annoying the visitor.
    $.cookie('searchassist_triggered', 'true', { path: '/' });
    return;
  }

  var val = jQuery.trim($(qs).val());
  if ((val.length > 0) && (val != 'Enter search here')) {
    // if something is in the input field, there's no need to proceed as the visitor clearly know it's there ...
    $.cookie('searchassist_triggered', 'true', { path: '/' });
    return;
  }

  var offset = ElementVisibilityOffset(qs);
  if (offset != 0) {
    var width = $(qsp).width();
    var height = $(qsp).height();
    var left = $(qsp).position().left;
    var orig = qsp;
    var ie = $.browser.msie;

    qsp = $(qsp).clone();
    qs = $('#quick_find', qsp);
    $('body').append(qsp);
    $(qs).focus(SearchBoxEvent).keydown(SearchBoxEvent);
    SetupSearchAutocomplete(qs);
    if (ie) {
      var top = $(window).scrollTop() - height;

      $(qsp).css({ position: 'absolute', left: left, width: width, height: height, top: top + 'px' }).animate({ top: "+=" + height }, 1000);
      $(window).scroll(function() {
        if (ElementVisibilityOffset(orig) == 0) {
          // original element is visible, remove the clone
          $(qsp).remove();
          qsp = undefined;
          return;
        }

        if (qsp) {
          $(qsp).css({ top: $(window).scrollTop() + 'px' });
        }
      });
    } else {
      $(qsp).css({ position: 'fixed', left: left, width: width, height: height, top: (-height) + 'px' }).animate({ top: "+=" + height }, 1000);
      $(window).scroll(function() {
        $(qsp).toggle(ElementVisibilityOffset(orig) != 0);
      });
    }
  } else {
    $(qsp).css({ position: 'relative' });
    $(qsp).animate({ left: "-=2" }, 'fast');
    for (var i = 0; i < 2; i++) {
      $(qsp).animate({ left: "+=7" }, 'fast').animate({ left: "-=7" }, 'fast');
    }
    $(qsp).animate({ left: "+=2" }, 'fast');
  }

  for (var i = 0; i < 4; i++) {
    $(qs).animate({ backgroundColor: 'yellow' }, 500).animate({ backgroundColor: 'white' }, 500, function() { $(qs).css({ backgroundColor: '' }); });
  }

  // set the cookie for six seconds in the future, to avoid cases where the visitor
  // has clicked on a link just as the assist has kicked in.
  setTimeout(SearchAssistShown, 6000);
}

function SearchBoxEvent() {
  $(this).stop(true, true).css({ background: '', color: 'black' });
  if ($(this).val() == 'Enter search here') {
    $(this).val('');
  }
  if (_SearchAssistTimer != -1) {
    clearTimeout(_SearchAssistTimer);
    _SearchAssistTimer = -1;
  }
}

function SetupSearchAutocomplete(obj) {
  if (_AutoCompleteTerms == undefined) {
    return;
  }
  if (obj == undefined) {
    obj = $('#quick_find');
  }
  $(obj).autocomplete({
    source: _AutoCompleteTerms,
    minLength: 2,
    autoFocus: true,
    create: function() {
      // remove some of the the default UI classes to make custom styling easier
      $('ul.ui-autocomplete').removeClass('ui-menu ui-widget ui-widget-content ui-corner-all').data('searchInput', obj);
    },
    open: function() {
      // don't want any more than 25 items in the list
      $('ul.ui-autocomplete').find('li:gt(25)').remove();
    },
    select: function(e, u) {
      $(obj).val(u.item.label);
      $(obj).closest('form').submit();
    }
  });
  if (document.location.pathname == '/advanced_search_result.php') {
    var val = $(obj).val();

    // removing and then setting the value again is a simple way of causing the
    // edit caret to move to the end of the input field.
    $(obj).val('');
    $(obj).focus();
    $(obj).val(val);
  }
}

function SetupSearchAssistant() {
  var qs = $('#quick_find');
  var tr = $.cookie('searchassist_triggered');

  $('li.ui-menu-item a', $('#quick_find').autocomplete('widget')).live('click', function(e) {
    e.preventDefault();
    e.stopPropagation();
    $(this).closest('ul.ui-autocomplete').data('searchInput').closest('form').submit();
    return false;
  });

  // Let the search assistant run as many times as it gets triggered
  //if (tr != null && tr == 'true') {
  //  return;
  //}

  // set the hint on the search box, if it's empty and doesn't already have focus
  if (jQuery.trim($(qs).val()).length == 0 && $(qs).get(0) !== document.activeElement) {
    $(qs).val('Enter search here').css({ color: 'gray' }).focus(SearchBoxEvent).keydown(SearchBoxEvent);
  }

  // if the search box is available, set the timer for 30 seconds
  if ($('#quick_find').length > 0) {
    _SearchAssistTimer = setTimeout(ShowSearchAssist, 30000);
  }
}

