(function($) {
    var ua = navigator.userAgent.toLowerCase();
    isWebkit = !!ua.match(/applewebkit/i);
    var supportsTouch = false;
    try {
        document.createEvent("TouchEvent");
        supportsTouch = true;
    } catch (e) {}

    var bindHere = function(fn, me) { 
      return function() { 
        return fn.apply(me, arguments); 
      }; 
    };

    var cssWithoutUnit = function(element, attribute) {
    var measure = element.css(attribute);
      return (measure !== undefined) ? parseInt(measure.replace('px', ''), 10) : 0;
    };

    var Position = function(x, y) {
        if (x && x.hasOwnProperty('x') && x.hasOwnProperty('y')) {
            x = x.x;
            y = x.y;
        }
        this.x = x;
        this.y = y;
    };
    Position.prototype = {
        difference: function(p) {
            return new Position(p.x - this.x, p.y - this.y);
        }
    };
            
    var Slider = function(settings)
    {
        $(window).load(function() {
            Slider.loaded(); 
        });
    
        return this.each(function() {
            Slider.init($(this));
            if (!supportsTouch) {
                Slider.args.loadTimers = setInterval(Slider.update, 1000);
            }
        });
    };
    
    Slider.args = {
        loaded: false
    };
    
    Slider.init = function($scrollObj)
    {
        var self = this;

        $scrollObj.wrap($('<div></div>').attr({'className':'slider-container'}));
        
        this.objs                 = {};     
        this.objs.scroll          = $scrollObj.css({overflow: 'visible', left: 0});
        this.objs.sliderContainer = $('.slider-container');
        
        this.setDimensions();
        this.initScrollbars();

        if (supportsTouch) {
          var touch = new TouchSlider();
          touch.init(this.objs.sliderContainer.selector + ' table', {tossing: true});
          touch.bind('slide', function(slider) {
            var maxLeft  = self.objs.sliderTrackX.width() - self.objs.drag.width();
            var ratio = self.objs.sliderTrackX.width() / slider.containerWidth();
            var left = -slider.position.x * ratio;
            self.objs.drag.css('left', left + 'px');    
          });
        } else {
          $(window).load(function() {
              Slider.update($scrollObj);          
          });

          $(window).resize(function() {
              Slider.update($scrollObj);
          });
        
          this.objs.sliderContainer.bind('mousewheel', bindHere(MouseEvents.mousewheel, this));
        }
    };
    
    Slider.setDimensions = function()
    {
        if (!this.dims)
        {
            this.dims = {}; 
        }
        
        if (!this.objs)
        {
            return false;
        }                
        
        // Width of container
        this.dims.containerWidth = this.objs.sliderContainer.innerWidth();

        // Width of content
        if (this.objs.scroll.attr('tagName') != 'TABLE')
        {
            this.objs.scroll.css({overflow:"hidden"});  
        }
        
        this.dims.contentWidth = this.objs.scroll.attr('scrollWidth');

        this.objs.scroll.css({overflow:"hidden"});
        
        if ($.browser.msie && $.browser.version.substr(0,1) < 8)
        {
            if (this.dims.contentWidth == this.dims.containerWidth && this.dims.containerWidth > $(window).width())
            {
                this.objs.sliderContainer.css('width', $(window).width());
            }
        }
        
        // Percent of content in view
        this.dims.percentInViewX = this.dims.containerWidth / this.dims.contentWidth;

        // Width of drag button
        this.dims.dragButtonWidth   = this.dims.containerWidth * this.dims.percentInViewX;
        this.dims.dragButtonPercent = this.dims.percentInViewX * 100;
    };

    Slider.initScrollbars = function()
    {
        this.objs.sliderTrack = this.objs.sliderContainer.find('.slider-track:first');
        if (this.dims.percentInViewX < 0.99) {
            this.addScrollbar();
            this.setScrollDimensions();
        } else {
            this.removeScrollbar();
        }
    };
    
    Slider.addScrollbar = function()
    {
        if (this.objs.sliderTrack.length <= 0)
        {
            var slider = $('<div/>', {
                'id': 'slider',
                'className': 'slider-track'
            });
            var sliderTrackX = $('<div/>', {
               'className': 'slider-track-x' 
            });
            var handle = $('<div/>', {
                'id': 'handle',
                'className': 'slider-drag'
            }).css('left', 0);

            this.objs.sliderContainer.append(slider.append(sliderTrackX.append(handle)));
            
            this.objs.sliderTrack  = slider;
            this.objs.sliderTrackX = sliderTrackX;
            this.objs.drag         = handle;

            this.objs.sliderTrackX.bind('mousedown', bindHere(MouseEvents.mousedown, this));
            
            if ($('#customize_iframe').length > 0)
            {
                var iframeTop = $('#customize_iframe').css('top').replace('px', '')*1;
                var iframeOffset = this.objs.sliderTrack.attr('offsetHeight');
                $('#customize_iframe').css('top', iframeTop+iframeOffset);
            }
        }
    };

    Slider.removeScrollbar = function()
    {
        if (this.objs.sliderTrack.length > 0)
        {
            if ($('#customize_iframe').length > 0)
            {
                var iframeTop = $('#customize_iframe').css('top').replace('px', '')*1;
                var iframeOffset = this.objs.sliderTrack.attr('offsetHeight');
                $('#customize_iframe').css('top', iframeTop-iframeOffset);              
            }
            
            this.objs.scroll.css({left: 0});
            this.objs.sliderTrack.remove();     
        }
    };

    Slider.setScrollDimensions = function()
    {
        var dragCss = {width: this.dims.dragButtonPercent+'%', position: 'relative'};           
        this.objs.drag.css(dragCss);        
    };
    
    Slider.adjustScroll = function()
    {
        var dragLeft     = this.objs.drag.css('left').replace('px','')*1;
        var adjustOffset = dragLeft+this.objs.drag.width();

        if (adjustOffset > this.objs.sliderTrackX.width())
        {               
            dragLeft = this.objs.sliderTrackX.width() - this.objs.drag.width();
            this.objs.drag.css({left: dragLeft+'px'});
        }

        var scrollWidth = this.dims.contentWidth - this.dims.containerWidth;
        var maxLeft     = this.objs.sliderTrackX.width() - this.objs.drag.width();
        
        var scrollPercent = maxLeft/dragLeft;
        var scrollLeft    = -scrollWidth/scrollPercent;

        this.objs.scroll.css({left: scrollLeft+'px'});
    };
    
    Slider.update = function()
    {
        // window.console.log('update');
        // Calculate dimensions
        if (this.objs)
        {
            this.setDimensions();   
            this.initScrollbars();
        }

        if (this.objs && this.objs.drag)
        {
            // Update scrollbar dimensions
            this.setScrollDimensions();
            this.adjustScroll();            
        }
    };
    
    Slider.loaded = function()
    {
        clearInterval(this.args.loadTimers);
        this.args.loadTimers = false;
        delete this.args.loadTimers;
        
        this.args.loaded = true;

        if (this.objs && this.objs.sliderContainer)
        {
            this.update();  
        }
    };

    var MouseEvents = {
        mousedown: function(e) {
            $drag = this.objs.drag;
            
            this.startX = e.pageX
            this.startY = e.pageY;
            this.offset = this.objs.drag.css('left').replace('px','')*1;
            this.position   = this.objs.drag.css('left').replace('px','')*1;
            this.maxLeft  = this.objs.sliderTrackX.width() - this.objs.drag.width();

            if (e.target != this.objs.drag.get(0))
            {
                var clickOffset = this.objs.sliderTrackX.offset();
                var offsetPercent = (this.startX - clickOffset.left) / this.objs.sliderTrackX.width();
                $drag.css('left', this.maxLeft*offsetPercent + 'px');    
                Slider.adjustScroll();
                
                this.offset = this.maxLeft*offsetPercent;
            }
            
            var self = this;
            $(document).bind('mousemove', function(e) {
                return MouseEvents.mousemove.call(self, e);
            });
            $(document).bind('mouseup', function(e) {
                $(document).unbind('mousemove');
                $(document).unbind('mouseup');
            });

            return false;
        },

        mousemove: function(e) {
            var left = this.offset - (this.startX - e.pageX);

            if (left < 0)
            {
                left = 0;
            }
            else if (left > this.maxLeft)
            {
                left = this.maxLeft;
            }
            
            Slider.adjustScroll();
            this.objs.drag.css({left: left+'px'});   
        },

        mousewheel: function(e, delta, deltaX, deltaY) {
            if (this.objs && this.objs.drag)
            {
                var offsetLeft = this.objs.drag.css('left').replace('px','')*1;
                var maxLeft    = this.objs.sliderTrackX.width()-this.objs.drag.width();
                var dragLeft   = offsetLeft+deltaX;

                if (dragLeft < 0)
                {
                    dragLeft = 0;
                }
                else if (dragLeft > maxLeft)
                {
                    dragLeft = maxLeft;
                }

                Slider.adjustScroll();
                this.objs.drag.css({left: dragLeft+'px'});      
            }       
        }
    };

 
    window.lucie.$.fn.slider = Slider;
})(lucie.$);
