
var gList,
    mList,
    zoomRemove=null,
    sGuru,
    lastID,
    currentZoomImage=null,
    pendingBookmark=null,
    fff,
    modelsVisible=false,
    nextTitle="",
    fixedMenus=false,
    fixedFilter=false;

function init(){
    setupZoom();
    window.onscroll = checkPositions;
    window.onresize = onResized;
    includeCaption=false;
}
function config()
{
    location.href="vms-config.jsp?vmsQreg";
}

function checkPositions()
{    
//xGetElementById("scPos").innerHTML = posTop();
    if (navigator.appName.indexOf("Microsoft")>=0)
        return crappyBrowserVersion();
        
    if (posTop()>=200 && !fixedMenus){
        fixedMenus=true;        
//        document.getElementById("topMenu").style.top=0;
//        document.getElementById("topMenu").style.left=getElementPosition("topBar")+"px"; 
//        document.getElementById("topMenu").style.position="fixed";        
        document.getElementById("leftColumn").style.top=0;
        document.getElementById("leftColumn").style.left=getElementPosition("leftColumn")+"px";
        document.getElementById("leftColumn").style.position="fixed";
        document.getElementById("rightColumn").style.top=0;
        document.getElementById("rightColumn").style.right=null;
        document.getElementById("rightColumn").style.left=getElementPosition("rightColumn")+"px";         
        document.getElementById("rightColumn").style.position="fixed";
    }else if (posTop()<200 && fixedMenus){    
//        document.getElementById("topMenu").style.position="absolute";
//        document.getElementById("topMenu").style.top=92+"px";
//
        document.getElementById("leftColumn").style.position="absolute";
        document.getElementById("leftColumn").style.top=170+"px";
        document.getElementById("leftColumn").style.left=10+"px";
        document.getElementById("rightColumn").style.position="absolute";
        document.getElementById("rightColumn").style.top=170+"px";
        document.getElementById("rightColumn").style.left=null;
        document.getElementById("rightColumn").style.right=10+"px";
        fixedMenus=false;
    }    
    return true;
}
function crappyBrowserVersion()
{
    return true;
    if (posTop()>=120){    
//        document.getElementById("topMenu").style.top=posTop();        
        document.getElementById("leftColumn").style.top=posTop();  
        document.getElementById("rightColumn").style.top=posTop();
    }else if (posTop()<120){            
//        document.getElementById("topMenu").style.top=92+"px";              
        document.getElementById("leftColumn").style.top=0+"px"; 
        document.getElementById("rightColumn").style.top=0+"px";        
    }    
    return true;
}
function styleGuru()
{
//    if (xGetElementById("q6").style.visibility!="hidden";
    gList = xGetElementById("glassesList");
    sGuru = xGetElementById("styleAdviserDiv");
    gList.style.display="none";
    xGetElementById("mainContent").appendChild(sGuru);
    sGuru.style.display="block";
}
function adviseMe()
{
    sGuru.style.display="none";
//    refresh();
    gList.style.display="block";
}
function changeModel()
{
    var w = xWidth("modelPicker");
    var h = xHeight("modelPicker");
    var x = (xClientWidth()-w)/2;
    var y = (xClientHeight()-h)/2;
    if (y<0)
        y=10;
    xMoveTo("modelPicker",x+xScrollLeft(),y+xScrollTop());
    opacity("modelPicker", 0, 100, 300);
    modelsVisible=true;
}
function toggleModels()
{
	if (modelsVisible==false){
        if (crappyBrowser)
            location.href="chooseModel.jsp";
        else
            changeModel();	   
	}else{	
		opacity("modelPicker", 100, 0, 300);
		modelsVisible=false;
	}
}
function vmsModel(id)
{
    document.getElementById("vmsLoading").innerHTML="<img src=\"images/loading.gif\" alt=\"Loading...\" />";
    makeRequest("http://www.specsonthenet.co.uk/servlet/VMS_Handler",
                "load=-"+id, vmsLoaded);
}
function vmsLoaded(httpRequest)
{
    if (httpRequest.readyState==4){
        if (httpRequest.status==200){
            if (xGetElementById("modelPicker").style.visibility == "visible"){
                if (crappyBrowser)
                    xGetElementById("modelPicker").style.visibility="hidden";
                else
                    opacity("modelPicker", 100, 0, 300);
            }
            var r = httpRequest.responseXML;               
            if(document.all){
                r=new ActiveXObject("Microsoft.XMLDOM");
                r.async="false";
                r.loadXML(httpRequest.responseText);
            }    
            if (r.getElementsByTagName('oops').length>0){
                alert(httpRequest.responseText);
                return;
            }else{
    //alert(httpRequest.responseText);        
                var vids = r.getElementsByTagName('loaded');
                if (vids.length==0){
                    alert("oops: no loaded tag found");
                    return;
                }
                vid = vids[0].firstChild.data;
                createCookie("vmid", vid, 30);
                xGetElementById("portraitIcon").src=r.getElementsByTagName('icon')[0].firstChild.data;
                if(pendingBookmark!=null)
                    addBookmark(pendingBookmark);
//                xGetElementById("ids").innerHTML = "cid:"+cid+", vid:"+ vid +", oid="+oid;
            }
        }else{
            alert("oops: "+httpRequest.status);
        }
        modelsVisible=false;
    }
}
function addBookmark(id)
{
    pendingBookmark=id;
    if (vid<=0){
        var vmid = readCookie("vmid");
        if (isNaN(vmid))
            vmid=0;        
        if (vmid>0){
            document.getElementById("vmsLoading").innerHTML="<img src=\"images/loading.gif\" alt=\"Loading...\" />";
            makeRequest("http://www.specsonthenet.co.uk/servlet/VMS_Handler",
                "load="+readCookie("vmid"), vmsLoaded);
        }else{
            if (crappyBrowser)
    	        location.href="chooseModel.jsp?frame="+escape(id);
    	    else
                changeModel();            
        }
    }else{    
        var thumb = checkShortlist(frames[id].code,frames[id].colour);
        xGetElementById("bookmarkTitle").innerHTML=frames[id].manu+" "+frames[id].code;
        if (thumb==null){            
            xGetElementById("addBookmark"+id).src="images/bookmarkLoader.gif";            
            makeRequest("http://www.specsonthenet.co.uk/servlet/VMS_Handler",
                    "bookmark=" +frames[id].code +"&colour=" +frames[id].colour +"&custId="+cid,
                    bookmarkSaved);
        }else{
        
            toggleZoom(thumb);
        }
    }
}
function checkShortlist(code, colour)
{
    var sl = xGetElementById("myFrames").childNodes;
    var i=0;
    if (colour.indexOf(":")>=0)
        colour=colour.substring(0,colour.indexOf(":"));    
    for (i=0; i<sl.length; ++i){
        if (sl[i].tagName!="IMG")
            continue;
        if (sl[i].src.indexOf(code+"_"+colour)>=0)
            return sl[i];
    }
    return null;
}
function okBookmark()
{
    zoomOut(null, null);
}
function removeBookmark()
{
    zoomRemove = xGetElementById("ZoomImage").src;
    zoomOut(null, null);
    makeRequest("http://www.specsonthenet.co.uk/servlet/VMS_Handler",
                "remove="+zoomRemove,
                bookmarkRemoved);
}
function removeBookSnap()
{
    if (zoomRemove==null)
        return;
    var kids = xGetElementById("myFrames").childNodes;
    for(var i=0; i<kids.length; ++i)
        if (kids[i].src==zoomRemove){
            xGetElementById("myFrames").removeChild(kids[i]);
            break;
        }
    zoomRemove=null;
    var flen = 0;
    for (var i=0; i<xGetElementById("myFrames").childNodes.length; ++i){
//alert("child "+i+" is a "+xGetElementById("myFrames").childNodes[i].tagName);    
        if (xGetElementById("myFrames").childNodes[i].tagName=="IMG")        
            ++flen;
    } 
    if (flen==0){  
        xGetElementById("myShortIntro").style.display="block";
    }                
}
function confirmBookmark(zoomDiv)  // add the shaded info bar
{
    var w = xWidth(zoomDiv)-1;
    var h = xHeight(zoomDiv);
//alert("zd @ "+xPageX(zoomDiv)+","+ xPageY(zoomDiv)+" = "+w+" x "+h);       
    var x = xPageX(zoomDiv);
    var y = xPageY(zoomDiv)+16; // 10;    
    
    xWidth("bookmarkConfirm", w);
    xWidth("bookmarkTitleShadow", w);
    
    xMoveTo("bookmarkConfirm",x,y); // x+xScrollLeft(),y+xScrollTop());
    xMoveTo("bookmarkTitleShadow", x,y); // x+xScrollLeft()+1,y+xScrollTop());
    xGetElementById("bookmarkTitleShadow").style.display="block";
    xGetElementById("bookmarkConfirm").style.display="block";
}
function hideConfirmBookmark()
{
    xGetElementById("bookmarkConfirm").style.display="none";
    xGetElementById("bookmarkTitleShadow").style.display="none";
}
function bookmarkSaved(httpRequest)
{
    if (httpRequest.readyState==4){
        if (httpRequest.status==200){
//alert(httpRequest.responseText);    
            if (pendingBookmark!=null){
    //            xHide("addBookmark"+pendingBookmark);
                xGetElementById("addBookmark"+pendingBookmark).src="images/face2.png";
                pendingBookmark=null;
            }
            var r = httpRequest.responseXML;
            if(document.all){
                r=new ActiveXObject("Microsoft.XMLDOM");
                r.async="false";
                r.loadXML(httpRequest.responseText);
            }      
            if (r.getElementsByTagName('oops').length>0){
    //alert(httpRequest.responseText);
                return;
            }else{
                var manu=r.getElementsByTagName('manu')[0].firstChild.data;
                var code=r.getElementsByTagName('code')[0].firstChild.data;
                var colour=r.getElementsByTagName('colour')[0].firstChild.data;
                var colourDesc=r.getElementsByTagName('colourDesc')[0].firstChild.data;
                
                if (r.getElementsByTagName('url')[0].firstChild==null){
                    alert("Sorry! LookingGlass image coming soon..."); //("Error: No VMS image for frame "+code+":"+colour);
                    return;
                }
                var iURL=r.getElementsByTagName('url')[0].firstChild.data;
                var booksnap = document.createElement("img");
                xGetElementById("myShortIntro").style.display="none"; 
                booksnap.src = iURL;
                booksnap.className="zoom clickable shortListThumb";
                booksnap.style.width="144px";
                booksnap.style.height="70px";
                booksnap.style.margin="10px 0 0 0";
    	        booksnap.onclick = function (event) { toggleZoom(this); };
    	        booksnap.onload=function (event) { toggleZoom(this); };
    	        booksnap.title=manu+" "+code+" ("+colourDesc+")";
                if (xGetElementById("myFrames").childNodes.length==0)
                    xGetElementById("myFrames").appendChild(booksnap);
                else
                    xGetElementById("myFrames").insertBefore(booksnap,xGetElementById("myFrames").childNodes[0]);
            }
        }else
            alert("oops: "+httpRequest.status);  
    }
}
function bookmarkRemoved(httpRequest)
{
    if (httpRequest.readyState==4){
//alert(httpRequest.responseText);        
        if (httpRequest.status==200){
            removeBookSnap();
        }
    }
}
function answer(id)
{
    if (id==6)
        xShow("goGuru");
    else
        xShow("q"+(++id));
}

