/**
 * Copyright (c) 2010 Sylvain Gougouzian (sylvain@gougouzian.fr) MIT
 * (http://www.opensource.org/licenses/mit-license.php) licensed. GNU GPL
 * (http://www.gnu.org/licenses/gpl.html) licensed.
 *
 * jQuery scrollBar by Sylvain Gougouzian http://sylvain.gougouzian.fr
 *
 * Version: 0.1
 *
 * Requires: jQuery 1.3.2+ // http://www.jquery.com
 *
 * Compatible : Internet Explorer 6+, Firefox 1.5+, Safari 3+, Opera 9+, Chrome
 * 0.9+
 */
jQuery(function($){
    $.fn.scrollbar = function(options){
        var el = this.eq(0).data("scrollbar");
        var opts = $.extend({}, $.fn.scrollbar.defaults, options);
        this.each(function(){
            el = new $scrollbar(this, opts);
        });
        return opts.api ? el : null;
    };
    
    $.scrollbar = function(e, opts){
        this.opts = opts;
        this.previousMousePos = -1;
        this.texte = $(e);
        this.wt = this.texte.parent().width();
		this.wh = this.texte.parent().height();
		var w = parseInt(opts.width);
        this.texte.width(this.wt - 5 - (parseInt(this.texte.parent().css('padding-right')) + w)).height('auto').css({
            'overflow': 'visible',
            'position': 'absolute',
            'top': '0px',
            'padding-right': '5px'
        }).wrap('<div></div>');
        this.th = parseInt(this.texte.height());
        this.container = this.texte.parent();
        this.container.addClass('jScrollPaneContainer').width(this.wt).height(this.wh);
        this.id = this.texte.attr('id');
        var scrollbar = '<div class="jScrollCap jScrollCapTop" style="height:0px;"></div><div id="' + this.id + '_scrollAbg" class="jScrollPaneTrack"><div class="bgMainWrapper"><div id="' + this.id + '_scrollAsc" class="jScrollPaneDrag"><div class="bgWrapper"></div></div></div></div><div class="jScrollCap jScrollCapBottom" style="height:0px;"></div><a id="' + this.id + '_scrollup" class="jScrollArrowUp" style="width: ' + w + 'px; top: 0px;" href="#"><span class="bgWrapper">' + opts.textUp + '</span></a><a id="' + this.id + '_scrolldown" class="jScrollArrowDown" style="width: ' + w + 'px; bottom: 0px;" href="#"><span class="bgWrapper">' + opts.textDown + '</span></a>';
        this.container.append(scrollbar);
        this.scrollbar = $('.jScrollPaneTrack', this.container);
        this.scrollbar.width(w).height(this.wh - (2 * parseInt(this.opts.arrowHeight))).css('top', this.opts.arrowHeight);
		this.sh = parseInt(this.scrollbar.height());
		this.asc = $('.jScrollPaneDrag', this.scrollbar);
        this.asc.width(w).css('top', '0px');
        this._init();
    };
    
    var $scrollbar = $.scrollbar;
    
    $scrollbar.fn = $scrollbar.prototype = {
        scrollbar: '0.1'
    };
    
    $scrollbar.fn.extend = $scrollbar.extend = $.extend;
    
    $scrollbar.fn.extend({
        _init: function(){
            var self = this;
            if ($('img', this.texte).length > 0) {
                $('img', this.texte).each(function (i) {
					$(this).load(function(){
						if (i == ($('img', self.texte).length - 1))
                    		self.recalcHeight();
					});
                });
            }
            else {
                this.recalcHeight();
	        }
            this.asc.bind('mousedown', function(e){
				self.startDrag(e);
            });
            $(document).bind('mouseup', function(){
                self.previousMousePos = null;
                self.endDrag();
            });
            $(this.container).bind('mousewheel', function(event, delta){
                var dir = delta > 0 ? 'Up' : 'Down';
                if (dir == 'Up') {
                    self.up();
                }
                else {
                    self.down();
                }
                return false;
            });
            $("#" + this.id + "_scrollup").click(function(){
                self.up();
                return false;
            });
            $("#" + this.id + "_scrolldown").click(function(){
                self.down();
                return false;
            });
			$('a', $(this.texte)).each(function () {
				$(this).click(function () {
					var h = $(this).attr('href');
					if (h && h.substr(0, 1) == '#' && h.length > 1) {
						setTimeout(function() {
							self.moveTo(h);
						}, $.browser.safari ? 100 : 0);
						return false;
					}
				});
			});
        },
		recalcHeight: function () {
			this.calcHeight();
			this.hashMove();
		},
		redraw: function (th) {
			if (th != undefined)
				this.th = th;
			this.recalcHeight();
			this.moveTo(0);
		},
		hashMove: function () {
			var self = this;
			if (location.hash && location.hash.length > 1) {
				setTimeout(function() { self.moveTo(location.hash); }, $.browser.safari ? 100 : 0);
			}
		},
        calcHeight: function(){
            var h = (this.wh * this.sh) / this.th;
			if (h > this.sh) h = this.sh;
			this.asc.height(h);
        },
        calcTextScroll: function(s){
            return (s * this.th) / this.sh;
        },
		calcDragScroll: function (s) {
			return ((s * (this.sh - parseInt(this.asc.height()))) / (this.th - this.wh));
		},
        down: function(move){
			var s = parseInt((move == undefined ? this.opts.scrollPadding : move));
			this.asc.css('top', this.downScroll(s) + 'px');
            this.texte.css('top', this.downText(s) + 'px');
        },
		downScroll: function (s) {
			var d = parseInt(this.asc.css('top')) + s;
            if ((d + parseInt(this.asc.height())) > this.sh) 
                d = this.sh - parseInt(this.asc.height());
			return d;
		},
		downText: function (s) {
			var dt = parseInt(this.texte.css('top')) - parseInt(this.calcTextScroll(s));
            if (dt < (0 - (this.th - this.wh))) 
                dt = 0 - (this.th - this.wh);
            return dt;
		},
        up: function(move){
            var s = parseInt((move == undefined ? this.opts.scrollPadding : move));
			this.asc.css('top', this.upScroll(s) + 'px');
            this.texte.css('top', this.upText(s) + 'px');
        },
		upScroll: function (s) {
			var d = parseInt(this.asc.css('top')) - s;
			return (d < 0 ? 0 : d);
		},
		upText: function (s) {
			var d = parseInt(this.texte.css('top')) + parseInt(this.calcTextScroll(s));
            return (d > 0 ? 0 : d);
		},
        startDrag: function(event){
            var self = this;
            this.previousMousePos = event.clientY;
            this.container.bind('mousemove', function(e){
                self.move(e);
            });
        },
        move: function(event){
            if (this.previousMousePos > event.clientY) {
                this.up(this.previousMousePos - event.clientY);
            }
            else {
                this.down(event.clientY - this.previousMousePos);
            }
            this.previousMousePos = event.clientY;
        },
		endDrag: function(){
            this.container.unbind('mousemove');
        },
		moveTo: function(pos) {
			if (typeof pos == "string") {
				$e = $(pos, this.texte);
				if (!$e.length) return;
				pos = $e.offset().top - this.texte.offset().top;
			}
			pos = parseInt(pos);
			this.asc.css('top', this.calcDragScroll(pos) + 'px');
			this.texte.css('top', 0 - pos + 'px');
		}
    });
    $.fn.scrollbar.defaults = {
        width: '14px',
        arrowHeight: '11px',
        scrollPadding: '15px',
        textUp: ' ',
        textDown: ' ',
        api: false
    };
});