//  ____________________________
// |                            |________________________________________________________
// |                                                                                     |
// |   ScrollPane (derives from Sprite)                                                  |
// |                                                                                     |
// |   This JS object is designed to be used as a relatively placed Scrolling            |
// |   Box with one vertical scrollbar.                                                  |
// |                                                                                     |
// |_____________________________________________________________________________________|
//	
function ScrollPane(id,css,container,w,hi,resizeable)
	{	
		this.inherit = Sprite;
		this.inherit(id,container);
		ImplementGuiInterface(this);
		this.type = 'static'
		this.focus=function rien(){};
		this.resizeable = resizeable;
		this.scrollUp=ScrollPaneScrollUp;
		this.scrollDown=ScrollPaneScrollDown;
		this.scrollStop=ScrollPaneScrollStop;
		this.scrollDrag = ScrollPaneScrollDrag;
		this.scrollTo = ScrollPaneScrollTo;
		this.scrollDragStart=ScrollPaneScrollDragStart;
		this.scrollDragStop=ScrollPaneScrollDragStop;
		
		this.updateScrollBox=ScrollPaneUpdateScrollBox
		this.resizeScrollBox=ScrollPaneResizeScrollBox;
		this.scrollJump = ScrollPaneScrollJump;
		this.scrollToTop = ScrollPaneScrollToTop;
		this.update=ScrollPaneUpdate;
		this.doLayout = ScrollPaneDoLayout;
		this.resizeDragStart = SPresizeDragStart;
		this.scrollingDisabled=false;
		//alert(container)
		
		
		this.canvas.position="relative";
		this.canvas.overflow="hidden";
		
		if(w){
			this.w=w;
			this.canvas.width=w+"px";
		}else{
			this.w = this.node.offsetWidth;
		}
		
		if(hi){
			this.h=hi;
			this.canvas.height=hi+"px";
		}else{
			this.h = this.node.offsetheight;
		}
		
		this.node.className = css;
		
		if(this.node.childNodes.length>0)
		{
			//alert(this.node.innerHTML);
			
			
			fs = (this.node.firstChild);
			while(fs.nodeType!=1&&fs.nextSibling)
			{
				fs=fs.nextSibling;
			}
			if(fs.nodeName.toLowerCase()=="iframe"){
				this.container = fs;
				if(ie)
				this.content = frames[fs.id].document.body.firstChild;
				if(moz)
				this.content = frames[fs.id].document.body;
				this.content.style.position="absolute";
				//alert(this.content.offsetHeight)
			}
			else{
				this.container = null;
				this.content = fs;
				this.content.style.position="absolute";
			}
			
			//alert(this.content.innerHTML);
		}
		else{ 
			//alert(this.id+" for some reason creating conent layer");
			this.content =makeChild(this.node,"div",id+"content",'&nbsp',css+"_text",this.w,null,0,0);
			this.container = null;
		}
		this.scrollbar = makeChild(this.node,"div",id+"scrollbar",null,css+"_scrollBar","auto",this.h,this.w-23,1+1*moz);
		this.up = makeButton(this.scrollbar,id+"up",css+"_up",0,0);
		this.dn = makeButton(this.scrollbar,id+"dn",css+"_dn",0,0);
		if(resizeable)
		{
				this.resizeButton = makeButton(this.node,this.id+"resize",css+"_resize");
				delegateEvent(this.resizeButton,"mousedown",this,"resizeDragStart");
				this.cancelTextSelect(this.resizeButton);
		}
		

		
		this.content.className=css+"_text";

		this.lineH=15
		this.yOffset=0;
		this.sboxYoffset=this.up.offsetHeight;
		this.sboxY=0;
		this.scrollbox=makeChild(this.scrollbar, "div", id+"box",null, css+"_scrollBox", "auto", 1, 0, this.sboxYoffset);
		sbw = this.scrollbox.offsetWidth;
		this.scrollbox.style.left = (this.scrollbar.offsetWidth - sbw)/2+"px";
		


		
		delegateEvent(this.up,"mousedown",this,"scrollUp");
		delegateEvent(this.up,"mouseup",this,"scrollStop");
		delegateEvent(this.dn,"mousedown", this,"scrollDown");
		delegateEvent(this.dn,"mouseup",this,"scrollStop");
		delegateEvent(this.dn,"mouseout",this,"scrollStop");
		delegateEvent(this.up,"mouseout",this,"scrollStop");
		delegateEvent(this.dn,"mouseover",this,"scrollStop");
		delegateEvent(this.up,"mouseover",this,"scrollStop");
		delegateEvent(this.dn,"click",this,"scrollStop");
		delegateEvent(this.up,"click",this,"scrollStop");
		delegateEvent(this.scrollbox,"mousedown",this,"scrollDragStart");
		delegateEvent(this.scrollbox,"mouseup",this,"scrollDragStop");
		delegateEvent(this.scrollbar,"mousedown",this,"scrollJump");
		this.doLayout();

	}
	function cancelImageDrag(e)
	{
		if(moz)
			e.preventDefault();
	}
	function ScrollPaneDoLayout()
	{
		this.content.style.display="block";
		imgs = this.content.getElementsByTagName("img");
		imgid=''
		for (i=0;i<7;i++)
			imgid += String.fromCharCode(65+Math.round(Math.random()*25));
		//alert(imgid)
		for(i=0;i<imgs.length;i++)
		{
			
			//alert(id);
			imgs[i].id=imgid+i;
			eval(imgid+i+"="+"imgs["+i+"]");
			imgs[i].loaded=new Function("this.onload=null;"+this.id+".resizeScrollBox()");
			delegateEvent(imgs[i],"load",imgs[i],"loaded");
			
		}
		w = getInnerWidth(this.node);
		h = getInnerHeight(this.node);
		if(this.container){
			this.container.style.width=w-this.scrollbar.offsetWidth+"px";
			this.container.style.height =h+"px";
			this.content.style.display="block";
			}else{
				this.content.style.width=w-this.scrollbar.offsetWidth+"px";
			}
			this.scrollbar.style.left = w-this.scrollbar.offsetWidth+"px";
		this.pH = h;
		this.cH = this.content.offsetHeight;
		if(this.resizeable)
		{
			this.resizeButton.style.left = this.scrollbar.style.left;
			this.resizeButton.style.top =h-this.resizeButton.offsetHeight+"px";
			//alert(h-this.resizeButton.offsetHeight+"px");
		}
		if(!this.scrollingDisabled)
		{
			if(this.cH<=this.h)
			{
	
				this.scroll = false;
				this.scrollbar.style.visibility="hidden";
				if(this.container){
					this.container.style.width=w+"px";
					}
				else{
					this.content.style.width=w+"px";
				}
			}
			else
			{
				this.scroll = true;
				this.scrollbar.style.visibility="inherit";
			}
			sbh = h;
			if(this.resizeable)
			sbh-=this.resizeButton.offsetHeight;
			//alert(sbh);
			//this.scrollbar.style.height = h+"px";
			this.scrollbar.style.height = sbh+"px";
			this.sbarH = this.scrollbar.offsetHeight - this.up.offsetHeight - this.dn.offsetHeight;
			this.dn.style.top = this.scrollbar.offsetHeight - this.dn.offsetHeight+"px"
			this.dn.style.left="0px";
			this.up.style.left="0px";
			
			if(this.scroll)
			{	
			this.resizeScrollBox();
			this.updateScrollBox();
			}
		}
		else
		{
			this.content.style.top="0px";
			this.yOffset = 0;
			this.scrollbar.style.visibility='hidden';
		}
		
	}
	function ScrollPaneScrollDragStart(e)
	{
		
		this.resizeScrollBox();
		this.dragType=1;
		GuiManager.dragObject = this;
		if(ie)
			return false;
		if(moz &&e)
			e.preventDefault();
		
	}
	function ScrollPaneScrollDragStop()
	{
		GuiManager.dragObject = null;
	}
	function ScrollPaneScrollDrag(e)
	{
		ev.register(e)
		DRAG_OBJECT.scrollDrag(ev,this);
	}
	
	function ScrollPaneScrollUp()
	{
		
		this.resizeScrollBox();
		this.yOffset+=this.lineH;
		if (this.yOffset>0)
			this.yOffset=0
		this.content.style.top=this.yOffset+"px";
		this.updateScrollBox();
		GuiManager.scrollRepeat = setTimeout(this.id+'.scrollUp()',40);
	}
	function ScrollPaneScrollTo(y)
	{
		if(y>this.cH-this.pH)
			y=this.cH-this.pH;
		if(y<0)
			y=0;
		this.yOffset=-y;
		this.content.style.top=this.yOffset+"px";
		this.updateScrollBox();
		
	}
	function ScrollPaneScrollDown(e)
	{
		if(e && e.button==2)
		{
			e.cancelDefault();
		}
		this.resizeScrollBox();
		this.yOffset-=this.lineH;
		if (this.yOffset<this.pH-this.cH)
			this.yOffset=this.pH-this.cH
		this.content.style.top=this.yOffset+"px";
		this.updateScrollBox();
		GuiManager.scrollRepeat = setTimeout(this.id+'.scrollDown()',40);
	}
	function ScrollPaneScrollStop()
	{		if(GuiManager.scrollRepeat)
				clearTimeout(GuiManager.scrollRepeat);
	}
	function ScrollPaneScrollDrag()
	{
		//alert(E.dy);
		this.sboxY+=GuiManager.dy;
		if(this.sboxY<this.sboxYoffset)
			this.sboxY=this.sboxYoffset;
		if(this.sboxY>this.sbarH-this.sboxH+this.sboxYoffset)
			this.sboxY=this.sbarH-this.sboxH+this.sboxYoffset;
		this.scrollbox.style.top=this.sboxY+"px";
		this.yOffset=-(this.sboxY-this.sboxYoffset)*this.cH/this.sbarH;
		this.content.style.top=this.yOffset+"px";
		//clipLayer(this.content.style,0,-this.yOffset,this.content.offsetWidth,this.h)
	
	}	
	function ScrollPaneUpdateScrollBox()
	{
		this.sboxY=this.sboxYoffset+Math.round(Math.abs(this.yOffset)*this.sbarH/this.cH);
		this.scrollbox.style.top=this.sboxY+"px";
	}
	function ScrollPaneUpdate(obj)
	{
		//alert(this.content.nodeName);
		switch(typeof(obj))
		{
			case "string" :
				this.content.innerHTML=obj;
			break;
			case "object" :
				this.content.parentNode.replaceChild(this.content,obj);
			break;
		
		}
		this.doLayout();
	}
	function ScrollPaneResizeScrollBox()
	{
		this.cH= this.content.offsetHeight;
		this.sboxH=(this.pH)*(this.sbarH/this.cH);
		this.scrollbox.style.height=this.sboxH+"px";
		//adjustBoxModel(this.scrollbox)
	}
	function ScrollPaneScrollToTop()
	{
		this.content.style.top="0px";
		this.yOffset=0;
		this.updateScrollBox();
	}
	function ScrollPaneScrollJump()
	{
		
		this.resizeScrollBox();
		yf = this.scrollbar.offsetTop;
		ob = this.scrollbar;
		while (ob != document.body)
		{
			ob = ob.parentNode;
			yf += ob.offsetTop;
		}
		mouseY = GuiManager.mouseY - yf;
		if(mouseY>parseInt(this.up.offsetHeight) && mouseY < this.sboxY)
		{
			nyo = this.yOffset + this.h;
			if(nyo>0)nyo=0;
			this.yOffset = nyo;
			this.content.style.top = this.yOffset+"px";
			this.updateScrollBox();
		}
		if(mouseY>this.sboxY+this.sboxH && mouseY < this.dn.offsetTop)
		{
			nyo = this.yOffset - this.h;
			if(nyo<-this.cH+this.pH)nyo=-this.cH+this.pH;
			this.yOffset = nyo;
			this.content.style.top = this.yOffset+"px";
			this.updateScrollBox();
		}
	}
	function __doNothing(){}