var fixedMenus=false;
var fixedFilter=false;
var lastId=-1;
var crappyBrowser = navigator.appName.indexOf("Microsoft")>=0;

function infoPage(id,colour)
{
    document.location.href="glasses_info.jsp?code="+escape(id)+"&colour="+escape(colour);
}
function refresh()
{
    var form = xGetElementById("frameFilterForm");
    var frameType=form.frameType.value;
    var colour=form.frameColour.value;
    var lensType="all"; // form.lensType.value;
    var colours = "GOLD:SILVER:BROWN:GUN METAL:BLACK";
    var fList="";
    listLen=0;
    for (var i=0; i<frames.length; ++i){
        if (frameType!="all" && frameType!=frames[i].frameType)
            continue;
        if (colour!="all" && colour!="colours" && colour!=frames[i].baseColour)
            continue;
        if (colour=="colours" && colours.indexOf(frames[i].baseColour)<0)
            continue;
        if (lensType=="biFocal" && frames[i].lensHeight<28)
            continue;
        if (lensType=="variFocal" && frames[i].lensHeight<32)
            continue;
        fList += "<div id='f" +i +"' class='specsPanel' onclick=\"infoPage('" +frames[i].code +"','"
              + frames[i].colour+"');\" onmouseover=\"details('"  +i  +"');\">"
              + "<img id=\"addBookmark" +i +"\" title=\"Add to Shortlist\" class=\"bookmark clickable\" style=\"width:21px;height:21px;z-index:5\" onclick=\"addBookmark(" +i+ ");\" src=\"images/face2.png\" alt=\"Add to shortlist\" />"
              + "<h3><a href='glasses_info.jsp?code=" +escape(frames[i].code) +"&colour="+escape(frames[i].colour) +"'>" +frames[i].manu+" "+frames[i].code+"</h3>"
              + "<img src='" +frames[i].thumb.src +"'/><p>" +frames[i].price +"</p></div>";
        ++listLen;
    }
    if (listLen==0)
        fList = "<p style=\"margin:150px auto;text-align:center;font-size:160%;font-weight:bold;\">no matches</p>";
    xGetElementById("glassesList").innerHTML=fList;
//    xGetElementById("frameCounter").innerHTML=listLen;
}
function selectDesigner()
{
    nextTitle = "Prescription Glasses by "+xGetElementById("frameManu").value;
    makeRequest("http://www.specsonthenet.co.uk/servlet/FrameSearch", "manu="+xGetElementById("frameManu").value , updateFrameSearch);
    fff = xGetElementById("frameFilterForm");
    xGetElementById("frameFilterPanel").removeChild(fff);
    xGetElementById("frameFilterPanel").appendChild(xGetElementById("frameLoader"));
    xGetElementById("frameLoader").style.display="block";
}
function updateFrameSearch(httpRequest)
{
    if (httpRequest.readyState==4){
        if (httpRequest.status==200){
//alert(httpRequest.responseText);        
            xGetElementById("glassesList").innerHTML="";
            
            var r = httpRequest.responseXML;
            if(document.all){
                r=new ActiveXObject("Microsoft.XMLDOM");
                r.async="false";
                r.loadXML(httpRequest.responseText);
            }  
            
            var res = r.getElementsByTagName("frame");
            window.status = "found "+res.length+" frames";
            if (nextTitle!=""){
                xGetElementById("listTitle").innerHTML = nextTitle;
                nextTitle="";
            }
            for (var i=0; i<res.length; ++i){
                var f = new Frame(  getNodeValue(res[i],'code'),
                                    getNodeValue(res[i],'manu'),
                                    getNodeValue(res[i],'name'),
                                    getNodeValue(res[i],'price'),
                                    getNodeValue(res[i],'colour'),
                                    getNodeValue(res[i],'baseColour'),
                                    getNodeValue(res[i],'size'),
                                    getNodeValue(res[i],'lensWidth'),
                                    getNodeValue(res[i],'bridgeWidth'),
                                    getNodeValue(res[i],'armLength'),
                                    getNodeValue(res[i],'lensHeight'),
                                    getNodeValue(res[i],'overallWidth'),
                                    getNodeValue(res[i],'frameType'),
                                    getNodeValue(res[i],'lensShape'),
                                    getNodeValue(res[i],'hinge'),
                                    getNodeValue(res[i],'sex'),
                                    getNodeValue(res[i],'url')
                                 );
                var alreadyLoaded = false;
                for (var j=0; j<frames.length; ++j){
                    if (frames[j].code==f.code && frames[j].colour==f.colour){
                        alreadyLoaded=true;
                        break;
                    }
                }
                if (alreadyLoaded==false){
                    var fid = frames.length;
                    frames.push(f);
                    var nf = "<div id='f" +fid +"' class='specsPanel' onclick=\"infoPage('" +f.code +"','"
                           + f.colour+"');\" onmouseover=\"details('"  + fid  +"');\">"
                           + "<img id=\"addBookmark" +i +"\" title=\"Add to Shortlist\" class=\"bookmark clickable\" style=\"width:21px;height:21px;z-index:5\" onclick=\"addBookmark(" +i+ ");\" src=\"images/face2.png\" alt=\"Add to shortlist\" />"
                           + "<h3><a href='glasses_info.jsp?code=" +escape(f.code) +"&colour="+escape(f.colour)+"'>" +f.manu+" "+f.code+"</h3>"
                           + "<img src='" +f.thumb.src +"'/><p>" +f.price +"</p></div>";
                    xGetElementById("glassesList").innerHTML += nf; // + xGetElementById("glassesList").innerHTML;
                }
            }
            var fl = xGetElementById("frameLoader");
            xGetElementById("frameFilterPanel").removeChild(fl);
            fl.style.display="none";
            document.body.appendChild(fl);
            xGetElementById("frameFilterPanel").appendChild(fff);
//            pageResized();
        }else{
            alert("Sorry, there was a problem retrieving the search results.");
        }
    }
}
function getNodeValue(obj,tag)
{
    try{
	   return obj.getElementsByTagName(tag)[0].firstChild.nodeValue;
	}catch(exception)
    {}
	return null;
}
function reset()
{
    document.getElementById("Metal").checked=true;
    document.getElementById("Plastic").checked=true;
    document.getElementById("Supra").checked=true;
    document.getElementById("Rimless").checked=true;
    document.getElementById("hypo").checked=true;
    document.getElementById("rectangular").checked=true;
    document.getElementById("oval").checked=true;
    document.getElementById("round").checked=true;
    document.getElementById("square").checked=true;
    document.getElementById("gold").checked=true;
    document.getElementById("silver").checked=true;
    document.getElementById("bronze").checked=true;
    document.getElementById("black").checked=true;
    document.getElementById("coloured").checked=true;
    document.getElementById("biFocal").checked=false;
    document.getElementById("variFocal").checked=false;
    refresh();
}
function clearFilter()
{
    document.getElementById("Metal").checked=false;
    document.getElementById("Plastic").checked=false;
    document.getElementById("Supra").checked=false;
    document.getElementById("Rimless").checked=false;
    document.getElementById("hypo").checked=false;
    document.getElementById("rectangular").checked=false;
    document.getElementById("oval").checked=false;
    document.getElementById("round").checked=false;
    document.getElementById("square").checked=false;
    document.getElementById("gold").checked=false;
    document.getElementById("silver").checked=false;
    document.getElementById("bronze").checked=false;
    document.getElementById("black").checked=false;
    document.getElementById("coloured").checked=false;
    document.getElementById("biFocal").checked=false;
    document.getElementById("variFocal").checked=false;
    refresh();
}
function isChecked(id)
{
    return document.getElementById(id).checked ? id : "";
}
function details(id)
{
    var f = frames[id];
    var t = xGetElementById("detailsTable");
    t.rows[0].cells[1].innerHTML = f.frameType;
    t.rows[1].cells[1].innerHTML = (f.hinges=="Flex" ? "yes" : "no");
    t.rows[2].cells[1].innerHTML = f.armLength;
    t.rows[3].cells[1].innerHTML = f.lensWidth;
    t.rows[4].cells[1].innerHTML = f.lensHeight;
    t.rows[5].cells[1].innerHTML = f.bridgeWidth;
    t.rows[6].cells[1].innerHTML = (f.frameType=="Plastic" ? "no" : "yes");
    t.rows[7].cells[1].innerHTML = f.overallWidth;
    t.rows[8].cells[1].innerHTML = (f.lensHeight>=28 ? "yes" : "no");
    t.rows[9].cells[1].innerHTML = (f.lensHeight>=30 ? "yes" : "no");
    
    if (lastId>=0)
        document.getElementById("f"+lastId).style.borderColor="WHITE";
    document.getElementById("f"+id).style.borderColor="BLUE";
    lastId=id;
}
function posTop(){
    return typeof window.pageYOffset != 'undefined'
        ? window.pageYOffset : document.documentElement && document.documentElement.scrollTop
        ? document.documentElement.scrollTop : document.body.scrollTop
        ? document.body.scrollTop : 0;
}
function getElementPosition(elemID){
    var offsetTrail = document.getElementById(elemID);
    var offsetLeft = 0;
    var offsetTop = 0;
    while (offsetTrail){
        offsetLeft += offsetTrail.offsetLeft;
        offsetTop += offsetTrail.offsetTop;
        offsetTrail = offsetTrail.offsetParent;
    }
    if (navigator.userAgent.indexOf('Mac') != -1 && typeof document.body.leftMargin != 'undefined'){
        offsetLeft += document.body.leftMargin;
        offsetTop += document.body.topMargin;
    }
//    return {left:offsetLeft,top:offsetTop};
    return offsetLeft;
}

