/* stylage du scroll
********************************************************/	
var BOX = {};

(function($) {
    var W = this, D = this.document;
    var fnEmpty = function() {};
    var onloadIsDone = false;
    
    $(W).load(function() {
        onloadIsDone = true;
    });
    
    // for in filter
    var isOwnProperty = function(o, p) {
        return typeof o.constructor.prototype[p] == 'undefined';
    };
    
    BOX.isOwnProperty = isOwnProperty;
    
    // get IDs from HTML classes, eg. class="box:signOut"
    var getStoreId = function(el) {
        return (!el.className || el.className.indexOf('box:') == -1) ? null : el.className.replace(/[^:]+:(\S+).*/, '$1');
    };
    
    BOX.getStoreId = getStoreId;
    
    // extend a class
    BOX.extend = function(sb, sp, members) {
        function addToPrototype(o) {
            for (var m in o) {
                if (isOwnProperty(o, m)) {
                    sb.prototype[m] = o[m];
                }
            }
        }
        
        if (typeof sp == 'object') {
            addToPrototype(sp);
        } else {
            var F = function() {};
            F.prototype = sp.prototype;
            sb.prototype = new F();
            sb.prototype.constructor = sb;
            sb.superclass = sp.prototype;
            if (sp.prototype.constructor == Object.prototype.constructor) {
                sp.prototype.constructor = sp;
            }
            
            if (typeof members == 'object') {
                addToPrototype(members);
            }
        }
    };
    
    // Observable Class
    BOX.Observable = function() {
        this.listeners = {};
    };
    BOX.Observable.prototype = {
        addEvents: function(events, listeners) {
            for (var i = 0, len = events.length; i < len; i++) {
                this.listeners[events[i]] = [];
            }
            if (typeof listeners == 'object') {
                for (var l in listeners) {
                    if (isOwnProperty(listeners, l)) {
                        this.addListener(l, listeners[l].fn, listeners[l].scope);
                    }
                }
            }
        },
        
        fireEvent: function(eventName) {
            var ls = this.listeners[eventName], len, li, i = 0, args = [{type: eventName, target: this}];
            if (typeof eventName == 'string' && ls && (len = ls.length)) {
                if (arguments.length > 1) {
                    args = args.concat(Array.prototype.slice.call(arguments, 1));
                }
                for (; i < len; i++) {
                    li = ls[i];
                    li.fn.apply(li.scope, args);
                }
            }
        },
        
        addListener: function(eventName, fn, scope) {
            if (!this.listeners[eventName]) {
                this.listeners[eventName] = [];
            }
            scope = scope || this;
            if (this.hasListener(eventName, fn, scope) == -1) {
                this.listeners[eventName].push({fn: fn, scope: scope});
            }
            return this;
        },
        
        addListeners: function(listeners) {
            if (typeof listeners == 'object') {
                for (var l in listeners) {
                    if (isOwnProperty(listeners, l)) {
                        this.addListener(l, listeners[l].fn, listeners[l].scope);
                    }
                }
            }
            return this;
        },
        
        removeListener: function(eventName, fn, scope) {
            if (this.listeners[eventName]) {
                scope = scope || this;
                var i;
                if ((i = this.hasListener(eventName, fn, scope)) > -1) {
                    this.listeners[eventName].splice(i, 1);
                }
            }
            return this;
        },
        
        removeListeners: function(listeners) {
            if (typeof listeners == 'object') {
                for (var l in listeners) {
                    if (isOwnProperty(listeners, l)) {
                        this.removeListener(l, listeners[l].fn, listeners[l].scope);
                    }
                }
            }
            return this;
        },
        
        purgeListeners: function(eventName) {
            if (typeof eventName == 'string') {
                this.listeners[eventName] = [];
            } else {
                this.listeners = {};
            }
            return this;
        },
        
        hasListener: function(eventName, fn, scope) {
            scope = scope || this;
            var ls = this.listeners[eventName], len = ls.length, l, i = 0;
            for (; i < len; i++) {
                l = ls[i];
                if (l.fn == fn && l.scope == scope) {
                    return i;
                }
            }
            return -1;
        }
    };
    
    var config = {};
    
    // set configuration object
    var setConfig = function(target, datas) {
        if (!config[target]) {
            config[target] = {};
        }
        for (var p in datas) {
            if (isOwnProperty(datas, p)) {
                config[target][p] = datas[p];
            }
        }
    };
    
    BOX.setConfig = setConfig;
    
    // SimpleDrag Class
    var SimpleDrag = function(datas) {
        SimpleDrag.superclass.constructor.call(this);
        
        this.addEvents(['drag', 'start', 'end'], (datas) ? datas.listeners : null);
        
        this.initialize(datas);
    };
    BOX.extend(SimpleDrag, BOX.Observable, {
        initialize: function(datas) {
            var that = this;
            
            that.root = $(datas.root);
            that.handle = (datas.handle) ? $(datas.handle) : null;
            if (!that.handle || !that.handle.length) {that.handle = that.root;}
            
            that.setMinMax({
                minX: datas.minX,
                maxX: datas.maxX,
                minY: datas.minY,
                maxY: datas.maxX
            })
            that.sx = null;
            that.sy = null;
            
            that.handle.mousedown(function(e) {
                that.start(e);
            });
            $(D).mouseup(function(e) {
                that.end(e);
            });
        },
        
        setMinMax: function(datas) {
            if (typeof datas == 'object') {
                for (var p in datas) {
                    if (isOwnProperty(datas, p)) {
                        this[p] = datas[p];
                    }
                }
            }
            return this;
        },
        
        drag: function(e) {
            var y = e.pageY - this.sy, x = e.pageX - this.sx;
            if (this.minX !== undefined) {x = Math.max(x, this.minX);}
            if (this.maxX !== undefined) {x = Math.min(x, this.maxX);}
            if (this.minY !== undefined) {y = Math.max(y, this.minY);}
            if (this.maxY !== undefined) {y = Math.min(y, this.maxY);}
            this.root.css({
                'top': y +'px'
            });
            e.preventDefault();
            this.fireEvent('drag', x, y);
        },
        
        start: function(e) {
            var that = this;
            var y = parseInt(that.root.css('top'), 10) || 0;
            that.root.css('top', y + 'px');
            that.sy = e.pageY - y;
            $(D).bind('mousemove.simpleDrag', function(e) {
                that.drag(e);
            });
            e.preventDefault();
            that.fireEvent('start');
        },
        
        end: function(e) {
            this.fireEvent('end');
            $(D).unbind('mousemove.simpleDrag');
        }
    });
    
    BOX.SimpleDrag = SimpleDrag;
    
    // SimpleScroll Class
    var SimpleScroll = function(datas) {
        SimpleScroll.superclass.constructor.call(this);
        
        this.addEvents(['moved', 'disable', 'enable'], (datas) ? datas.listeners : null);
        
        this.initialize(datas);
    };
    BOX.extend(SimpleScroll, BOX.Observable, {
        initialize: function(datas) {
            var that = this;
            
            this.scrollUnit = (typeof datas.scrollUnit == 'number') ? datas.scrollUnit : null;
            this.postOnLoadCompute = false;
            
            datas.target.innerHTML = config.scroll.container.replace('%content%', datas.target.innerHTML);
            
            this.sParent = $(datas.target);
            this.sContent = this.sParent.children();
            
            if (datas.buttons) {
                this.sContainer = $(config.scroll.fullBar).appendTo(datas.target);
                this.sUp = $('span.up', this.sContainer);
                this.sDown = $('span.down', this.sContainer);
            } else {
                this.sContainer = $(config.scroll.simpleBar).appendTo(datas.target);
            }
            this.sFace = $('span.face', this.sContainer);
            
            this.drag = new SimpleDrag({
                root: this.sFace,
                minX: 0,
                maxX: 0,
                minY: 0
            }).addListener('drag', function(e, x, y) {
                if (y == Math.round(that.sD)) {
                    y = that.sD;
                }
                var tTop = Math.round(y / that.sH * that.tH);
                that.sContent.css('top', - tTop + 'px');
            });
	  
            this.compute();
            if ($('img', this.sParent).length && !onloadIsDone) {
                $(W).load(function() {
                    that.postOnLoadCompute = true;
                    that.compute();
                });
            }
            
            this.sParent.bind('DOMMouseScroll', function(e) {that.wheel(e);}).bind('mousewheel', function(e) {that.wheel(e);});
            this.sContainer.click(function(e) {that.clickToPosition(e, this);});
            
            this.fireEvent('load');
        },
        
        checkForDisplayNone: function(el) {
            if (el) {
                if (!el.scrollHeight) {
                    this.displayNone = $(el.parentNode);
                    while (this.displayNone.parent().css('display') == 'none') {
                        this.displayNone = this.displayNone.parent();
                    }
                    this.displayNone.addClass('hideButDraw');
                }
            } else if (this.displayNone) {
                this.displayNone.removeClass('hideButDraw');
            }
        },
        
        enable: function() {
            this.sContent.removeClass('scrollNone').addClass('scrollContent');
            this.drag.setMinMax({maxY: Math.round(this.sD)});
            var tTop = parseInt(this.sContent.css('top'), 10);
            this.moveContentTo(tTop);
            this.disabled = false;
            this.fireEvent('enable');
            this.sContainer.css('visibility', 'visible');
	  //this.sContainer.css('display', 'block');
        },
        
        disable: function() {
            this.sContainer.css('visibility', 'hidden');
	 //this.sContainer.css('display', 'none');
            this.sContent.removeClass('scrollContent').addClass('scrollNone');
            this.disabled = true;
            this.fireEvent('disable');
        },
        
        compute: function() {
            this.checkForDisplayNone(this.sContent[0]);
            this.tH = this.sContent[0].scrollHeight;
            this.th = this.sParent[0].offsetHeight;
            this.tD = this.tH - this.th;


            this.sH = this.sContainer[0].offsetHeight;
            if (this.tH <= this.th) {
                this.sh = this.sH;
            } else {
                this.sh = this.th / this.tH * this.sH;
            }
            
            this.sD = this.sH - this.sh;
            this.sD = Math.round(this.sD)
			
            if (!this.scrollUnit) {
                var unit = Math.ceil((this.sH - this.sh) / this.sH * this.sh);
                this.scrollUnit = (unit > 10) ? unit : 10;
            }
            //TODO gérer les hauteurs de scroll si hFace<30
            this.sFaceOffset = this.sFace[0].offsetHeight - this.sFace.height();
			var hFace = (Math.round(this.sh) - this.sFaceOffset - 4);
			
			if($('#dispatch').length > 0) {
			    if(hFace<30){hFace = 30;}
			}
			
			this.sFace.css('height', hFace + 'px');
            this.offset = this.sContainer.offset().top;
            
            if (this.tH <= this.th) {
                this.disable();
            } else {
                this.enable();
            }
            
            this.checkForDisplayNone();
        },
        
        moveContentTo: function(tTop) {
            if (!this.disabled && !isNaN(tTop)) {
                if (tTop > 0) {tTop = 0;}
                if (tTop < - this.tD) {tTop = - this.tD;}
                var sTop = Math.round(Math.abs(tTop) / this.tH * this.sH);
                this.sContent.css('top', tTop + 'px');
                this.sFace.css('top', sTop + 'px');
            }
        },
        
        moveScrollBarTo: function(sTop) {
            if (!this.disabled && !isNaN(sTop)) {
                if (sTop < 0) {sTop = 0;}
                if (sTop > this.sD) {sTop = Math.round(this.sD);}
                var tTop = - Math.round(sTop / this.sH * this.tH);
                this.sContent.css('top', tTop + 'px');
                this.sFace.css('top', sTop + 'px');
            }
        },
        
        wheel: function(e) {
            if (!this.disabled) {
                var s = (e.detail)? -(e.detail) / 3 : e.wheelDelta / 120;
                var tTop = Math.round(parseInt(this.sContent.css('top'), 10) + (s * this.scrollUnit));
                this.moveContentTo(tTop);
                e.preventDefault();
            }
        },
        
        clickToPosition: function(e, el) {
            var t = e.target,
                sTop, tTop;
            if (t == el) {
                sTop = e.pageY - this.offset - Math.round(this.sh / 2);
                this.moveScrollBarTo(sTop);
            } else if ($(t).hasClass('up')) {
                tTop = Math.round(parseInt(this.sContent.css('top'), 10) + this.scrollUnit);
                this.moveContentTo(tTop);
            } else if ($(t).hasClass('down')) {
                tTop = Math.round(parseInt(this.sContent.css('top'), 10) - this.scrollUnit);
                this.moveContentTo(tTop);
            }
        }
    });
    
    BOX.SimpleScroll = SimpleScroll;
    
})(jQuery);