//  ____________________________
// |                            |________________________________________________________
// |                                                                                     |
// |   BaseGui (derives from Sprite)                                                     |
// |_____________________________________________________________________________________|
//	
	function ImplementGuiInterface(sprite)
	{	
		
		sprite.mouseEventDispatch = base_mouseEventDispatch;
		sprite.mouseDown = base_mouseDown;
		sprite.dragStart = base_dragStart;
		sprite.dragStop = base_dragStop;
		sprite.drag = base_drag;
		sprite.focus = base_focus;
		sprite.isFocused = false;
		sprite.blur = base_blur;
		sprite.onblur = function rien(){};
		sprite.onfocus = function rien(){};
		sprite.isDraggable = false;
		sprite.dragStyle=0;
		sprite.hide = m_override_hide;
		sprite.show = m_override_show;
		sprite.close = base_close;
		sprite.open = base_open;
		sprite.disableTextSelect = base_disableTextSelect
		sprite.enableTextSelect = base_enableTextSelect
		sprite.cancelTextSelect  = base_cancelTextSelect
		sprite.dragOpacity=0.5;

	}
	function base_disableTextSelect()
		{
			if(moz)
			document.onmousedown=new Function("return false;");
			// doesn't seem to be a problem in IE
		}
	function base_enableTextSelect()
		{
			if(moz)
			document.onmousedown = function rien(){}
			// doesn't seem to be a problem in IE
		}
	function base_cancelTextSelect(obj)
	{
		delegateEvent(obj,"mouseover",this,"disableTextSelect");
		delegateEvent(obj,"mouseout",this,"enableTextSelect");
	}
	
	function m_override_hide(){
  	this.canvas.visibility="hidden";
	this.visible= false;
		GuiManager.killObject(this);
	}
	function m_override_show(){
	  	this.canvas.visibility="visible";
		this.visible = true;
		GuiManager.addObject(this);
	}
	function base_close()
	{
		//alert(this.id); return;
		if(GuiManager.closeGui)
		{
			if(this.type=="dialog")
				GuiManager.closeDialog(this);
			else
				GuiManager.closeGui(this);
		}
		else
		{
			this.hide();
		}	
	}  
	function base_open()
	{
		if(GuiManager.openGui)
		{
			GuiManager.openGui(this);
		}
		else
		{
			this.show();
		}
	
	}
	function base_mouseEventDispatch(x,y) 
	{
		//alert(this+" mousevent dispatch");
		x-=this.x;
		y-=this.y;
		targetChild = null;
		if(this.children.length)
		{
			
			for(this.i=this.children.length-1;this.i>-1;this.i--){
				if (x<this.children[this.i].x || x>this.children[this.i].x+this.children[this.i].w)
					continue;
				else if (y<this.children[this.i].y || y>this.children[this.i].y+this.children[this.i].h)
					continue;
					 else { 
					 	targetChild = this.children[this.i];
						break
					 }
			}
			if (targetChild){
				//dbg.printLn("mousdispatch to "+targetChild.id);
				targetChild.mouseEventDispatch(x,y);
				return;
			}
					
		}
		else
		{
			if(this.parent)
			this.focus();
			//alert ("focusing: "+this.id);
		}
		
		this.mouseDown(x,y);	
			
		
	}
	function base_mouseDown(x,y)
	{
		
		if (!this.parent)
			this.dragType = 0;
			//alert(this.isDraggable);
			if(this.isDraggable)
				this.dragStart();
		
	}
	function base_dragStart()
	{
		GuiManager.dragObject = this;
		switch(this.dragType)
		{
		case 0 :
			if(GuiManager.dragType==0)
			{
				this.dragThing = this;
				setOpacity(this.canvas,this.dragOpacity);
			}
		else
			this.dragThing = GuiManager.dragBox;
			this.dragThing.setSize(this.w,this.h);
			this.dragThing.setXY(this.x,this.y,1);
		break;
		case 1:
			this.dragThing = this.scrollBox;
			break;
		case 2:
			this.dragThingy = GuiManager.dragBox;
			this.dragThingy.canvas.zIndex = GuiManager.superZ;
			//alert(this.w+" "+this.h+" ");
			this.dragThingy.setSize(this.w,this.h);
			this.dragThingy.setXY(getPageLeft(this.node),getPageTop(this.node),1);
		}
		
	}
	function base_dragStop(finalX,finalY)
	{
		switch(this.dragType)
		{
		case 0:
		this.setXY();
		if(this.dragThing==this)
			setOpacity(this.canvas,1);
		else
			this.dragThing.hide();
		break;
		case 2:
		this.setSize(this.w,this.h);
		this.dragThingy.hide();
		//document.body.appendChild(this.dragThingy.node)
		break;
		}
	}
	function base_drag()
	{
		switch(this.dragType)
		{
		case 0:
		this.x += GuiManager.dx;
		this.y += GuiManager.dy;
		if(this.x<0)this.x=0;
		if(this.y<0)this.y=0;
		if(!this.dragThing.busy)this.dragThing.setXY(this.x,this.y);
		break;
		case 1:
		this.scrollDrag();
		break;
		case 2:
		this.w +=GuiManager.dx;
		this.h +=GuiManager.dy;
		this.dragThingy.setSize(this.w,this.h);
		break;
		}
	}

	function base_focus(z)
	{
		if(this.type!='inline')
		{
		 	if(!this.parent)this.canvas.zIndex=z;
		 	this.isFocused=true;
			if (GuiManager.isFocused!=this)
			{	if (GuiManager.isFocused)
					GuiManager.isFocused.blur();
		 		GuiManager.isFocused = this;
			}
		}
		this.onfocus();
		for(this.i=0;this.i<this.children.length;this.i++)
		{
			this.children[this.i].focus()
		}
	}
	function base_blur(){
		
	 	this.isFocused = false;
		if(GuiManager.isFocused==this)
			GuiManager.isFocused = null;
		this.onblur();
		for(this.i=0;this.i<this.children.length;this.i++)
		{
			this.children[this.i].focus()
		}
	}
	
	
	function ImplementAcceptDrop(sprite)
	{
	
		sprite.acceptsDrop = true;
		
		/* 
		   called when a dragDropObject is hovering this object 
		   override to change behaviour 
		 */
		sprite.dragOver = function Idd_base_dragOver()
							{//alert('drag over');
								/*if(this.theme)
								{
								
									//if(getCssStyle(this.theme+"_dragOver"))
										this.node.className = this.theme+"_dragOver";
								}*/
								this.canvas.borderColor="#ff6600";
							}
							
		/* 
			called of drag and drop object ceases to hover and when object is dropped
		 */					
		sprite.dragOut =  function Idd_base_dragOut()
							{
								
								 this.canvas.borderColor="";
							}	
							
		/* 
			called before dragDrop return true if accepted, false if rejected 
		    returning false will inhibit a call to dragDrop 
		 */					
		sprite.validateDrop =  function idd_base_dropCheck(dragDropObject)
							{
								/* be default any drop is OK */
								return true;
							}					
							
		/* 
		   called if dragDropObject is dropped into this gui 
		   
		*/ 							
		sprite.dragDrop = function Idd_basic_dragDrop(dragDropObject)
							{
								/* the most basic update is to tack on the gui
								   this is probably not the behaviour
								   overwrite this function */
								this.content.appendChild(dragDropObject.node);
							}
	
	
}