function onResized()
{
    var leftMargin = 175;
    var rightMargin = 165;
    var rem = xWidth("mainColumn") % 240;
    xGetElementById("mainContent").style.marginLeft = (rem/2)+"px";
    createCookie("mainContentLeft",((rem/2)+"px"),24);
    window.status="content width="+xWidth("mainColumn")+" rem = "+rem;
    checkPositions();
}

function prepZooms() {
	if (! document.getElementsByTagName) {
		return;
	}
	var links = document.getElementsByTagName("img");
	for (i = 0; i < links.length; i++) {
		if (links[i].getAttribute("src").search(/(.*)\.(jpg|jpeg|gif|png|bmp|tif|tiff)/gi) != -1) {
			if (links[i].getAttribute("class") == "zoom") {
//				links[i].onclick = function (event) { return zoomClick(this, event); };
//				links[i].onmouseover = function () { zoomPreload(this); };
	           links[i].style.cursor="url(images/zoom/zoomin.cur), auto";
	           links[i].onclick = function (event) { toggleZoom(this); };
//	           links[i].onmouseout = function (event) { return zoomOut(this, event); };
			}
		}
	}
}

// Zoom: Load an image into an image object. When done loading, function sets preloadActive to false,
// so other bits know that they can proceed with the zoom.
// Preloaded image is stored in imgPreload and swapped out in the zoom function.
function toggleZoom(from){

    if (crappyBrowser){
        window.open(from.src, "_blank", "height=830,width=630,directories=0,menubar=0,toolbar=0,location=0,statusbar=0,", true);     
    }else{    
        if (zoomOpen && currentZoomImage==from){
            zoomOut(from);
            currentZoomImage=null;
            xGetElementById(from).style.cursor="url(images/zoom/zoomin.cur), auto";
        }else{
            if (currentZoomImage!=from){
                zoomOpen = false;
            	zoomOrigH[theID] = "";
            	zoomOrigW[theID] = "";
            	zoomdiv.style.visibility = "hidden";
            	xGetElementById("ShadowBox").style.visibility = "hidden";
            	xGetElementById("bookmarkConfirm").style.display="none";
                xGetElementById("bookmarkTitleShadow").style.display="none";
            	zoomActive[theID] == false;
            }
            if (from.title!=null){
                var ztitle = from.title;
                if (ztitle.indexOf("(")>=0)
                    ztitle=ztitle.substring(0,ztitle.indexOf("("));
                xGetElementById("bookmarkTitle").innerHTML=ztitle;        
            }
            zoomPreload(from);
            currentZoomImage=from;
        	xGetElementById(from).style.cursor="url(images/zoom/zoomout.cur), auto";
        }            
	}
}
function zoomPreload(from) {

	var theimage = from.getAttribute("src");

	// Only preload if we have to, i.e. the image isn't this image already

	if (imgPreload.src.indexOf(from.getAttribute("src").substr(from.getAttribute("src").lastIndexOf("/"))) == -1) {
		preloadActive = true;
		imgPreload = new Image();

		// Set a function to fire when the preload is complete, setting flags along the way.

		imgPreload.onload = function() {
			preloadActive = false;
		}

		// Load it!
		imgPreload.src = theimage;
		preloadActive = false;
	}
	zoomClick(from);
}
// Zoom: Move an element in to endH endW, using zoomHost as a starting point.
// "from" is an object reference to the href that spawned the zoom.

