/* Version modifiée de la Class "Scroller" de mootools pour permettre l'ajout de zone en dehors de la div 'scroll' */

var OuterScroller = new Class({

	options: {
		area: 20,
		addarea: 0,
		outArea: {
			type : 'V' ,
			width : null,
			height : null
		},
		velocity: 1,
		onChange: function(x, y){
			this.element.scrollTo(x, y);
		},
		always: 0,
		runVelocity: null
		
	},

	initialize: function(element, options){
		this.setOptions(options);
		this.element = $(element);
		this.mousemover = ([window, document].contains(element)) ? $(document.body) : this.element;
		if(this.element.offsetHeight>=$('insidemove').offsetHeight){
			this.options.always=0;
			this.options.runVelocity=null;
		}
		if (this.options.outArea.type=='H'){
			this.cel = this.element.getElements( 'div' );
			this.child=$(this.cel[0].id);
			this.childs = this.child.getElements('div');
			var totwidth =0; 
			for(i=0;i<=(this.childs.length-1);i++){
				var child1 = this.childs[i];
				totwidth+=child1.getSize().size.x;
			}
			this.child.setAttribute('width',totwidth);
		}
		if (this.options.addarea==1){
			this.addOutArea(this);
		}
		if (this.options.always==1){
			if (this.options.runVelocity==null)
				this.options.runVelocity=this.options.velocity;
			this.createLoop();
			this.start4();
		}
	},
	
	
	
	start: function(){
		this.coord = this.getCoords.bindWithEvent(this);
		this.mousemover.addListener('mousemove', this.coord);
	},

	start2: function(){
		this.startUp = this.initStart2.bindWithEvent(this);
		this.dmu.addListener('mousemove', this.startUp);
	},
	initStart2: function(){
		if (this.timer) this.timer = $clear(this.timer);
		if (this.timer3) this.timer3 = $clear(this.timer3);
		if (this.timer4) this.timer4 = $clear(this.timer4);
		if (!this.timer2) this.timer2 = this.scrollUp.periodical(50, this);
	},
	
	start3: function(){
		this.startDown = this.initStart3.bindWithEvent(this);
		this.dmd.addListener('mousemove', this.startDown);
	},
	initStart3: function(){
		if (this.timer) this.timer = $clear(this.timer);
		if (this.timer2) this.timer2 = $clear(this.timer2);
		if (this.timer4) this.timer4 = $clear(this.timer4);
		if (!this.timer3) this.timer3 = this.scrollDown.periodical(50, this);
	},

	start4: function(){
		if (this.timer) this.timer = $clear(this.timer);
		if (this.timer2) this.timer2 = $clear(this.timer2);
		if (this.timer3) this.timer3 = $clear(this.timer3);
		if (!this.timer4) this.timer4 = this.runScroll.periodical(50, this);
	},

	stop: function(){
		this.mousemover.removeListener('mousemove', this.coord);
		this.timer = $clear(this.timer);
			this.start4();
	},
	stop2: function(){
		this.timer2 = $clear(this.timer2);
			this.start4();
	},
	stop3: function(){
		this.timer3 = $clear(this.timer3);
		this.start4();
	},
	getCoords: function(event){
		this.page = (this.element == window) ? event.client : event.page;
		if (this.timer2) this.timer2 = $clear(this.timer2);
		if (this.timer3) this.timer3 = $clear(this.timer3);
		if (this.timer4) this.timer4 = $clear(this.timer4);
		if (!this.timer) this.timer = this.scroll.periodical(50, this);
	},
	
	checkBefore: function(direction){
		var el = this.element.getSize();
		var Ymax = this.element.getSize().scrollSize.y-this.element.getSize().size.y;
		var Xmax = this.element.getSize().scrollSize.x-this.element.getSize().size.x;
			if (this.options.outArea.type=='H'){
				if (el.scroll.x==0){
					var scrollto = this.elementContenor.childNodes[0].getSize().size.x;
					this.element.scrollTo(scrollto,0);
					this.elementChild1=this.elementChildCC.clone();
					this.elementContenor.setStyle('width',(this.elementContenor.childNodes[0].getSize().size.x)*2+'px');
					if (this.elementContenor.childNodes.length>1)
						if (this.elementContenor.childNodes[1] )
							this.elementContenor.childNodes[1].remove();
					this.elementChild1.injectBefore(this.elementContenor.childNodes[0]);
				}
				if (el.scroll.x==Xmax){
					var scrollto = this.element.getSize().scroll.x-this.elementContenor.childNodes[0].getSize().size.x;
					this.element.scrollTo(scrollto,0);
					this.elementContenor.setStyle('width',(this.elementContenor.childNodes[0].getSize().size.x)*2+'px');
					if (this.elementContenor.childNodes.length>1)
						if (this.elementContenor.childNodes[0] )
							this.elementContenor.childNodes[0].remove();
					this.elementChild1=this.elementChildCC.clone();
					this.elementChild1.injectAfter(this.elementContenor.childNodes[0]);
				}
			}else{
				if (el.scroll.y==0){
					var scrollto = this.elementContenor.childNodes[0].getSize().size.y;
					this.element.scrollTo(0,scrollto);
					this.elementChild1=this.elementChildCC.clone();
					if (this.elementContenor.childNodes.length>1)
						if (this.elementContenor.childNodes[1] )
							this.elementContenor.childNodes[1].remove();
					this.elementChild1.injectBefore(this.elementContenor.childNodes[0]);
				}
				if (el.scroll.y==Ymax){
					var scrollto = this.element.getSize().scroll.y-this.elementContenor.childNodes[0].getSize().size.y;
					this.element.scrollTo(0,scrollto);
					if (this.elementContenor.childNodes.length>1)
						if (this.elementContenor.childNodes[0] )
							this.elementContenor.childNodes[0].remove();
					this.elementChild1=this.elementChildCC.clone();
					this.elementChild1.injectAfter(this.elementContenor.childNodes[0]);
				}
			}
	},
	
	createLoop: function(){
			this.cel = this.element.getElements( 'div' );
			this.elementContenor=$(this.cel[0].id);
			this.spacer = new Element('div');
			this.spacer.setStyle('clear','both');
			this.element.appendChild(this.spacer);
			this.elementChild = this.elementContenor.clone();
			this.elementChild.setStyle('float','left');
			this.elementChildCC = this.elementChild.clone();
			this.elementContenor.empty();
			this.elementContenor.appendChild(this.elementChild);
	},
	
	runScroll: function(){
		if (this.options.always==1)
			this.checkBefore('down');
		var el = this.element.getSize();
		var Ymax = this.element.getSize().scrollSize.y-parseInt(this.element.getStyle('height'));
		var Xmax = this.element.getSize().scrollSize.x-parseInt(this.element.getStyle('width'));
		if (this.options.outArea.type=='H'){
			if (el.scroll.x<Xmax){
				el.scroll.x+=this.options.velocity*this.options.runVelocity;
				if (el.scroll.x<Xmax)
					this.element.scrollTo(el.scroll.x,0);
				else
					this.element.scrollTo(Xmax,0);
			}
		}else{
			if (el.scroll.y<Ymax){
				el.scroll.y+=this.options.velocity*this.options.runVelocity;
				if (el.scroll.y<Ymax)
					this.element.scrollTo(0,el.scroll.y);
				else
					this.element.scrollTo(0,Ymax);
			}
		}
	},
	
	
	
	scrollUp: function(){
		if (this.options.always==1)
			this.checkBefore('up');
		var el = this.element.getSize();
		var Ymax = this.element.getSize().scrollSize.y-parseInt(this.element.getStyle('height'));
		var Xmax = this.element.getSize().scrollSize.x-parseInt(this.element.getStyle('width'));
		if (this.options.outAreaType=='H'){
			if (el.scroll.x<Xmax){
				el.scroll.x-=this.options.velocity*this.options.area;
				if (el.scroll.x<Xmax)
					this.element.scrollTo(el.scroll.x,0);
				else
					this.element.scrollTo(0,0);
			}
		}else{
			if (el.scroll.y>0){
				el.scroll.y-=this.options.velocity*this.options.area;
				if (el.scroll.y>0)
					this.element.scrollTo(0,el.scroll.y);
				else
					this.element.scrollTo(0,0);
			}
		}
	},
	
	scrollDown: function(){
		if (this.options.always==1)
			this.checkBefore('down');
		var el = this.element.getSize();
		var Ymax = this.element.getSize().scrollSize.y-parseInt(this.element.getStyle('height'));
		var Xmax = this.element.getSize().scrollSize.x-parseInt(this.element.getStyle('width'));
		if (this.options.outArea.type=='H'){
			if (el.scroll.x<Xmax){
				el.scroll.x+=this.options.velocity*this.options.area;
				if (el.scroll.x<Xmax)
					this.element.scrollTo(el.scroll.x,0);
				else
					this.element.scrollTo(Xmax,0);
			}
		}else{
			if (el.scroll.y<Ymax){
				el.scroll.y+=this.options.velocity*this.options.area;
				if (el.scroll.y<Ymax)
					this.element.scrollTo(0,el.scroll.y);
				else
					this.element.scrollTo(0,Ymax);
			}
		}
		
	},
	
	scroll: function(){
		if (this.options.always==1)
			this.checkBefore();
		var el = this.element.getSize();
		var pos = this.element.getPosition();

		var change = {'x': 0, 'y': 0};
		for (var z in this.page){
			if (this.page[z] < (this.options.area + pos[z]) && el.scroll[z] != 0)
				change[z] = (this.page[z] - this.options.area - pos[z]) * this.options.velocity;
			else if (this.page[z] + this.options.area > (el.size[z] + pos[z]) && el.scroll[z] + el.size[z] != el.scrollSize[z])
				change[z] = (this.page[z] - el.size[z] + this.options.area - pos[z]) * this.options.velocity;
		}
		if (change.y || change.x) this.fireEvent('onChange', [el.scroll.x + change.x, el.scroll.y + change.y]);
	},
	
	addOutArea: function(){
		var parentElement = this.element.getParent(); 
		//alert('pe '+parentElement.id);
		switch (this.options.outArea.type){
			case 'H': 
				if (this.options.outArea.width==null)
					this.options.outArea.width=20;
				if (this.options.outArea.height==null)
					this.options.outArea.height=this.element.offsetHeight;
				break;
			case 'V':
			default : 
				if (this.options.outArea.width==null)
					this.options.outArea.width=this.element.offsetWidth+40;
				if (this.options.outArea.height==null)
					this.options.outArea.height=20;
				break;
		}
		this.options.outArea.width=parseInt(this.options.outArea.width);
		this.options.outArea.height=parseInt(this.options.outArea.height);
		if (!($('upmouse'))){
			this.dmu = new Element('div',{
				'id':'upmouse',
				'styles':{
					'position': 'absolute', 
					'width': this.options.outArea.width+'px', 
					'height':  this.options.outArea.height+'px'
				},
				'events':{
					'mouseenter':this.start2.bindWithEvent(this),
					'mouseleave':this.stop2.bindWithEvent(this)
				}
			});
			if (this.options.outArea.type=='H') {
				 this.dmu.setStyles({
				 	'top' : this.element.getTop()+'px',
				 	'left' : this.element.getLeft()-this.options.outArea.width+'px'
				 });
			} else {
				 this.dmu.setStyles({
				 	'margin-top' : '-'+this.options.outArea.height+'px'
				 });
			}
			this.dmu.injectBefore(this.element.id);
		}else{
			this.dmd = $('upmouse');
			this.dmd.addEvents({
				'mouseenter':this.start3.bindWithEvent(this),
				'mouseleave':this.stop3.bindWithEvent(this)
			});
		}
		if (!($('downmouse'))){
			this.dmd = new Element('div',{
				'id':'downmouse',
				'styles':{
					'position': 'absolute', 
					'width': this.options.outArea.width+'px', 
					'height':  this.options.outArea.height+'px'
				},
				'events':{
					'mouseenter':this.start3.bindWithEvent(this),
					'mouseleave':this.stop3.bindWithEvent(this)
				}
			});
			if (this.options.outArea.type=='H') {
				 this.dmd.setStyles({
				 	'top' : this.element.getTop()+'px',
				 	'left' : this.element.getLeft()+this.element.getSize().size.x+'px'
				 });
			} 
			this.dmd.injectAfter(this.element.id);
		}else{
			this.dmd = $('downmouse');			this.dmd.addEvents({
				'mouseenter':this.start3.bindWithEvent(this),
				'mouseleave':this.stop3.bindWithEvent(this)
			});
		}
	}
});

OuterScroller.implement(new Events, new Options);