function create_from_src(src) {
	var tmpdiv=document.createElement("div");
	tmpdiv.innerHTML=src;
	return tmpdiv.childNodes[0] || null;
}

function create_span_from_src(src) {
	var tmpdiv=document.createElement("span");
	tmpdiv.innerHTML=src;
	return tmpdiv;
}
function stylyze(obj,src) {
	var tmpdiv=create_from_src("<span style=\""+src+"\"></span>");
	for(var att in tmpdiv.style){
		var o=tmpdiv.style[att];
		if ((typeof(o)!="object") && (typeof(o))!="function") {
			try
			{
				obj.style[att]=o;
			}
			catch (e){}
		}
	}
	return tmpdiv;
}

function dscrollpane(id,width,height,helem) {
	//test conflit d'id interne et externe
	if(dscrollpane.insts[id] || document.getElementById(id)) {
		alert("conflit d'id de scrollpane : "+id);
		return;
	}
	//met la nouvelle instance dans objet static
	this.id=id;
	dscrollpane.insts[id]=this;
	//
	this.eventDisabled=false;
	//
	this.scrollheight=18;
	this.minsize=this.scrollheight*4;
	this.scrollincr=20;
	//
	if (!width) this._width=this.scrollheight*4; else this._width=width;
	if (!height) this._height=this.scrollheight*4; else this._height=height;
	var ex=this._extobjrefs;
	//
	var sys_scroll_style_attribs=    "position:absolute;overflow:hidden;width:"+this.scrollheight+";height:"+this.scrollheight+";";
	//
	var main_divs_src="<div id="+id+" style=\"position:relative;\"><div ftag=pane style=\"position:absolute;width:50;height:50;overflow:hidden;\"><table cellspacing=0 cellpadding=0><tr><td ftag=panecontent></td></tr></table></div><div ftag=hscroll style=\"position:absolute;\"></div><div ftag=vscroll style=\"position:absolute;\"></div><div ftag=scrolldrag style=\""+sys_scroll_style_attribs+"\"></div></div>";
	//
	var scroll_H_inner_src="<div ftag=bthscrollleft style=\""+sys_scroll_style_attribs+"background:url(images/scrollpanediv_files/Scroll.gif);\"></div><div ftag=bthscrollmiddle style=\""+sys_scroll_style_attribs+"background:url(images/scrollpanediv_files/Scroller.gif);\"></div><div ftag=bthscrollright style=\""+sys_scroll_style_attribs+"background:url(images/scrollpanediv_files/Scroll.gif);\"></div>";
	var scroll_V_inner_src="<div ftag=btvscrolltop style=\""+sys_scroll_style_attribs+"background:url(images/scrollpanediv_files/ScrollUp.gif);\"></div><div ftag=btvscrollmiddle style=\""+sys_scroll_style_attribs+"background:url(images/scrollpanediv_files/Scroller.gif);\"></div><div ftag=btvscrollbottom style=\""+sys_scroll_style_attribs+"background:url(images/scrollpanediv_files/ScrollDown.gif);\"></div>";
	//
	this.hobj=create_from_src(main_divs_src);
	this.hobj.childNodes[1].innerHTML=scroll_H_inner_src;
	this.hobj.childNodes[2].innerHTML=scroll_V_inner_src;
	var objs={
		obj:this,
		hobj:this.hobj,
		pane:this.hobj.childNodes[0],
		panecontent:this.hobj.childNodes[0].childNodes[0].getElementsByTagName("td")[0],
		hscroll:this.hobj.childNodes[1],
		vscroll:this.hobj.childNodes[2],
		hscroller:this.hobj.childNodes[1].childNodes[1],
		vscroller:this.hobj.childNodes[2].childNodes[1],
		scrollleftbutton:this.hobj.childNodes[1].childNodes[0],
		scrollrightbutton:this.hobj.childNodes[1].childNodes[2],
		scrollupbutton:this.hobj.childNodes[2].childNodes[0],
		scrolldownbutton:this.hobj.childNodes[2].childNodes[2],
		scrolldrag:this.hobj.childNodes[3]
	};
	//initalise les valeur de necessite de scrolls H et V
	this.b_hscroll=true;
	this.b_vscroll=true;
	//cree les references de chaque objets de objs vers chaque objets (this==objs.obj compris)
	//chaque objet peut ainsi acceder aux methodes et propriétés des autres composants du scroll
	this._refstoobjs(objs);
	//references internes au scrollbars
	this._refstoobjs({scrollroot:this.hscroll, scroller:this.hscroller, btscrollinc:this.scrollrightbutton, btscrolldec:this.scrollleftbutton, scrollaxis:'X'});
	this._refstoobjs({scrollroot:this.vscroll, scroller:this.vscroller, btscrollinc:this.scrolldownbutton, btscrolldec:this.scrollupbutton, scrollaxis:'Y'});
	//operateurs d'increment / decrement pour les boutons gauche droite haut bas
	this.scrollleftbutton.scrollop=this.scrollupbutton.scrollop='-';
	this.scrollrightbutton.scrollop=this.scrolldownbutton.scrollop='+';
	//alias de function qui rendent les scrollers V et H autonome par rapport a leur propre position
	this.hscroller.getScroller=function(){return this.obj.getHScroller()};
	this.hscroller.setScroller=function(v){this.obj.setHScroller(v)};
	this.vscroller.getScroller=function(){return this.obj.getVScroller()};
	this.vscroller.setScroller=function(v){this.obj.setVScroller(v)};
	this.hscroller.getScroll=function(){return this.obj.getHScroll()};
	this.hscroller.setScroll=function(v){this.obj.setHScroll(v)};
	this.vscroller.getScroll=function(){return this.obj.getVScroll()};
	this.vscroller.setScroll=function(v){this.obj.setVScroll(v)};
	this.hscroller.ScrollInc=function(){this.obj.HScrollInc()};
	this.hscroller.ScrollDec=function(){this.obj.HScrollDec()};
	this.vscroller.ScrollInc=function(){this.obj.VScrollInc()};
	this.vscroller.ScrollDec=function(){this.obj.VScrollDec()};
	////sizes
	this._frameresize();
	//scrolls
	this._scrollresize();
	//HTML events
	this._initevents();
	//if (helem && helem.childNodes) helem.appendChild(this.hobj);
	if (helem && helem.childNodes) {
		helem.parentNode.appendChild(this.hobj);
		this.appendChild(helem);
	}
}
//objet static qui stocke les instances crees
dscrollpane.insts={};
dscrollpane.scrolling=null; //reserve pour reference de l'objet courant scrollantr
dscrollpane.scrolling_busy=false; //reserve si objet occupe true
dscrollpane.scrolling_val=null; //reserve pour valeur position clic souris au focus du scroller
dscrollpane.scrolling_int=null; //reserve pour valeur int interval id
dscrollpane.scrolling_axiskey=null; //reserve pour l'axe
//methodes statiques
dscrollpane.getFirstScrollParent=function(helem){
	var hobj=helem,obj=null;
	while(hobj=hobj.parentNode){
		obj=hobj.obj || obj;
		if(dscrollpane.prototype.isPrototypeOf(obj)) break;
	}
	return obj;
};
//
var p=dscrollpane.prototype={obj:null, hobj:null, pane:null, panecontent:null, hscroll:null, vscroll:null, hscroller:null, vscroller:null, scrollleftbutton:null,scrollrightbutton:null, scrollupbutton:null, scrolldownbutton:null, scrolldrag:null};