/* initialisation du scroll
********************************************************/	
       
      $('html').attr('id', 'js');

        BOX.setConfig('scroll', {
            container: '<div class="scrollContent">%content%</div>',
            simpleBar: '<div class="scrollBar" style="visibility:hidden;" id="scrollbar"><span class="face"><img src="/templates/general/img/bgFaceScrollTop.gif" alt=""  class="top" /><span class="faceScrollCenterContainer"><img src="/templates/general/img/bgFaceScrollCenter.gif" alt="" class="center" /></span><img src="/templates/general/img/bgFaceScrollBottom.gif" alt="" class="bottom" /></span></div>',
            fullBar: '<div class="scrollBar" style="visibility:hidden;"><span class="up"></span><span class="face"></span><span class="down"></span></div>'
        });
        
        var scrollsCache = {};
		var scrollGuid = 0;
        
	function addScrollToContainer(root){
		$('.scroll', root || document).each(function(){
			if($('div.scrollBar', this).length === 0) {
				var id = BOX.getStoreId(this) || 'scroll' + (++scrollGuid);
				$(this).addClass('box:' + id);
				scrollsCache[id] = new BOX.SimpleScroll({
					target: this,
					buttons: false
				});
			}
		});
		// next block not present in production env.
		/*$('.scrollnews', root || document).each(function(){
			var id = BOX.getStoreId(this) || 'scroll' + (++scrollGuid);
			$(this).addClass('box:' + id);
			scrollsCache[id] = new BOX.SimpleScroll({
				target: this,
				buttons: false
			});
		});*/
	}
	
/********************************************************/	
