(function($) {

  $.fn.slider = function(options)
  {
    var opts = $.extend({}, $.fn.slider.defaults, options);

    return this.each(function()
    {
      var $select = $(this);
      var _select = this;
      _select.ticks = new Array();

      var $container = $('<div class="slider"><img src="/images/slider-bar.gif" class="bar" alt="" /><span class="range"></span></div>').insertAfter($select);
      var $handles = $('<span class="left"><span class="label"></span><span class="anchor"></span></span><span class="right"><span class="label"></span><span class="anchor"></span></span>').appendTo($container);

      var $left = $handles.filter('.left');
      var $right = $handles.filter('.right')
      var $range = $container.find('.range');

      var _width = $container.width();
      var _handleWidth = $handles.width();
      var _offset =  opts.tweaks.margin + (_handleWidth/2);

      var _min = Infinity;
      var _max = 0;

      $select.find('option').each(function(i)
      {
        _select.ticks[i] = {value:this.value,pixel:0};
        _min = Math.min(_min,this.value);
        _max = Math.max(_max,this.value);
      });

      var _factor = (_max-_min)/_width;

      for(var i=0; i < _select.ticks.length; i++)
      {
        _select.ticks[i].pixel = Math.round((_select.ticks[i].value-_min)/_factor);
        $container.prepend('<span class="tick" style="left:'+_select.ticks[i].pixel+'px;"></span>');
      }

      $left.attr('slidermin',0-_handleWidth).attr('slidermax',_width-_handleWidth).attr('slidervalue',_min).find('.label').text(_min);
      $right.attr('slidermin',0).attr('slidermax',_width).attr('slidervalue',_max).find('.label').text(_max);

      $container.mousemove(function(e)
      {
        if($left.find('span.anchor').get(0).clicked)
        {
          if(parseInt(e.pageX-_offset) >= parseInt($left.attr('slidermin')) && parseInt(e.pageX-_offset) <= parseInt($left.attr('slidermax')))
          {
            if(parseInt(e.pageX-_offset) <= parseInt($right.css('left').replace('px',''))-_handleWidth)
            {
              $left.get(0).style.left = e.pageX-_offset+"px";

              var _value = snapTo(parseInt($left.get(0).style.left)+_handleWidth,_select.ticks).value;

              $left.attr('slidervalue',_value).find('.label').text(_value);
              $range.trigger('slider:change');
            }
          }
        }

        if($right.find('span.anchor').get(0).clicked)
        {
          if(parseInt(e.pageX-_offset) >= parseInt($right.attr('slidermin')) && parseInt(e.pageX-_offset) <= parseInt($right.attr('slidermax')))
          {
            if(parseInt(e.pageX-_offset) >= parseInt($left.css('left').replace('px',''))+_handleWidth)
            {
              $right.get(0).style.left = e.pageX-_offset+"px";

              var _value = snapTo($right.get(0).style.left,_select.ticks).value;

              $right.attr('slidervalue',_value).find('.label').text(_value);
              $range.trigger('slider:change');
            }
          }
        }
      });

      $handles.find('span.anchor').mousedown(function()
      {
        this.clicked = true;
      });

      $handles.find('span.anchor').bind('mouseup',function()
      {
        this.clicked = false;

        $handle = $(this).parent('span');
        var _side = ($handle.hasClass('left')) ? 'left' : 'right';
        var _snap = (_side == 'left') ? snapTo(parseInt($handle.get(0).style.left)+(_handleWidth-opts.tweaks.left),_select.ticks) : snapTo(parseInt($handle.get(0).style.left)-opts.tweaks.right,_select.ticks);

        if(_snap != null)
        {
          (_side == 'left') ? $handle.get(0).style.left = (_snap.pixel-(_handleWidth-opts.tweaks.left))+"px" : $handle.get(0).style.left = (_snap.pixel-opts.tweaks.right)+"px";

          $handle.attr('slidervalue',_snap.value).find('.label').text(_snap.value);

          $range.trigger('slider:change');
          $(opts.gridClassName).trigger('subcatgrid:filter');
        }
      });

      $range.bind('slider:change',function()
      {
        $range.css({left:parseInt($left.css('left'))+5,width:parseInt($right.css('left'))-parseInt($left.css('left'))});
      });

      $container.bind('slider:reset',function()
      {
        $left.attr('slidervalue',_min).css({left:-(_handleWidth-opts.tweaks.left)}).find('.label').text(_min);
        $right.attr('slidervalue',_max).css({left:_width-opts.tweaks.right}).find('.label').text(_max);

        $range.trigger('slider:change');
      });

      $container.click(function(e)
      {
        var _snap = snapTo(parseInt(e.pageX-opts.tweaks.margin),_select.ticks);

        if(_snap != null)
        {
          if(Math.abs(parseInt($left.css('left'))-_snap.pixel) <  Math.abs(parseInt($right.css('left'))-_snap.pixel))
          {
            $left.get(0).style.left = (_snap.pixel-(_handleWidth-opts.tweaks.left))+"px";
            $left.attr('slidervalue',_snap.value).find('.label').text(_snap.value);
          }
          else
          {
            $right.get(0).style.left = (_snap.pixel-opts.tweaks.right)+"px";
            $right.attr('slidervalue',_snap.value).find('.label').text(_snap.value);
          }

          $range.trigger('slider:change');
          $(opts.gridClassName).trigger('subcatgrid:filter');
        }
      });

      $select.bind('subcatgrid:restrict',function(event,data)
      {
      });
    });
  };

  function snapTo(left,ticks)
  {
    var _candidate = null;
    var _diff = Infinity;

    for(var i=0; i < ticks.length; i++)
    {
      if(Math.abs(ticks[i].pixel-parseInt(left)) < _diff)
      {
        _diff = Math.abs(ticks[i].pixel-parseInt(left));
        _candidate = ticks[i];
      }
    }

    return _candidate;
  };

  $.fn.slider.defaults =
  {
    gridClassName: '.subcategory-grid > ul',
    tweaks: {left:0,right:-1,margin:29+23}
  };

})(jQuery);