p._refstoobjs=function(objlist) {
	for (var att in objlist) this._extobjrefs(objlist,objlist[att]);
};
p._extobjrefs=function(src,dst){
	if (typeof(dst)!='object' || typeof(src)!='object') return;
	for (var att in src) dst[att]=src[att];
};
////
p._scrollresize=function(){
	var vs,hs,ex,scrollheight, width=this._width,height=this._height;
	vs=this.vscroll;
	hs=this.hscroll;
	ex=this._extobjrefs;
	scrollheight=this.scrollheight;
	//hscroll bt left
	ex({left:0, top:0}, hs.childNodes[0].style);
	//hscroll scroller
	ex({left:scrollheight, top:0}, hs.childNodes[1].style);
	//hscroll bt right
	ex({left:this._width-(scrollheight*2), top:0}, hs.childNodes[2].style);
	//vscroll bt left
	ex({left:0, top:0}, vs.childNodes[0].style);
	//vscroll scroller
	ex({left:0, top:scrollheight}, vs.childNodes[1].style);
	//vscroll bt right
	ex({left:0, top:this._height-(scrollheight*2)}, vs.childNodes[2].style);
	//Vscroll
	ex({width:scrollheight, height:height-scrollheight, left:width-scrollheight, top:0, background:"url(images/scrollpanediv_files/Scrollbarv.gif)"}, this.vscroll.style);
	//HSCROLL
	ex({width:width-scrollheight, height:scrollheight, left:0, top:height-scrollheight, background:"url(images/scrollpanediv_files/Scrollbarh.gif)"}, this.hscroll.style);
	//scrolldrag
	ex({left:width-scrollheight, top:height-scrollheight, width:scrollheight, height:scrollheight},this.scrolldrag.style);
};
p._frameresize=function(){
	var width=this._width,height=this._height,scrollheight=this.scrollheight;
	var ex=this._extobjrefs;
	//mainframe
	ex({width:width, height:height}, this.hobj.style);
	//pane
	ex({width:width-scrollheight, height:height-scrollheight, left:0, top:0}, this.pane.style);
	//
};
////
p._initevents=function(){
	//scrolls
	var _scroller_onmousedown_=function () {
		if (dscrollpane.scrolling_busy) return;
		var evtkey="client"+this.scrollaxis;
		dscrollpane.scrolling=this;
		dscrollpane.scrolling_busy=true;
		dscrollpane.scrolling_val=((arguments.length!=0) ? arguments[0][evtkey] : event[evtkey])-this.getScroller();
		dscrollpane.scrolling_axiskey=evtkey;
		this.hobj.onselectstart=function() {return false};
		document.onmouseup=function() {
			dscrollpane.scrolling.hobj.onselectstart=null;
			dscrollpane.scrolling=null;
			dscrollpane.scrolling_busy=false;
			document.onmouseup=null;
			document.onmousemove=null;
			return true;
		};
		document.onmousemove=function() {
			var val=((arguments.length!=0) ? arguments[0][dscrollpane.scrolling_axiskey] : event[dscrollpane.scrolling_axiskey]);
			dscrollpane.scrolling.setScroller(val-dscrollpane.scrolling_val);
		};
		return false;
	};
	this.vscroller.onmousedown=_scroller_onmousedown_;
	this.hscroller.onmousedown=_scroller_onmousedown_;
	//Vscroll bar
	var _scroll_onmousedown_=function(){
		if (dscrollpane.scrolling_busy) return; //si le scroller est cliqué la fontion est aussi appelee
		var evtkey="client"+this.scrollaxis,offkey=this.scrollaxis=='X' ? 'offsetLeft':'offsetTop',po=this,baroffset=po[offkey]+this.obj.scrollheight,val=arguments.length!=0 ? arguments[0][evtkey] : event[evtkey];
		while(po=po.offsetParent) baroffset+=po[offkey];
		this.scroller.setScroller(val-baroffset);
	};
	this.hscroll.onmousedown=_scroll_onmousedown_;
	this.vscroll.onmousedown=_scroll_onmousedown_;
	//scrollbuttons
	var _scrollincdec_onmousedown_=function(){
		if (dscrollpane.scrolling_busy) return;
		dscrollpane.scrolling_busy=true;
		dscrollpane.scrolling=this.scroller;
		dscrollpane.scrolling_int=setInterval("dscrollpane.scrolling.Scroll"+(this.scrollop=='+' ? 'Inc' : 'Dec')+"()",50);
		document.onmouseup=function(){clearInterval(dscrollpane.scrolling_int);dscrollpane.scrolling_busy=false;document.onmouseup=null};
		dscrollpane.scrolling_int;
	};
	this.scrollleftbutton.onmousedown=_scrollincdec_onmousedown_;
	this.scrollrightbutton.onmousedown=_scrollincdec_onmousedown_;
	this.scrollupbutton.onmousedown=_scrollincdec_onmousedown_;
	this.scrolldownbutton.onmousedown=_scrollincdec_onmousedown_;
	//scroll mozilla (quand le browser autorise le scroll manuel via molette souris) , synchonise les scrollbars avec l'etat de scroll
	/*this.pane.onscroll=function() {
		if (dscrollpane.scrolling_busy) return;
		this.obj._Hscroll2scroller();
		this.obj._Vscroll2scroller();
	};*/
	//scroll wheel
	var _pane_onmousewheel_=function(event){
		if (dscrollpane.scrolling_busy) return;
		dscrollpane.scrolling_busy=true;
		var delta = 0;
		if (!event) event = window.event;/* For IE. */
		var obj=dscrollpane.getFirstScrollParent(event.srcElement || event.target);
		//if (obj.eventDisabled) return;
		if (event.wheelDelta) { /* IE/Opera. */
			delta = event.wheelDelta/120;/* In Opera 9, delta differs in sign as compared to IE.*/
			if (window.opera) delta = -delta;
		} else if (event.detail) {
			delta = -event.detail/3;/** Mozilla case. */
		}
		if (event.preventDefault) event.preventDefault();
		event.returnValue = false;
		//
		if (obj.eventDisabled) obj=dscrollpane.getFirstScrollParent(obj.hobj);
		//
		if (obj.b_vscroll) {
			obj.setVScroll(obj.getVScroll() + (obj.scrollincr*(-delta)));
		} else if(obj.b_hscroll) {
			obj.setHScroll(obj.getHScroll() + (obj.scrollincr*(-delta)));
		}
		dscrollpane.scrolling_busy=false;
	};
	if(document.attachEvent)
		this.pane.attachEvent("onmousewheel",_pane_onmousewheel_);
	else
		this.pane.addEventListener("DOMMouseScroll", _pane_onmousewheel_, false);
	//resize pas fini
	this.panecontent.onresize=function() { //merche seulement sur IE (pour une fois)
		//alert("resize");
	};
};
////
p.resize=function(width,height) {
	/*if ((width|0)    <this.minsize) width= this._width;
	if ((height|0)   <this.minsize) height=this._height;*/
	if (width==null){width=this._width;} else if(width<this.minsize){width=this.minsize;};
	if (height==null){height=this._height;} else if(height<this.minsize){height=this.minsize;};
	this._width=width;
	this._height=height;
	this._frameresize();
	this._scrollresize();
	this._oncontentresize();
};
p._oncontentresize=function(){
	this._selectscrolls();
	this._Hscroll2scroller();
	this._Vscroll2scroller();
};
p._selectscrolls=function() { //determine si l'usage des scrolls H et/ou V sont necessaires
	var Hms,Vms;
	this.b_hscroll=false;
	this.b_vscroll=false;
	Hms=this.getHMaxScroll();
	Vms=this.getVMaxScroll();
	if (Hms) {
		this.b_hscroll=true;
		this.hscroll.style.display='';
		this.vscroll.style.height=this._height-this.scrollheight;
		this.vscroll.childNodes[2].style.top=this._height-(this.scrollheight*2);
		this.pane.style.height=this._height-this.scrollheight;
		this.setHScroll(this.getHScroll());
	} else {
		this.b_hscroll=false;
		this.hscroll.style.display='none';
		this.vscroll.style.height=this._height;
		this.vscroll.childNodes[2].style.top=this._height-this.scrollheight;
		this.pane.style.height=this._height;
		this.pane.scrollLeft=0;
	}
	//
	if (Vms) {
		this.b_vscroll=true;
		this.vscroll.style.display='';
		this.hscroll.style.width=this._width-this.scrollheight;
		this.hscroll.childNodes[2].style.left=this._width-(this.scrollheight*2);
		this.pane.style.width=this._width-this.scrollheight;
		this.setVScroll(this.getVScroll());
	} else {
		this.b_vscroll=false;
		this.vscroll.style.display='none';
		this.hscroll.style.width=this._width;
		this.hscroll.childNodes[2].style.left=this._width-this.scrollheight;
		this.pane.style.width=this._width;
		this.pane.scrollTop=0;
	}
	//
	this.scrolldrag.style.display=(this.b_hscroll && this.b_vscroll) ? '' : 'none';
};
////
//size
p.getCW=function() {
	return this.panecontent.offsetWidth;
};
p.getCH=function() {
	return this.panecontent.offsetHeight;
};
//scroll max
p.getHMaxScroll=function() {
	var v=this.getCW()-(this._width-((this.b_vscroll) ? this.scrollheight : 0 ));
	if (v>0) return v; else return 0;
};
p.getVMaxScroll=function() {
	var v=this.getCH()-(this._height-((this.b_hscroll) ? this.scrollheight : 0 ));
	if (v>0) return v; else return 0;
};
//scroll
p.getHScroll=function() {
	return this.pane.scrollLeft;
};
p.getVScroll=function() {
	return this.pane.scrollTop;
};
p.setHScroll=function(v) {
	var sm=this.getHMaxScroll();
	if (v<0) v=0;
	if (v>sm) v=sm;
	this.pane.scrollLeft=v;
	this._Hscroll2scroller();
};
p.setVScroll=function(v) {
	var sm=this.getVMaxScroll();
	if (v<0) v=0;
	if (v>sm) v=sm;
	this.pane.scrollTop=v;
	this._Vscroll2scroller();
};
//scroll + -
p.HScrollInc=function(){
	this.setHScroll(this.getHScroll()+this.scrollincr);
};
p.HScrollDec=function(){
	this.setHScroll(this.getHScroll()-this.scrollincr);
};
p.VScrollInc=function(){
	this.setVScroll(this.getVScroll()+this.scrollincr);
};
p.VScrollDec=function(){
	this.setVScroll(this.getVScroll()-this.scrollincr);
};
//scroller 
p.getHScroller=function() {
	return parseInt(this.hscroller.style.left)-this.scrollheight;
};
p.getVScroller=function() {
	return parseInt(this.vscroller.style.top)-this.scrollheight;
};
p.setHScroller=function(v){
	var sm=this.getHScrollerMax();
	if(v<0) v=0;
	if(v>sm) v=sm;
	this.hscroller.style.left=this.scrollheight+v;
	this.pane.scrollLeft= Math.floor(this.getHMaxScroll() * (v / sm));
};
p.setVScroller=function(v){
	var sm=this.getVScrollerMax();
	if(v<0) v=0;
	if(v>sm) v=sm;
	this.vscroller.style.top=this.scrollheight+v;
	this.pane.scrollTop= Math.floor(this.getVMaxScroll() * (v / sm));
};
//scroller max
p.getHScrollerMax=function() {
	return this._width-( this.scrollheight*((this.b_vscroll) ? 4 : 3) );
};
p.getVScrollerMax=function() {
	return this._height-( this.scrollheight*((this.b_hscroll) ? 4 : 3) );
};
//scroll => scroller
p._Hscroll2scroller=function(){
	var v,sm=this.getHScrollerMax(),div=this.getHMaxScroll();
	if(div==0) return;
	v=Math.floor(sm * (this.getHScroll() / div));
	if (v>sm) v=sm;
	this.hscroller.style.left=this.scrollheight+v;
};
p._Vscroll2scroller=function(){
	var v,sm=this.getVScrollerMax(),div=this.getVMaxScroll();
	if(div==0) return;
	v=Math.floor(sm * (this.getVScroll() / div));
	if (v>sm) v=sm;
	this.vscroller.style.top=this.scrollheight+v;
};
////
p._triggercontentresized=function(){
	setTimeout("dscrollpane.insts['"+this.id+"']._oncontentresize()",1);
};
////
p.setScrolling=function(bscrolling) {
	//position:absolute;width:50;height:50;overflow:hidden
	var ps=this.pane.style;
	var hs=this.hobj.style;
	if(bscrolling){
		this._selectscrolls();
		this.eventDisabled=false;
		hs.overflow='hidden';
	}else{
		this.setHScroll(0);
		this.setVScroll(0);
		ps.width=this.getCW();
		ps.height=this.getCH();
		//ps.width="";
		//ps.height="";
		this.hscroll.style.display='none';
		this.vscroll.style.display='none';
		this.scrolldrag.style.display='none';
		this.eventDisabled=true;
		hs.overflow='visible';
	}
};
////
p.setHTML=function(hsrc) {
	this.panecontent.innerHTML=hsrc;
	this.setHScroll(0);
	this.setVScroll(0);
	//declenche evenement a retardement sinon la taille du contenu html n'est pas actualisée
	this._triggercontentresized();
};
p.takeChildsOf=function(helem){ //prends les enfants de l'element html donné et les met dans le scrollpane
	if (!helem || !helem.childNodes) return;
	this.panecontent.innerHTML='';//vide le container
	var cns=helem.childNodes,l=cns.length,i;
	for(i=0;i<l;i++) {
		this.panecontent.appendChild(cns[i]);
	}
	this._triggercontentresized();
};
p.setHTMLObject=function(helem){ //prends un objet HTML et le met dans le scrollpane
	if (!helem) return;
	this.panecontent.innerHTML='';//vide le container
	this.panecontent.appendChild(helem);
	this._triggercontentresized();
};
p.appendChild=function(helem){
	if (!helem) return;
	this.panecontent.appendChild( (dscrollpane.prototype.isPrototypeOf(helem)) ? helem.hobj : helem );
	this._triggercontentresized();
};
p.appendChildFromCode=function(hsrc){
	if (!hsrc) return;
	this.panecontent.appendChild(create_span_from_src(hsrc));
	this._triggercontentresized();
};

p.getHTML=function(){
	return "<div style=\"position:relative;\">"+this.hobj.innerHTML+"</div>";
};
delete p; //supprime la reference vers le prototype (class)

