/*
 * General plugin and function code
 */

// Drilldown plugin code in private scope.
(function($) {

  // search preview function
  $.fn.searchPreview = function() {
    return this.each(function() {
      $(this).keyup(function() {
        if(this.lastValue != this.value && this.value != null && this.value.length > 1) {
          //$('#quick-search-results').show();
          $('#quick-search-results').slideDown(200);
          var q = this.value;
          var qfact = q.replace(/([-\w]+)/gi,'%2B$1*');
          if(this.timer) {
            clearTimeout(this.timer);
          }
          if(this.timer2) {
            clearTimeout(this.timer2);
          }
          this.timer = setTimeout(function() {
            $('#quick-search-results-tests,#quick-search-results-facts,#quick-search-results-articles').loading();
            $.get('/taconite/searchcombo/SearchPreviewTests?q=' + q, function(data){$('#quick-search-results-tests').loading('remove');});
            $.get('/taconite/searchcombo/SearchPreviewFacts?q=' + qfact, function(data){$('#quick-search-results-facts').loading('remove');});
            $.get('/taconite/searchcombo/SearchPreviewArticles?q=' + q, function(data){$('#quick-search-results-articles').loading('remove');});            
          }, 300);
          this.timer2 = setTimeout(function() {
            $('#quick-search-results-ads').loading();
            $.get('/taconite/searchcombo/SearchPreviewAds?q=' + q, function(data){
              pageTracker._trackPageview("/SEARCHBOX/start?q=" + q);
              $('#quick-search-results-ads').loading('remove');
              $('#quick-search-results-ads .show-all').click(function(){
                document.location.href = $(this).attr('href') + '&q=' + q;
                return false;
              });
            });
          }, 300);
          this.lastValue = this.value;
        } else if (this.value.length <= 1) {
          //$('#quick-search-results').hide();
          $('#quick-search-results').slideUp(200);
          this.lastValue = '';
        } 
      });
    });
  };

  var lastDropId = false,
  selectors = {
    navigation: '> li > a',
    items: ' > li',
    selectedItem: 'div.dropdown li.selected',
    dropdown: 'div.dropdown',
    links: 'div.dropdown li a, div.dropdown a.button',
    urlForm: '#url-params'
  },
  dataModel = {
    'drilldown-searchdepartments': {
      populated: true,
      enabled: true
    }
  };

  // Retreves the parent id from current element
  function getParentId(elem) {
    var parent = $(elem).parents('li[id]')[0];
    return (parent) ? parent.id : false;
  }

  // Animate the current dropdown elment id, based on effect and speed
  function animateDropDown(dropId, effect, speed, callback) {
    var $elem = $('#' + dropId).find(selectors.dropdown);
    if (effect == 'fadeOut') {
      var data = dataModel[dropId];
      if(data && data.opened){ data.opened = false;}
      
      // reset SELECT elements for IE6
      if($.browser.msie && /MSIE 6\.0/i.test(window.navigator.userAgent) && !/MSIE 7\.0/i.test(window.navigator.userAgent)){
        $('#search-box #category-specific').show();
      }
      $('#sellertypeform').show();
    } else {
      var offset = $elem.parent().position();
      $elem.css('left',offset.left);
    }
    $elem[effect](speed,callback);
  }

  // disable all dropdown links
  function disableDropDownLinks(link) {
    $(link).addClass('disabled');
  }

  // enable all dropdown links
  function enableDropDownLinks(link) {
    $(link).removeClass('disabled');
  }

  // enable dropdown, bad function name though? (enableD)
  function enabledDropDown(dropId) {
    // Get the current data model and set the enabled prop to true.
    //var dropData = dataModel[dropId];
    //dropData.enabled = true;
    // Add enabled class to main container based on Id.
    $('#' + dropId).addClass('enabled');
  }

  // send a get ajax request based on href target.
  function loadDropDown(href, dropId, dropData, show) {
    var urlParts = href.split('?'), params = {}, url = href, formParams = serializeFormUrlParams(), exclude = [];
    if(urlParts[1]) {
      params = urlParts[1];
      url = urlParts[0];
    }
    if(dropData.excludeParams) exclude = dropData.excludeParams;
    params = $.extend(parseUrlParams(formParams, exclude),parseUrlParams(params, []));
    url = url + appendParams(params);
    $('#facts-result').loading();
    $.get(url, function() {
      $('#facts-result').loading('remove');
      lastRequestedURL = href;

      // populate data
      $('#' + dropId).addClass('populated');

      if(show) animateDropDown(dropId,'fadeIn','fast');   
    });
  }

  function appendParams(p) {
    var a = []; //'?';
    for(var i in p) {
      if(p[i].length > 0) a.push(i + '=' + p[i]);
    }
    return '?' + a.join('&');
  }

  function parseParam(p) {
    return p.split('=');  
  }

  function inArray(key,arr) {
    if (arr) {
      for (var i = 0; i < arr.length; i++) {
        if (key == arr[i]) return true;
      }
    }
    return false; 
  }

  function parseUrlParams(params,exclude) {
    var hash = {};
    if(params.length > 0) {
      if(params.split('&')[1]) {
        params = params.split('&');
        for (var i = 0; i < params.length; i++) {
          var p = parseParam(params[i]);
          if(!inArray(p[0],exclude)) hash[p[0]] = p[1];
        }
      } else {
        var p = parseParam(params);
        if(!inArray(p[0],exclude)) hash[p[0]] = p[1];
      }
    }
    return hash;
  }


  // get url parameters from hidden form url-params.
  function serializeFormUrlParams() {
    var str = $(selectors.urlForm).serialize();
    return (str.length > 0) ? str : '';
  }

  // Disables underlaying dropdowns based on the data model in dataModel
  function disableUnderlayingDropDowns(dropId) {
    var removeNext = false;
    // Loop thru the data model
    $.each(dataModel,function(key, val) {
      // Start removing underlaying dropdown.
      if (removeNext && val.dependent) {
        // Disabled props
        // Add disabled dropdown to list arr.
        var $span = $('#' + key).removeClass('enabled').find(' > a span');
        if($span.length > 0)$span.text($span[0]._orgName);
      }
      // Set remove mode
      if(key == dropId) removeNext = true;
    });
  }

  function removeDropDownLinkSelection(id){
    $('#' + id + ' li.selected').removeClass('selected');
  }

  function addLinkDropDownName(id,elem) {
    var $span = $('#' + id).find('a > span');
    if(!$span[0]._orgName) $span[0]._orgName = $span.text();
    $span.text($(elem).text());
  }

  function isDropDownEnabled(id) {
    return $('#' + id).is('.enabled');
  }

  function isDropDownPopulated(id) {
    return $('#' + id).is('.populated');
  }

  // Extend main jQuery scope, function drilldown
  $.extend($, {
    drilldown: {
      construct: function(elem) {
        $(elem)
          .find(selectors.navigation)
          .click(function() {
                    
            // Get drop id from parent element
            var dropId = getParentId(this),
            // Get current dropData from parent id
            dropData = dataModel[dropId];
            // if no drop data is present return false
            if(!dropData) return false;
            // if dropdown is opened close it.
                  
            // Only preform a action if the dropdown is enabled.
            if(isDropDownEnabled(dropId)) {  
              if(dropData.opened) {
                animateDropDown(lastDropId,'fadeOut',10);
                return false;
              }
              // If the current dropdown is enabled and is not populated. 
              if (!isDropDownPopulated(dropId) && isDropDownEnabled(dropId)) {
                // Send the ajax request.
                loadDropDown(this.href, dropId, dropData, true);
                // Enabled the dropdown based on element id attribute
                enabledDropDown(dropId);    
              } else {
                // If the last dropdown is not the same as the current close it.
                animateDropDown(lastDropId,'fadeOut','fast');
                // Open the current dropdown.
                animateDropDown(dropId,'fadeIn','fast');
              }
              // Store the current id as lastDropId
              lastDropId = dropId;

              // Set opened state
              dropData.opened = true;

              // hide SELECT elements for IE6
              if($.browser.msie && /MSIE 6\.0/i.test(window.navigator.userAgent) && !/MSIE 7\.0/i.test(window.navigator.userAgent)){
                $('#search-box #category-specific').hide();
              }
              $('#sellertypeform').hide();
            }
            // Cancel normal event behavior.
            return false;
          })
        .end()
        .find(selectors.items)

        .each(function() {
          var drop = $(this);
          drop
            .find(selectors.selectedItem)
            .each(function() {
              addLinkDropDownName(drop.attr('id'),this);
            });
        });
        // Bind click event to all new appended links in dropdown div.  
        $(selectors.links)
          .livequery('click', function(event) {

            if($(this).hasClass('exclude')) return true;

            // if link is disabled return false, prevents dubble clicks
            if($(this).hasClass('disabled') || $(this).parent().hasClass('ui-slider') || $(this).parent().hasClass('ui-slider-2')) return false;

            // save a reffrence to the link dom object.
            var oLink = this;

            // set diable class name
            disableDropDownLinks(oLink);

            // Get dropData based on element attribute id
            var parentDropData = dataModel[lastDropId];
            //if(parentDropData.opened) parentDropData.opened = false;
            var dropId = parentDropData.next;
            var dropData = dataModel[dropId];

            // Fade out the last selected dropdown
            animateDropDown(lastDropId,'fadeOut','fast',function() {
              // when fade is finshed remove disable class
              enableDropDownLinks(oLink);
            });
            // Append clicked name to dropdown tab
            if(!$(this).hasClass('button')) addLinkDropDownName(lastDropId, this);
            // If the current dropdown has a next property
            if (dropId) {
              // Check if the are dropdown under the current one.
              disableUnderlayingDropDowns(lastDropId);
              // Send a ajax request, cache this should be cached.
              loadDropDown(this.href, dropId, dropData, false);
              // Enable current dropdown
              enabledDropDown(dropId);
              // Remove last selected dropdown content link.
              removeDropDownLinkSelection(lastDropId);
              // Store current dropdown as lastDropId
              lastDropId = dropId;
            // current dropdown does not have a next property
            } else {
              // Send a ajax request, cache this should be cached.
              loadDropDown(this.href, lastDropId, parentDropData, false);
              // Remove last selected dropdown content link.
              removeDropDownLinkSelection(lastDropId);
              // Store current dropdown as lastDropId
              lastDropId = dropId;
            }
            // Add link selection class to parent element in this case the LI
            $(this).parent().addClass('selected');
            // Cancel normail event behavior
            return false;
        });
        // bind to doc ready.
        $(document).click(function(event) {
            if($(event.target).parents('#' + lastDropId).length == 0) animateDropDown(lastDropId,'fadeOut','fast');
        });
      }
    }
  });

  // extend jQuery's plugin scope
  $.extend($.fn, {
    drilldown: function() {
      return this.each(function() { 
        $.drilldown.construct(this);
      });
    }
  });

  // init plugin method number
  $.extend($.fn, {
    number: function() {
      return parseInt($(this).text());
    }
  });

  // init plugin method loading
  $.extend($.fn, {
    loading: function(action) {
      var a = action || 'add';
      return this.each(function() {
        if (a == 'add') {
          var w = $(this).outerWidth(), h = $(this).outerHeight();
          $(this).append($('<div class="loading"><img src="/images/loading.gif"/><p>Laddar information...</p><div>').css({}));
        } else {
          $(this).find('div.loading').remove();
        }
      });
    }
  });

  $.extend(
    $.expr[ ":" ],
    { reallyvisible : "!($(a).is(':hidden') || $(a).parents(':hidden').length)" }
  );

})(jQuery);
