/*
 * This class is used to display and position in-document popups.
 * Popups are referenced by id and such elements should already contain their content.
 * Initial visibility of such elements should be 'hidden'.
 * 
 * Handles popup positioning relative to cursor position within the browser window and 
 * the size of the popup to be displayed.  For instance, the default position of right and
 * below the cursor.  If the popup event is received from the far right of the browser window,
 * the popup will be displayed to the left and below the cursor instead.
 *
 * Also provides a partial implementation of popup chains (only level 1 chains tried so far)
 * A chain is a child[s] of a parent popup, positioned relative to the parent and closed if the parent closes.
 */
 
function QSPop(iname, preHideAction){
/* have to pass the name of the instance of this class to get the timers to fire the right methods.
 * wtb better way to do this.
 */
    var lastqs=null;
    var iname;
    var pha;
    document.onmousemove = getpos;
    var DELAY = 100;
    var lx,ly;
    var isIE=document.all; 
    var op;
    var chain,linkParents;
    
    this.pha = preHideAction;
    this.iname = iname;
    this.showqsnode = showqsnode;
    this.showqsnodeNow = showqsnodeNow;
    this.hideqsnode = hideqsnode;
    this.hideqsnodeNow = hideqsnodeNow;
    this.op = op;
    this.getMousePos = getMousePos;
    this.getpos = getpos;
    this.createChain = createChain;
    this.solidify = solidify;
    
    function createChain(newLink){
        if(chain)
            for(x=0;x<chain.length;x++)
                if(newLink.id == chain[x].id) return;//already up
        clearChain();
        var obj = document.createElement("div");    
        obj.innerHTML = newLink.innerHTML;
        obj.style.position = 'absolute';
        obj.style.zIndex = 100;
        obj.style.top = 0;
        obj.style.left = 0;
        obj.id = newLink.id;
        document.body.appendChild(obj);
        
        var l1 = parseInt(lastqs.style.left) + lastqs.offsetWidth;
        if((l1 + obj.offsetWidth) > (document.body.clientWidth))
		    obj.style.left = parseInt(lastqs.style.left)-obj.offsetWidth;//left
        else obj.style.left = l1;
        if((ly + obj.offsetHeight) > document.body.clientHeight)
            obj.style.top = document.body.clientHeight - obj.offsetHeight - 5;
        else
            obj.style.top = ly;
        chain = [obj];
        linkParents = [newLink.parentNode];
        newLink.parentNode.removeChild(newLink);//avoid id conflicts
    }
    function clearChain(){
        if(chain){
            for(i=0;i<chain.length;i++){
                var ci = chain[i];
                var obj = document.createElement("div");    
                obj.innerHTML = ci.innerHTML;
                obj.id = ci.id;
                obj.style.display = 'none';
                document.body.removeChild(ci);
                linkParents[i].appendChild(obj);                          
            }
        }
        chain = null;      
    }  
    function getMousePos(){
        return [lx,ly];
    }
    function hideqsnode(e){
        if(lastqs != null && lastqs.style.visibility == 'visible'){
            var z = iname+'.hideqsnodeNow()';
            window.setTimeout(z, DELAY);
        }
    }
    function hideqsnodeNow(e, op){
        if(lastqs == null){return;}
        mode = IDLE;     
        if(this.op != null && this.op == false){
            var ee = null;      
            if(e)ee = e.originalTarget;
            else if(window.event) ee = window.event.srcElement;
            var tmp = null;
            if(ee){
                tmp = ee;
                while(tmp != document){
                    if(tmp == null)return;//break?
                    if(tmp == lastqs){
                        return;
                    }
                    if(chain)
                        for(x=0;x<chain.length;x++)
                            if(tmp == chain[x])return;
                    try{
                        tmp = tmp.parentNode;
                    }catch(ex){return;}
                }          
            }   
        }else{}
        var cpy = lastqs;
        lastqs.style.visibility = 'hidden';
        lastqs = null;
        if(cpy != null && this.pha != null){
            this.pha(cpy);                   
        }
        clearChain();
        this.op = false;
    }
    function showqsnode(qsid, x, y){
      var z;
      if(x != null && y != null){
            z = iname+'.showqsnodeNow("'+qsid+'",'+x+','+y+')';
      }else
          z = iname+'.showqsnodeNow(\''+qsid+'\')';
      window.setTimeout(z, DELAY);
    }
    function showqsnodeNow(qsid, ox, oy){
        if(lastqs != null)this.hideqsnodeNow();
	    lastqs = document.getElementById(qsid);
	    lastqs.style.opacity = 0;
	    if(lastqs.innerHTML == '')return;
	    //sticking it at 0,0 first helps ensure offsetWidth will not be 0
	    lastqs.style.left = 0;
	    lastqs.style.top = 0;
	    lastqs.style.visibility = 'visible';
	    if(ox == null || oy == null){
	        if(lastqs.offsetWidth > document.body.clientWidth-lx)
		        lastqs.style.left = lx+document.body.scrollLeft-lastqs.offsetWidth-5;//left
	        else
		        lastqs.style.left = lx+document.body.scrollLeft+5;//right
	        if(parseInt(lastqs.style.left) < document.body.scrollLeft)
		        lastqs.style.left= document.body.scrollLeft;
	        if(lastqs.offsetHeight > document.body.clientHeight-ly)
		        lastqs.style.top = ly+document.body.scrollTop-lastqs.offsetHeight-5;//above
	        else
		        lastqs.style.top = ly+document.body.scrollTop+5;//below
	        if(parseInt(lastqs.style.top) < document.body.scrollTop)
		        lastqs.style.top = document.body.scrollTop;
		}else{
		    lastqs.style.top = oy;
		    lastqs.style.left = ox;
		}
	    lastqs.style.visibility = 'visible';
	    //lastqs.style.opacity = .1;
	    solidify(.1);
    }
    function solidify(s){
      if(lastqs){
          s = parseFloat(s);
          lastqs.style.opacity = s;
          lastqs.style.filter = 'alpha(opacity='+(s*100)+')';
          if(s >= 1) return;
          var z = iname+'.solidify(\''+(s+.1)+'\')';
          window.setTimeout(z, 25);
      }
    }
    function getpos(e){
	    if(isIE){
		    lx = event.clientX;
		    ly = event.clientY;
	    }else{
		    lx = e.clientX;
		    ly = e.clientY;
	    }
	    try{
	        node = e.target;
            while(node.id == null || node.id == ''){
	            node = node.parentNode;
                if(node == null)break;
	        }
	    }catch(ee){}
    }
}