/* -*- java -*- */
/*
 *  Copyright 2004 Mihai Parparita.
 *  Derived from: http://persistent.info/files/20040508.magnifier/
 *  Used under license.
 *
 *  Modified extensively (2006) by Alan Donovan.
 */

var kShadowPadding = 17;

// Note: need to edit the shadow.png to be this size, plus kShadowPadding
// around each edge:
var kMagnifierWidth = 550;
var kMagnifierHeight = 300;

function xPos(event) {
    if (event.pageX) {
	return event.pageX;
    } else {
	return event.clientX;
    }
}

function yPos(event) {
    if (event.pageY) {
	return event.pageY;
    } else {
	return event.clientY;
    }
}

function MagnifierPosition()
{
    // -1 to account for the border
    this.style.left =
	Math.round(this.xPosition - 1 - this.width/2) + "px";
    this.style.top =
	Math.round(this.yPosition - 1 - this.height/2) + "px";

    this.shadow.style.left =
	Math.round(this.xPosition - this.width/2 - kShadowPadding) + "px";
    this.shadow.style.top =
	Math.round(this.yPosition - this.height/2 - kShadowPadding) + "px";

    var magnifierCenterX =
	Math.round(this.xPosition * this.xMultiplier - this.width/2);
    var magnifierCenterY =
	Math.round(this.yPosition * this.yMultiplier - this.height/2);

    this.style.backgroundPosition = -magnifierCenterX + "px " +
	-magnifierCenterY + "px";
}

function BaseButtonClick(event)
{
    if (!event) {
	event = window.event;
    }

    var base = event.currentTarget || event.srcElement;

    var magnifier = base.magnifier;
    magnifier.on = !magnifier.on; // toggle state

    // Center magnifier on event position:
    magnifier.xPosition = event.layerX; // layerX/Y is relative to img topleft.
    magnifier.yPosition = event.layerY;

    magnifier.render();
}

function MagnifierRender()
{
    if (!this.on) {
	this.shadow.style.display = "none";
	this.style.display = "none";

    } else {
	var shadow = this.shadow;
	var shadowWidth = this.width + 2 * kShadowPadding;
	var shadowHeight = this.height + 2 * kShadowPadding;

	// MSIE 5.x/6.x must be treated specially in order to make them use the
	// PNG alpha channel
	var shadowImageSrc = "/images/shadow-584x334.png";
	if (shadow.runtimeStyle) {
	    shadow.runtimeStyle.filter =
		"progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"
		+ shadowImageSrc + "', sizingMethod='scale')";
	} else {
	    shadow.style.backgroundImage = "url(" + shadowImageSrc + ")";
	    shadow.style.width = shadowWidth + "px";
	    shadow.style.height = shadowHeight + "px";
	    shadow.style.display = "block";

	    if (this.runtimeStyle) {
		// msie counts the border as being part of the width
		this.width += 2; this.height += 2; // must compensate
	    }

	    this.style.width = this.width + "px";
	    this.style.height = this.height + "px";
	    this.style.display = "block";
	    this.position();
	}
    }
}

function MagnifierMouseDown(event)
{
    if (!event) {
	event = window.event;
    }

    document.body.magnifier = this; // used by document.body.MagnifierDrag
    this.inDrag = true;
    this.startX = xPos(event);
    this.startY = yPos(event);
    this.savedCursor = this.style.cursor;
    this.style.cursor = "crosshair";
}

function MagnifierMouseUp(event)
{
    if (!event) {
	event = window.event;
    }

    if (this.inDrag) {
	this.inDrag = false;
	this.style.cursor = this.savedCursor;
 	document.body.magnifier = null; // used by document.body.MagnifierDrag
    }
}

// Note: this == document.body!
function MagnifierDrag(event)
{
    if (!event) {
	event = window.event;
    }

    var magnifier = this.magnifier;

    if (magnifier && magnifier.inDrag) {
	var eventX = xPos(event);
	var eventY = yPos(event);

	magnifier.xPosition += eventX - magnifier.startX;
	magnifier.yPosition += eventY - magnifier.startY;

	magnifier.startX = eventX;
	magnifier.startY = eventY;

	magnifier.position();
    }
}

function MagnifierButtonClick(event)
{
    if (!event) {
	event = window.event;
    }

    event.stopPropagation(); // don't continue up and fire BaseButtonClick!
};

function loadMagnifier(baseID, zoomedURL, zoomedWidth, zoomedHeight)
{
    // get the zoomed image (load as early as possible)
    var zoomedImage = document.createElement("img");
    zoomedImage.src = zoomedURL;

    // get the div's
    var base = document.getElementById(baseID);
    if (base == null) {
      // This is quite normal if the image has been suppressed.
      // alert("couldn't find base for magnifier " + baseID);
	return;
    }

    var magnifier = document.createElement("div");

    // get the regular image
    var normalImage = null;
    for (var i = 0; i < base.childNodes.length; i++) {
	if (base.childNodes[i].tagName &&
	    base.childNodes[i].tagName.toLowerCase() == "img") {
	    normalImage = base.childNodes[i];
	    break;
	}
    }

    if (normalImage == null) {
	alert("couldn't find normal image for magnifier " + baseID);
	return;
    }

    magnifier.on = false;

    magnifier.xMultiplier = zoomedWidth/normalImage.width;
    magnifier.yMultiplier = zoomedHeight/normalImage.height;

    magnifier.width = kMagnifierWidth;
    magnifier.height = kMagnifierHeight;

    // Start position (relative to image origin):
    magnifier.xPosition = normalImage.width / 2;
    magnifier.yPosition = normalImage.height / 2;

    magnifier.id = baseID + "Magnifier";
    magnifier.className = "magnifier";

    // styles (only dynamic ones, rest are part of the class)
    magnifier.style.backgroundImage = "url(" + zoomedURL + ")";

    // Add close button
    var closeButton = document.createElement("img");
    closeButton.src = "/images/close.gif";
    closeButton.style.position = "absolute";
    closeButton.style.right = 0;
    closeButton.style.top = 0;
    closeButton.onclick = function(event) {
	magnifier.on = false;
	magnifier.render();
    }
    closeButton.style.cursor = "default";
    magnifier.appendChild(closeButton);

    // Event handlers:
    base.onclick = BaseButtonClick;
    magnifier.onmousedown = MagnifierMouseDown;
    magnifier.onmouseup = MagnifierMouseUp;
    magnifier.onclick = MagnifierButtonClick;

    // we attach this handler to the body because if the user moves
    // the mouse fast enough, it'll go outside the boundaries of the
    // magnifier, and then the magnifier's mousemove handler won't fire
    document.body.onmousemove = MagnifierDrag;

    magnifier.position = MagnifierPosition;
    magnifier.render = MagnifierRender;

    // shadow
    var shadow = document.createElement("div");
    shadow.id = baseID + "MagnifierShadow";
    shadow.className = "magnifierShadow";

    // point objects at each other
    base.magnifier = magnifier;
    magnifier.shadow = shadow;

    // add to document and lay out
    base.appendChild(shadow);
    base.appendChild(magnifier);
    magnifier.render(); // also positions
}
