function attachImageViewer(aElement)
{
    aElement.onclick = function() { enlargeImage(aElement); }
    aElement.style.cursor = "pointer";
}

function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
		curleft = obj.offsetLeft
		curtop = obj.offsetTop
		while (obj = obj.offsetParent) {
			curleft += obj.offsetLeft
			curtop += obj.offsetTop
		}
	}
	return [curleft,curtop];
}

var gScreening;
var gImageViewer;
var gCloseLabel;

function closeImageViewer()
{
    gScreening.style.display = 'none';
    gImageViewer.style.display = 'none';
    gCloseLabel.style.visibility = 'hidden';
}

function resetImageViewer(aImg)
{
    // Prepare / reset black screening div
    if(!gScreening)
    {
        gScreening = aImg.ownerDocument.createElement('div');
        gScreening.style.display = 'none'
        gScreening.style.position = 'absolute';
        gScreening.style.top = 0;
        gScreening.style.left = 0;
        gScreening.style.height = aImg.ownerDocument.body.scrollHeight;
        gScreening.style.width = aImg.ownerDocument.body.scrollWidth;
        gScreening.style.background = 'black';
        aImg.ownerDocument.body.appendChild(gScreening);
    } 

    gScreening.style.opacity = 0;
    gScreening.style.display = 'block';


    // Prepare image viewer
    if(!gImageViewer)
    {
        gImageViewer = aImg.ownerDocument.createElement('img');
        gImageViewer.className = 'imageViewer';
        gImageViewer.style.display = 'none';
        gImageViewer.style.position = 'absolute';
        aImg.ownerDocument.body.appendChild(gImageViewer);

        gImageViewer.onclick = closeImageViewer;
    }

    if(!gCloseLabel)
    {
        gCloseLabel = aImg.ownerDocument.createElement('div');
        gCloseLabel.className = 'imageViewerLabel';
        gCloseLabel.appendChild(aImg.ownerDocument.createTextNode('click to close'));
        aImg.ownerDocument.body.appendChild(gCloseLabel);
    }
    
    gCloseLabel.style.opacity = 0;
    gCloseLabel.style.visibility = 'hidden';
    
    var lPos = findPos(aImg);

    gImageViewer.src = aImg.src;
    gImageViewer._realWidth = gImageViewer.width;
    gImageViewer._realHeight = gImageViewer.height;
    gImageViewer.style.left = lPos[0]-4;
    gImageViewer.style.top = lPos[1]-4;
    gImageViewer.style.width = aImg.style.width;
    gImageViewer.style.height = aImg.style.height;
}

function enlargeImage(aSrcElement)
{
    var lSrcElem = aSrcElement;
    resetImageViewer(lSrcElem);

    var lDrv = new AnimationDriver(50);

    var lSeq = new AnimateSequence();


    var lShowViewer = new AnimateInterpolate(2, [ new AnimateInterpolate.ObjectAttribute(gImageViewer.style, 'display', 'none', 'block', AnimateInterpolate.Select) ]);
    lSeq.addAnimation(lShowViewer);


    var lConc = new AnimateConcurrently();
    var lDim = new AnimateInterpolate(5, [ new AnimateInterpolate.ObjectAttribute(gScreening.style, 'opacity', 0, 0.4) ]);
    lConc.addAnimation(lDim);

    var lEndWidth = gImageViewer._realWidth;
    var lEndHeight = gImageViewer._realHeight;

    var lExplodeLeft = (document.body.clientWidth-lEndWidth)/2;
    var lExplodeTop = (document.body.clientHeight-lEndHeight)/2+document.body.scrollTop;

    gCloseLabel.style.left = lExplodeLeft+lEndWidth-gCloseLabel.clientWidth;
    gCloseLabel.style.top = lExplodeTop+lEndHeight-gCloseLabel.clientHeight;

    var lExplode = new AnimateInterpolate(15, [
        new AnimateInterpolate.ObjectAttribute(gImageViewer.style, 'left', parseInt(gImageViewer.style.left), lExplodeLeft), 
        new AnimateInterpolate.ObjectAttribute(gImageViewer.style, 'top', parseInt(gImageViewer.style.top), lExplodeTop),
        new AnimateInterpolate.ObjectAttribute(gImageViewer.style, 'width', aSrcElement.clientWidth, lEndWidth), 
        new AnimateInterpolate.ObjectAttribute(gImageViewer.style, 'height', aSrcElement.clientHeight, lEndHeight)
    ]);
    lConc.addAnimation(lExplode);

    lSeq.addAnimation(lConc);
    
    var lShowCloseLabel = new AnimateSequence();
    lShowCloseLabel.addAnimation(new AnimateInterpolate(2, [ new AnimateInterpolate.ObjectAttribute(gCloseLabel.style, 'visibility', 'hidden', 'visible', AnimateInterpolate.Select) ]));
    lShowCloseLabel.addAnimation(new AnimateInterpolate(15, [ new AnimateInterpolate.ObjectAttribute(gCloseLabel.style, 'opacity', 0, 1.0) ]));
    lSeq.addAnimation(lShowCloseLabel);
                                                 
    lDrv.addAnimation(lSeq);

    
    lDrv.start();
}