function zoomIn(from, shift) {

	zoomimg.src = from.getAttribute("src");

	// Determine the zoom settings from where we came from, the element in the <a>.
	// If there's no element in the <a>, or we can't get the width, make stuff up

	if (from.width) {
		startW = from.width;
		startH = from.height;
		startPos = findElementPos(from);
	} else {
		startW = 50;
		startH = 12;
		startPos = findElementPos(from);
	}

	hostX = startPos[0];
	hostY = startPos[1];

	// Make up for a scrolled containing div.
	// TODO: This HAS to move into findElementPos.

	if (document.getElementById('scroller')) {
		hostX = hostX - document.getElementById('scroller').scrollLeft;
	}

	// Determine the target zoom settings from the preloaded image object

	endW = imgPreload.width;
	endH = imgPreload.height;

	// Start! But only if we're not zooming already!

	if (zoomActive[theID] != true) {

		// Clear everything out just in case something is already open
        
		if (document.getElementById("ShadowBox")) {
			document.getElementById("ShadowBox").style.visibility = "hidden";
		} else if (! browserIsIE) {

			// Wipe timer if shadow is fading in still
			if (fadeActive["ZoomImage"]) {
				clearInterval(fadeTimer["ZoomImage"]);
				fadeActive["ZoomImage"] = false;
				fadeTimer["ZoomImage"] = false;
			}

			document.getElementById("ZoomImage").style.webkitBoxShadow = shadowSettings + '0.0)';
		}

		document.getElementById("ZoomClose").style.visibility = "hidden";

		// Setup the CAPTION, if existing. Hide it first, set the text.

		if (includeCaption) {
			document.getElementById(zoomCaptionDiv).style.visibility = "hidden";
			if (from.getAttribute('title') && includeCaption) {
				// Yes, there's a caption, set it up
				document.getElementById(zoomCaption).innerHTML = from.getAttribute('title');
			} else {
				document.getElementById(zoomCaption).innerHTML = "";
			}
		}

		// Store original position in an array for future zoomOut.

		zoomOrigW[theID] = startW;
		zoomOrigH[theID] = startH;
		zoomOrigX[theID] = hostX;
		zoomOrigY[theID] = hostY;

		// Now set the starting dimensions

		zoomimg.style.width = startW + 'px';
		zoomimg.style.height = startH + 'px';
		zoomdiv.style.left = hostX + 'px';
		zoomdiv.style.top = hostY + 'px';

		// Show the zooming image container, make it invisible

		if (includeFade == 1) {
			setOpacity(0, zoomID);
		}
		zoomdiv.style.visibility = "visible";

		// If it's too big to fit in the window, shrink the width and height to fit (with ratio).

		sizeRatio = endW / endH;
		if (endW > myWidth - minBorder) {
			endW = myWidth - minBorder;
			endH = endW / sizeRatio;
		}
		if (endH > myHeight - minBorder) {
			endH = myHeight - minBorder;
			endW = endH * sizeRatio;
		}

        xWidth("bookmarkTitleShadow", (endW-2));                

		zoomChangeX = ((myWidth / 2) - (endW / 2) - hostX);
		zoomChangeY = (((myHeight / 2) - (endH / 2) - hostY) + myScroll);

		zoomChangeW = (endW - startW);
		zoomChangeH = (endH - startH);

		// Shift key?
        if (crappyBrowser)
            zoomSteps=1;

		if (shift) {
			tempSteps = zoomSteps * 7;
		} else {
			tempSteps = zoomSteps;
		}

// Setup Zoom

		zoomCurrent = 0;

// Setup Fade with Zoom, If Requested

		if (includeFade == 1) {
			fadeCurrent = 0;
			fadeAmount = (0 - 100) / tempSteps;
		} else {
			fadeAmount = 0;
		}

// Do It!
            
        zoomTimer[theID] = setInterval("zoomElement('"+zoomID+"', '"+theID+"', "+zoomCurrent+", "+startW+", "+zoomChangeW+", "+startH+", "+zoomChangeH+", "+hostX+", "+zoomChangeX+", "+hostY+", "+zoomChangeY+", "+tempSteps+", "+includeFade+", "+fadeAmount+", 'zoomDoneIn(zoomID)')", zoomTime);
		zoomActive[theID] = true;
	}
}
function zoomDoneIn(zoomdiv, theID) {

	// Note that it's open

	zoomOpen = true;
	
	confirmBookmark(zoomdiv); // add the info bar
	
	zoomdiv = document.getElementById(zoomdiv);    

    // Position the table shadow behind the zoomed in image, and display it

	if (document.getElementById("ShadowBox")) {

		setOpacity(0, "ShadowBox");
		shadowdiv = document.getElementById("ShadowBox");

		shadowLeft = parseInt(zoomdiv.style.left) - 12;
		shadowTop = parseInt(zoomdiv.style.top) - 8;
		shadowWidth = zoomdiv.offsetWidth + 24;
		shadowHeight = zoomdiv.offsetHeight + 25;

		shadowdiv.style.width = shadowWidth + 'px';
		shadowdiv.style.height = shadowHeight + 'px';
		shadowdiv.style.left = shadowLeft + 'px';
		shadowdiv.style.top = shadowTop + 'px';

		document.getElementById("ShadowBox").style.visibility = "visible";
		fadeElementSetup("ShadowBox", 0, 100, 5);

	} else if (! browserIsIE) {
		// Or, do a fade of the modern shadow
		fadeElementSetup("ZoomImage", 0, .8, 5, 0, "shadow");
	}

	// Position and display the CAPTION, if existing

	if (includeCaption && document.getElementById(zoomCaption).innerHTML != "") {
		// setOpacity(0, zoomCaptionDiv);
		zoomcapd = document.getElementById(zoomCaptionDiv);
		zoomcapd.style.top = parseInt(zoomdiv.style.top) + (zoomdiv.offsetHeight + 15) + 'px';
		zoomcapd.style.left = (myWidth / 2) - (zoomcapd.offsetWidth / 2) + 'px';
		zoomcapd.style.visibility = "visible";
		// fadeElementSetup(zoomCaptionDiv, 0, 100, 5);
	}

	// Display Close Box (fade it if it's not IE)

	if (!browserIsIE) setOpacity(0, "ZoomClose");
	document.getElementById("ZoomClose").style.visibility = "visible";
	if (!browserIsIE) fadeElementSetup("ZoomClose", 0, 100, 5);

	// Get keypresses
	document.onkeypress = getKey;

}
function zoomOut(from, evt) {

	// Get shift key status.
	// IE events don't seem to get passed through the function, so grab it from the window.

	if (getShift(evt)) {
		tempSteps = zoomSteps * 7;
	} else {
		tempSteps = zoomSteps;
	}

	// Check to see if something is happening/open

	if (zoomActive[theID] != true) {

	   hideConfirmBookmark();

		// First, get rid of the shadow if necessary.

		if (document.getElementById("ShadowBox")) {
			document.getElementById("ShadowBox").style.visibility = "hidden";
		} else if (! browserIsIE) {

			// Wipe timer if shadow is fading in still
			if (fadeActive["ZoomImage"]) {
				clearInterval(fadeTimer["ZoomImage"]);
				fadeActive["ZoomImage"] = false;
				fadeTimer["ZoomImage"] = false;
			}

			document.getElementById("ZoomImage").style.webkitBoxShadow = shadowSettings + '0.0)';
		}

		// ..and the close box...

		document.getElementById("ZoomClose").style.visibility = "hidden";

		// ...and the caption if necessary!

		if (includeCaption && document.getElementById(zoomCaption).innerHTML != "") {
			// fadeElementSetup(zoomCaptionDiv, 100, 0, 5, 1);
			document.getElementById(zoomCaptionDiv).style.visibility = "hidden";
		}

		// Now, figure out where we came from, to get back there

		startX = parseInt(zoomdiv.style.left);
		startY = parseInt(zoomdiv.style.top);
		startW = zoomimg.width;
		startH = zoomimg.height;
		zoomChangeX = zoomOrigX[theID] - startX;
		zoomChangeY = zoomOrigY[theID] - startY;
		zoomChangeW = zoomOrigW[theID] - startW;
		zoomChangeH = zoomOrigH[theID] - startH;

		// Setup Zoom

		zoomCurrent = 0;

		// Setup Fade with Zoom, If Requested

		if (includeFade == 1) {
			fadeCurrent = 0;
			fadeAmount = (100 - 0) / tempSteps;
		} else {
			fadeAmount = 0;
		}

		// Do It!

		zoomTimer[theID] = setInterval("zoomElement('"+zoomID+"', '"+theID+"', "+zoomCurrent+", "+startW+", "+zoomChangeW+", "+startH+", "+zoomChangeH+", "+startX+", "+zoomChangeX+", "+startY+", "+zoomChangeY+", "+tempSteps+", "+includeFade+", "+fadeAmount+", 'zoomDone(zoomID, theID)')", zoomTime);
		zoomActive[theID] = true;
	}
}
function zoomDone(zoomdiv, theID) {

	// No longer open

	zoomOpen = false;

	// Clear stuff out, clean up

	zoomOrigH[theID] = "";
	zoomOrigW[theID] = "";
	document.getElementById(zoomdiv).style.visibility = "hidden";
	zoomActive[theID] == false;

	// Stop getting keypresses

	document.onkeypress = null;
	
    removeBookSnap();
}