function DragDropObject(id,type,node,xOffset,yOffset,data,from)
{
	/* make object draggable and stuff */
	this.inherit = Sprite;
	this.inherit(id,null);
	/* make the GUI that is dragged */
	
	this.xOffset = xOffset;
	this.yOffset = yOffset;
	
	w=node.offsetWidth; h=node.offsetHeight;

	this.node = node.cloneNode(true);
	this.canvas = this.node.style;
		this.setSize(w,h);
	this.canvas.display="none";
	this.canvas.visibility="hidden";
	this.canvas.position="absolute";
	document.body.appendChild(this.node);
	this.canvas.display="block";
	/* set the type */
	this.type = type;
	
	/* data can be anything : a JSON object or whatever -- destination has to know how
	  to decode it -- attach a function on the destination that accepts */
	this.data = data;
	
	/* the source GUI may want to do some updating GuiManager will call updateFromDragDrop */
	this.from = from;
	
	this.destroy= function ddo_destroy()
	{
		bla = this.node.parentNode.removeChild(this.node);
		bla = null;
	}
	

}
	function ScrollWindow(id,css,content,title,width,height)
	{
		this.inherit=ScrollPane;
		this.inherit(id,css,null,width,height,true);
		this.type='';
		this.dragStart = base_dragStart;
		//this.isDraggable = true;
		//ImplementGuiInterface(this);
		
		//this.show();
		//this.setXY(200,200);
		this.canvas.position="absolute";

		this.content=(content) ? getLayer(content) : makeChild(null,"div", id+"content",null);
		this.content.className="";
		this.content.style.position="relative";
		this.content.style.visibility="inherit";
		//this.content.style.width="100%";


		
		this.top = makeChild(this.node,"div",this.id+"top",'<div class="'+css+'_title">'+title+'</div>',css+"_top",this.w,"auto",0,0);

		


		this.container = makeChild(this.node,"div",this.id+"container",null,css+"_text",this.w-this.scrollbar.offsetWidth,this.h-this.top.offsetHeight,1,this.top.offsetHeight);
		this.container.style.overflow="hidden";
		this.container.appendChild(this.content.parentNode.removeChild(this.content));
		//this.resizeButton = makeButton(this.node,this.id+"resize",css+"_resize");
		this.closeButton = makeButton(this.top,this.id+"close",css+"_close",0,0);
		this.pH = this.container.offsetHeight;
		this.scrollPaneDoLayout = this.doLayout;
		this.doLayout = SW_doLayout;
		this.mouseDown = SW_mouseDown;
		//this.resizeDragStart = SW_resizeDragSrart;
		this.isDraggable = true;
		this.cancelTextSelect(this.top);
		
		//this.cancelTextSelect(this.scrollBox);
		//delegateEvent(this.resizeButton,"mousedown",this,"resizeDragStart");
		delegateEvent(this.closeButton,"mousedown",this,"close");
		//alert(this.close);
		this.setSize(width,height);
		
	}
	function SW_doLayout()
	{
		this.scrollPaneDoLayout();
		//alert(this.h);
		imgs = this.content.getElementsByTagName("img");
		for(i=0;i<imgs.length;i++)
		{
			//alert("alert(this.id+' loaded');this.onload=null;"+this.id+".resizeScrollBox()");
			imgs[i].id=this.id+"img"+i;
			imgs[i].loaded=new Function("this.onload=null;"+this.id+".resizeScrollBox()");
			delegateEvent(imgs[i],"load",imgs[i],"loaded");
			
		}
		//this.setSize(this.w,this.h);
		w = getInnerWidth(this.node);
		h = getInnerHeight(this.node);
		//alert(w+" "+this.w+" "+this.node.offsetWidth);
		this.scrollbar.style.height = (h-this.top.offsetHeight-this.resizeButton.offsetHeight)+"px";
		this.scrollbar.style.top=this.top.offsetHeight+"px";
		this.scrollbar.style.zIndex=10;
		this.top.style.width=w+"px";
		this.closeButton.style.top="0px";
		this.closeButton.style.left=(getInnerWidth(this.top)-this.closeButton.offsetHeight-2)+"px";
		this.scrollbar.style.left = w-this.scrollbar.offsetWidth+"px";
		this.container.style.height = h-this.top.offsetHeight+"px";
		this.container.style.width = this.scrollbar.style.left;
		this.cH=this.content.offsetHeight;
		this.sbarH=getInnerHeight(this.scrollbar)-this.dn.offsetHeight-this.up.offsetHeight;
		this.sboxH=this.sbarH/this.cH*this.h;
		this.sboxY = this.top.offsetHeight+this.up.offsetHeight;
		this.container.style.top=this.top.offsetHeight+"px";
		//alert(getInnerHeight(this.scrollbar))
		this.dn.style.top=getInnerHeight(this.scrollbar)-this.dn.offsetHeight+"px";
		this.resizeButton.style.left = this.scrollbar.style.left;
		this.resizeButton.style.top =h-this.resizeButton.offsetHeight+"px";
		this.pH = getInnerHeight(this.container)//.offsetHeight;
		if(this.cH>this.pH)
		{
			this.scroll = true;
			this.scrollbar.style.visibility="inherit";
			this.resizeScrollBox();
			this.updateScrollBox();
		}
		else
		{
			this.scroll = false;
			this.scrollbar.style.visibility="hidden";
			this.yOffset = 0;
			this.content.style.top = this.yOffset;
			//this.updateScrollBox();
		}
		
		
		
	}
	function SW_mouseDown(x,y)
		{
			//alert(this.top.offsetHeight);
			if(y < this.top.offsetHeight)
			{
				if(this.closeButton)
				{
					if((x>this.closeButton.offsetLeft&&x<this.closeButton.offsetLeft+this.closeButton.offsetWidth)
						&& (y>this.closeButton.offsetTop&&y<this.closeButton.offsetTop+this.closeButton.offsetHeight))
						return;
				}
				this.dragType=0;
				this.dragStart();
			}
		}
	function SPresizeDragStart()
		{

			this.dragType=2;
			this.dragStart();
		}
