function FloatingLayer(fl_id) {
    var me=this;			// Self-Reference
    var baseId='FloatingLayer0';	// Oggetto base (per inizializzazione e clonazione)
    var baseClass='flolay';		// floatingObject className
    var visible=false;			// Visible
    var floatingObject=null;		// PUB: floatingObject
    var posX=10;			// PUB: left position
    var posY=160;			// PUB: top position
    var fl_titleObj=null;
    var fl_contentObj=null;
    var fl_movingLayer=null;
    var fl_nowXY={};
    var fl_nowSize={};
    var fl_offsetXY={};
    var fl_topZIndex=1;
    var fl_onMouseMoveSave=null;
    var fl_onMouseUpSave=null;
    var fl_onScrollSave=null;
    var fl_onSelectStartSave=null;
    var fl_offsetYSave=0;
    var fl_isAutoscroll=false;
    var fl_moveTarget={};
    var fl_moveStep={};
    this.obj=null;			// Public reference to outer object
    this.setId=setId;			// Set ID for FL - ONLY BEFORE create()
    this.setClass=setClass;		// Set base class for FL - ONLY BEFORE create()
    this.setPosition=setPosition;	// Set x,y position
    this.move=move;			// Move relative by x,y
    this.create=create;			// FL creation
    this.setTitle=setTitle;
    this.setContent=setContent;
    this.addContent=addContent;
    this.setVisible=setVisible;		// Set FL visibility
    this.setAutoscroll=setAutoscroll;	// Set Autoscroll on|off toggle='x'
    var isIE=document.all?true:false;

    if(!fl_id || fl_id=='') fl_id=baseId;	// Default div id
    else baseId=fl_id;				// Custom div id
    floatingObject=null;

    // PUBLIC setId(idName)
    function setId(idName) {
	if(floatingObject) return;		// Only *before* create
	baseId=idName;
    }

    // PUBLIC setClass(clsName)
    function setClass(clsName) {
	if(floatingObject) return;		// Only *before* create
	baseClass=clsName;
    }

    // PUBLIC setPosition(x,y)
    function setPosition(x,y) {
	if(!floatingObject) {
	    posX=x;
	    posY=y;
	    return;
	}
	floatingObject.style.left=x+'px';
	if(fl_isAutoscroll) {
	    floatingObject.style.top=(y+document.body.scrollTop)+'px';
	    fl_offsetYSave=y+'px';
	} else {
	    floatingObject.style.top=y+'px';
	}
    }

    // PUBLIC move(x,y)
    function move(x,y) {
	if(!floatingObject) return;
	fl_moveTarget[0]=parseInt(floatingObject.style.left)+x;
	fl_moveStep[0]=(x==0?0:x>0?2:-2);
	fl_moveTarget[1]=parseInt(floatingObject.style.top)+y;
	fl_moveStep[1]=(y==0?0:y>0?2:-2);
	if(fl_isAutoscroll) {
	    fl_offsetYSave=fl_moveTarget[1]-document.body.scrollTop;
	}
	moveFunction();
    }
    function moveFunction() {	// Animation Handler
	var curX=parseInt(floatingObject.style.left);
	var curY=parseInt(floatingObject.style.top);
	if((fl_moveStep[0]>0 && curX<fl_moveTarget[0]) || (fl_moveStep[0]<0 && curX>fl_moveTarget[0])) {
	    floatingObject.style.left=(curX+fl_moveStep[0])+'px';
	} else fl_moveStep[0]=0;
	if((fl_moveStep[1]>0 && curY<fl_moveTarget[1]) || (fl_moveStep[1]<0 && curY>fl_moveTarget[1])) {
	    floatingObject.style.top=(curY+fl_moveStep[1])+'px';
	} else fl_moveStep[1]=0;
	if(fl_moveStep[0]!=0 || fl_moveStep[1]!=0) setTimeout(moveFunction,1);
    }

    // PUBLIC create(width,title,content)
    function create(width,title,content) {
	// Object creation and rendering
	var obj=document.createElement("div");
	obj.style.position='absolute';
	obj.style.width=width;
	obj.style.left=posX+'px';
	obj.style.top=posY+'px';
	obj.className=baseClass;
	obj.id=baseId;
	var obj_top=document.createElement("div");	// L1:TOP
	obj_top.className=baseClass+'_top';
	var sobj=document.createElement('span');	// L2:Title
	sobj.id=baseId+'_Title';
	sobj.className=baseClass+'_title';
	sobj.innerHTML=title;
	obj_top.appendChild(sobj);
	fl_titleObj=sobj;
	sobj=document.createElement("span");		// L2:Close
	sobj.className=baseClass+'_close';
	obj_top.appendChild(sobj);
	var obj_cont=document.createElement("div");	// L1:CONTENT
	obj_cont.id=baseId+'_Content';
	obj_cont.className=baseClass+'_content';
	obj_cont.innerHTML=content;
	var obj_border=document.createElement("div");	// L1:BORDER (resize)
	obj_border.id=baseId+'_Border';
	obj_border.className=baseClass+'_border';
	obj.appendChild(obj_top);
	obj.appendChild(obj_cont);
	obj.appendChild(obj_border);
	fl_contentObj=obj_cont;
	document.body.appendChild(obj);			// Append to document
	// Event handlers & class vars initialization
	floatingObject=this.obj=obj;				// Outer DIV object
	for(i=0; i<obj.childNodes.length && obj.childNodes[i].className!=baseClass+'_top'; i++) ;
	if(i==obj.childNodes.length) {
	    floatingObject=this.obj=null;
	    return;
	}
	obj=obj.childNodes[i];
	setEventHandlers(obj);
	setVisible(visible);
    }

    function setEventHandlers(obj) {
	obj.onmousedown=function(e) { moveMouseDown(e); };
	// obj.onmouseup=function(e) { moveMouseUp(e); };
	for(i=0; i<obj.childNodes.length && obj.childNodes[i].className!=baseClass+'_close'; i++) ;
	if(i!=obj.childNodes.length) {
	    obj.childNodes[i].onclick=function(e) { setVisible(0); };
	}
	obj=obj.parentNode;	// Parent: floating obj
	for(i=0; i<obj.childNodes.length && obj.childNodes[i].className!=baseClass+'_border'; i++) ;
	if(i!=obj.childNodes.length) {
	    // obj.childNodes[i].onclick=function(e) { setVisible(0); };
	    obj.childNodes[i].onmousedown=function(e) { resizeMouseDown(e); };
	    // obj.childNodes[i].onmouseup=function(e) { resizeMouseUp(e); };
	}
    }

    // MOVE handling
    function moveMouseDown(evt) {	// Event Handler
	if(isIE) evt=event;
	if(fl_movingLayer) {
	    moveMouseUp(evt);
	    return;
	}
	var obj=isIE?evt.srcElement:evt.target;
	while(obj && obj.className!=baseClass) obj=obj.parentNode;
	if(!obj) return;
	fl_movingLayer=obj;
	fl_offsetXY[0]=evt.clientX;
	fl_offsetXY[1]=evt.clientY;
	fl_nowXY[0]=parseInt(fl_movingLayer.style.left);
	fl_nowXY[1]=parseInt(fl_movingLayer.style.top);
	fl_movingLayer.style.zIndex=fl_topZIndex++;	// BringToFront
	if(document.onmousemove!=moveMouseMove) fl_onMouseMoveSave=document.onmousemove;
	document.onmousemove=moveMouseMove;
if(document.onmouseup!=moveMouseUp) fl_onMouseUpSave=document.onmouseup;
document.onmouseup=moveMouseUp;
	fl_onSelectStartSave=document.body.onselectstart;
	document.body.onselectstart=function() { return false; };
    }
    function moveMouseUp(e) {	// Event Handler
	if(fl_movingLayer) {
	    document.onmousemove=fl_onMouseMoveSave;
document.onmouseup=fl_onMouseUpSave;
	    document.body.onselectstart=fl_onSelectStartSave;
	    fl_movingLayer=null;
	    fl_offsetYSave=parseInt(floatingObject.style.top)-document.body.scrollTop;
// setContent("<pre>"+debugObj(floatingObject.style));
// setContent("<pre>"+debugObj(floatingObject));
	}
    }
    function moveMouseMove(evt) {	// Event Handler
	if(isIE) evt=event;
	if(!fl_movingLayer) {
	    if(fl_onMouseMoveSave) fl_onMouseMoveSave(evt);
	    return;
	}
	if(isIE && event.button!=1) {
	    moveMouseUp(evt);
	    if(fl_onMouseMoveSave) fl_onMouseMoveSave(evt);
	    return;
	}
	fl_movingLayer.style.left=(fl_nowXY[0]+evt.clientX-fl_offsetXY[0])+'px';
	fl_movingLayer.style.top=(fl_nowXY[1]+evt.clientY-fl_offsetXY[1])+'px';
	if(fl_onMouseMoveSave) fl_onMouseMoveSave(evt);
	return false;
    }
    
    // RESIZE handling
    function resizeMouseDown(evt) {	// Event Handler
	if(isIE) evt=event;
	if(fl_movingLayer) {
	    resizeMouseUp(evt);
	    return;
	}
	var obj=isIE?evt.srcElement:evt.target;
	while(obj && obj.className!=baseClass) obj=obj.parentNode;
	if(!obj) return;
	fl_movingLayer=obj;
	fl_offsetXY[0]=evt.clientX;
	fl_offsetXY[1]=evt.clientY;
	fl_nowSize[0]=parseInt(fl_movingLayer.style.width);	// NO Chrome
	fl_nowSize[1]=parseInt(fl_movingLayer.clientHeight);
	fl_movingLayer.style.zIndex=fl_topZIndex++;	// BringToFront
	if(document.onmousemove!=resizeMouseMove) fl_onMouseMoveSave=document.onmousemove;
	document.onmousemove=resizeMouseMove;
	if(document.onmouseup!=moveMouseUp) fl_onMouseUpSave=document.onmouseup;
	document.onmouseup=moveMouseUp;
	document.body.onselectstart = function() { return false; };
    }
    function resizeMouseUp(e) {	// Event Handler
	if(fl_movingLayer) {
	    document.onmousemove=fl_onMouseMoveSave;
	    document.onmouseup=fl_onMouseUpSave;
	    document.onselectstart=fl_onSelectStartSave;
	    fl_movingLayer=null;
	}
    }
    function resizeMouseMove(evt) {	// Event Handler
	if(isIE) evt=event;
try {
 // alert(debugObj(fl_movingLayer.style));
 // alert(fl_nowSize[0]);
 // alert(evt.clientX);
 // alert(fl_offsetXY[0]);
// alert(fl_movingLayer.style.width);
fl_movingLayer.style.width=(fl_nowSize[0]+evt.clientX-fl_offsetXY[0])+'px';
// alert(fl_movingLayer.style.width);
// fl_movingLayer.style.height='500px';
fl_movingLayer.style.height=fl_nowSize[1]+evt.clientY-fl_offsetXY[1];
} catch(e) {	// NO Chrome
	alert("Error: "+e.description);
	resizeMouseUp(evt);
}
return false;

	if(!fl_movingLayer) {
	    if(fl_onMouseMoveSave) fl_onMouseMoveSave(evt);
	    return;
	}
	if(isIE && event.button!=1) {
	    resizeMouseUp(evt);
	    if(fl_onMouseMoveSave) fl_onMouseMoveSave(evt);
	    return;
	}
	fl_movingLayer.style.width=(fl_nowSize[0]+evt.clientX-fl_offsetXY[0])+'px';
	fl_movingLayer.style.height=(fl_nowSize[1]+evt.clientY-fl_offsetXY[1])+'px';
	// if(fl_onMouseMoveSave) fl_onMouseMoveSave(evt);
	return false;
    }

    // PUBLIC setTitle(title)
    function setTitle(title) {
	if(fl_titleObj==null) return;
	fl_titleObj.innerHTML=title;
    }

    // PUBLIC setContent(content)
    function setContent(content) {
	if(fl_contentObj==null) return;
	if(typeof(content)=='object') {
	    fl_contentObj.innerHTML='';
	    fl_contentObj.appendChild(content);
	} else fl_contentObj.innerHTML=content;
    }
    // PUBLIC addContent(content)
    function addContent(content) {
	if(fl_contentObj==null) return;
	if(typeof(content)=='object') {
	    fl_contentObj.appendChild(content);
	} else fl_contentObj.innerHTML+=content;
    }

    // setVisible(yesno)
    function setVisible(yesno) {
	if(yesno=='x') yesno=!visible;
	if(typeof(floatingObject)=='object') floatingObject.style.visibility=yesno?"visible":"hidden";
	visible=yesno?true:false;
    }

    // setAutoscroll (follow page) x=toggle
    function setAutoscroll(yesno) {
	if(yesno=='x') yesno=!fl_isAutoscroll;
	if(yesno) {
	    fl_isAutoscroll=true;
	    try {
	    fl_offsetYSave=parseInt(floatingObject.style.top)-document.body.scrollTop;
	    if(fl_offsetYSave<16) {
		fl_offsetYSave=16;
		floatingObject.style.top=(fl_offsetYSave+document.body.scrollTop)+'px';
	    }
	    } catch(e) {}
	    if(window.onscroll!=onScroll) fl_onScrollSave=window.onscroll;
	    window.onscroll=onScroll;
	} else {
	    fl_isAutoscroll=false;
	    if(window.onscroll==onScroll) window.onscroll=fl_onScrollSave;
	    fl_onScrollSave=null;
	}
    }
    function onScroll(evt) {	// Event Handler
	if(isIE) evt=event;
	floatingObject.style.top=(fl_offsetYSave+document.body.scrollTop)+'px';
	if(fl_onScrollSave) fl_onScrollSave(evt);
    }
    function debugObj(obj) {
	var s="";
	// s+="<b><u>Object: "+obj.type?obj.type:""+"</u></b><br>";
	for(var prop in obj) s+=prop+": "+obj[prop]+"\n";
	return(s);
    }
}
