// --------------------------------------------------------------------------------
//
//	ImgZoom v2.09.004
//	by plan p. GmbH - http://www.plan-p.de/
//	Last Modification: 14. Jan 2010
//	
//	modified for "Geelong - Cool Mates Workwar"-Site
//
//  Inspired by a lot of similar scripts!
//
// --------------------------------------------------------------------------------


//
//  ImgZoom Configuration
//
var ImgZoomOptions = Object.extend({
    overlayOpacity: 	0.75, 		// transparency of shadow overlay
	overlayDuration: 	0.25,		// the duration of displaying overlay before and after image visible
	overlayDelay: 		0.10,		// delay before displaying overlay
    resizeDuration: 	0.50, 		// the duration of the image resizing animation (0.00 <= X <= 3.00)
    boxAppearDuration: 	0.75, 		// the duration needed by the box to appear after click
    minimizeAtEnd: 		true, 		// if true, the box will minimize when closed
	initImgSize: 		48			// initial size (height & width) of image before resizing
}, window.ImgZoomOptions || {});


//
//  ImgZoom Class
//
var ImgZoom = Class.create();

ImgZoom.prototype = {
    imageArray: [],
    activeImage: undefined,
    imageDisplayed: false,
    isActive: false,
    
	//
    // initialize()
    // Constructor runs on completion of the DOM loading.
	//
    initialize: function() {
		// collect the imgzoom-rels
		this.updateImageList();
        
		// register event listener for the keyboard
		this.keyboardAction = this.keyboardAction.bindAsEventListener(this);

		// check the config
        if (ImgZoomOptions.resizeDuration > 3) ImgZoomOptions.resizeDuration = 3;
        if (ImgZoomOptions.resizeDuration < 0)  ImgZoomOptions.resizeDuration = 0;

        if (ImgZoomOptions.overlayDuration > 1.5) ImgZoomOptions.overlayDuration = 1.5;
        if (ImgZoomOptions.overlayDuration < 0)  ImgZoomOptions.overlayDuration = 0;

        if (ImgZoomOptions.initImgSize > 500) ImgZoomOptions.initImgSize = 500;
        if (ImgZoomOptions.initImgSize < 10)  ImgZoomOptions.initImgSize = 10;

		// insert the elements into the dom
		var objBody = document.getElementsByTagName("body").item(0);

		var objOverlay = document.createElement("div");
		objOverlay.setAttribute('id','overlay');
		objOverlay.style.display = 'none';
		objBody.appendChild(objOverlay);
		
		var objImgZoom = document.createElement("div");
		objImgZoom.setAttribute('id','imgZoom');
		objImgZoom.style.display = 'none';
		objBody.appendChild(objImgZoom);

		var objImageContainer = document.createElement("div");
		objImageContainer.setAttribute('id','imageContainer');
		objImgZoom.appendChild(objImageContainer);

		var objImgZoomImage = document.createElement("img");
		objImgZoomImage.setAttribute('id','imgZoomImage');
		objImageContainer.appendChild(objImgZoomImage);

		var objImgZoomBtnClose = document.createElement("a");
		objImgZoomBtnClose.setAttribute('id','imgZoomBtnClose');
		objImgZoomBtnClose.setAttribute('href','#close');
		objImageContainer.appendChild(objImgZoomBtnClose);

		// setup observers
		$('overlay').hide().observe('click', (function() { this.end(); }).bind(this));
		$('imgZoom').hide().observe('click', (function() { this.end(); }).bind(this));

        var th = this;
        (function(){
            var ids = 'overlay imgZoom imageContainer imgZoomImage imgZoomBtnClose';   
            $w(ids).each(function(id){ th[id] = $(id); });
        }).defer();

    },

    //
    // updateImageList()
    // Loops through anchor tags looking for 'imgzoom' references and applies onclick events to appropriate links.
    //
    updateImageList: function() {   
        this.updateImageList = Prototype.emptyFunction;

        document.observe('click', (function(event){
            var target = event.findElement('a[rel^=imgzoom]') || event.findElement('area[rel^=imgzoom]');
            if (target) {
                event.stop();
				if(!this.isActive)
				{
					this.isActive = true;
                	this.start(target);
				}
            }
        }).bind(this));
    },
    
    //
    //  start()
    //  Display overlay and imgZoom. If image is part of a set, add siblings to imageArray.
    //
    start: function(imageLink) {
		// fix for objects that sticky on top of z-index
		$$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'hidden' });

		var imageNum = 0;       
        this.imageArray = [];
 		this.imageArray.push([imageLink.href, imageLink.title]);         

        // calculate top and left offset etc.
		var arrayPageViewport = document.viewport.getDimensions();
        var arrayPageScroll = document.viewport.getScrollOffsets();
        var imgZoomTop = Math.round(arrayPageScroll.top + ((arrayPageViewport.height - ImgZoomOptions.initImgSize) / 2));
        var imgZoomLeft = Math.round(arrayPageScroll.left + ((arrayPageViewport.width - ImgZoomOptions.initImgSize) / 2));
		
		this.imgZoom.setStyle({ top: imgZoomTop + 'px', left: imgZoomLeft + 'px' });
		this.imageContainer.setStyle({ width: ImgZoomOptions.initImgSize + 'px', height: ImgZoomOptions.initImgSize + 'px' }); 
        new Effect.Appear(this.imgZoom, { duration: ImgZoomOptions.boxAppearDuration, from: 0.0, to: 1.0 });

		this.changeImage(imageNum, true);
    },

    //
    //  changeImage()
    //  Hide most elements and preload image in preparation for resizing image container.
    //
    changeImage: function(imageNum, start) {
        this.activeImage = imageNum; 	// update global var

		this.imageDisplayed = false;

		if(!start)
		{
			var tmp_delay = 0.25;
			new Effect.Fade(this.imgZoomImage, { duration: tmp_delay, from: 1.0, to: 0.0, queue: 'end' });
		}
		
        var fnc_delayed = (function(){
			this.imgZoomImage.hide();
			
	        // once image is preloaded, resize image container
			var imgPreloader = new Image();
	        imgPreloader.onload = (function(){
				this.imgZoomImage.src = this.imageArray[this.activeImage][0];
				this.resizeImageContainer(imgPreloader.width, imgPreloader.height, start);
				this.imageDisplayed = true;
	        }).bind(this);
	        imgPreloader.src = this.imageArray[this.activeImage][0];
		}).bind(this).delay(tmp_delay);
    },

	//
	//  resizeImageContainer()
	//
	resizeImageContainer: function(imgWidth, imgHeight, start) {
		if(start)
		{
			// stretch overlay to fill page and fade in
			$('overlay').setStyle({ width: '100%', height: '100%' });
			new Effect.Appear(this.overlay, { duration: ImgZoomOptions.overlayDuration, from: 0.0, to: ImgZoomOptions.overlayOpacity, delay: ImgZoomOptions.overlayDelay });
		}
		else
		{
			new Effect.Appear(this.overlay, { duration: 0.0, from: ImgZoomOptions.overlayOpacity, to: ImgZoomOptions.overlayOpacity, delay: ImgZoomOptions.overlayDelay });
		}

		// get current width and height of old image and current viewport
		var widthCurrent  = this.imageContainer.getWidth();
		var heightCurrent = this.imageContainer.getHeight();
		var arrayPageViewport = document.viewport.getDimensions();
        var arrayPageScroll = document.viewport.getScrollOffsets();

		// check for to large images
		if( imgWidth>(arrayPageViewport.width-50) || imgHeight>(arrayPageViewport.height-50) )
		{
			var wScale = (arrayPageViewport.width-100) / imgWidth;
			var hScale = (arrayPageViewport.height-100) / imgHeight;
			if(wScale<hScale)
			{
				imgWidth = imgWidth * wScale;
				imgHeight = imgHeight * wScale;
			}
			else
			{
				imgWidth = imgWidth * hScale;
				imgHeight = imgHeight * hScale;				
			}
		}
		
		// calculate top and left offset etc.
		var imgZoomTop = Math.round(arrayPageScroll.top + ((arrayPageViewport.height - imgHeight) / 2));
		var imgZoomLeft = Math.round(arrayPageScroll.left + ((arrayPageViewport.width - imgWidth) / 2));
		//var imgZoomLeft = arrayPageScroll.left;

		// set new width and height
		this.imgZoomImage.setStyle({ width: imgWidth + 'px', height: imgHeight + 'px' });

		// calculate size difference between new and old image, and resize if necessary
		var wDiff = widthCurrent - (imgWidth);
		var hDiff = heightCurrent - (imgHeight);

		// save new size into object
		var newImgStyleObj = new Object();
		newImgStyleObj.width = (imgWidth) + 'px';
		newImgStyleObj.height = (imgHeight) + 'px';
		
		// save new offsets into object
		var newRootStyleObj = new Object();
		newRootStyleObj.top = imgZoomTop + 'px';
		newRootStyleObj.left = imgZoomLeft + 'px';
		
		// morph to new offset and size
		new Effect.Parallel([
				new Effect.Morph(this.imgZoom, { style: newRootStyleObj	}),
				new Effect.Morph(this.imageContainer, { style: newImgStyleObj })
			], {
				duration: ImgZoomOptions.resizeDuration
			}
		);

		// if new and old image are same size and no scaling transition is necessary, 
		// do a quick pause to prevent image flicker.
		var timeout = 0;
		if ((hDiff == 0) && (wDiff == 0)){
			timeout = 100;
			if (Prototype.Browser.IE) timeout = 250;   
		}

		(function(){
			this.showImage();
		}).bind(this).delay(timeout / 1000);
	},
	
	//
	//  showImage()
	//  Display image and begin preloading neighbors.
	//
	showImage: function(){
		new Effect.Appear(this.imgZoomImage, { 
			duration: ImgZoomOptions.resizeDuration, 
			queue: 'end'
		});
		(function(){
			this.imgZoom.show();
			this.imgZoom.setOpacity(1.0);
		}).bind(this).delay(ImgZoomOptions.resizeDuration);
	},

	//
	//  enableKeyboardNav()
	//
	enableKeyboardNav: function() {
		document.observe('keydown', this.keyboardAction); 
	},

	//
	//  disableKeyboardNav()
	//
	disableKeyboardNav: function() {
		document.stopObserving('keydown', this.keyboardAction); 
	},

	//
	//  keyboardAction()
	//
	keyboardAction: function(event) {
		var keycode = event.keyCode;

		var escapeKey;
		if (event.DOM_VK_ESCAPE) { 	// mozilla
			escapeKey = event.DOM_VK_ESCAPE;
        } else { 	// ie
			escapeKey = 27;
        }

		var key = String.fromCharCode(keycode).toLowerCase();
        
		if (key.match(/x|o|c/) || (keycode == escapeKey)){ 	// close
			this.end();
		}
	},

	//
	//  end()
	//
	end: function() {
		if(!this.isActive) { return; }
		this.isActive = false;
		
		this.disableKeyboardNav();
		new Effect.Fade(this.imgZoom, { duration: (ImgZoomOptions.overlayDuration *2), delay: 0.0 });
		new Effect.Fade(this.overlay, { duration: (ImgZoomOptions.overlayDuration *2), delay: (ImgZoomOptions.overlayDuration *2) });

		if(this.imageDisplayed  && ImgZoomOptions.minimizeAtEnd)
		{
			var arrayPageViewport = document.viewport.getDimensions();
	        var arrayPageScroll = document.viewport.getScrollOffsets();

			var endSizeWidth = this.imgZoomImage.width / 3;
			var endSizeHeight = this.imgZoomImage.height / 3;

			// calculate top and left offset etc.
			var imgZoomTop = Math.round(arrayPageScroll.top + ((arrayPageViewport.height - endSizeHeight) / 2));
			var imgZoomLeft = Math.round(arrayPageScroll.left + ((arrayPageViewport.width - endSizeWidth) / 2));

			// save new size into object
			var newImgStyleObj = new Object();
			newImgStyleObj.width = (endSizeWidth) + 'px';
			newImgStyleObj.height = (endSizeHeight) + 'px';

			// save new offsets into object
			var newRootStyleObj = new Object();
			newRootStyleObj.top = imgZoomTop + 'px';
			newRootStyleObj.left = imgZoomLeft + 'px';

			// morph to new offset and size
			new Effect.Parallel([
					new Effect.Morph(this.imgZoom, { style: newRootStyleObj }),
					new Effect.Morph(this.imgZoomImage, { style: newImgStyleObj }),
					new Effect.Morph(this.imageContainer, { style: newImgStyleObj })
				], {
					duration: (ImgZoomOptions.overlayDuration *3)
				}
			);
		}
		this.imageDisplayed = false;

		(function(){
			this.imageContainer.setStyle({ width: ImgZoomOptions.initImgSize + 'px', height: ImgZoomOptions.initImgSize + 'px' }); 
		}).bind(this).delay(ImgZoomOptions.overlayDuration *4);

		// undo: fix for sticky (z-indexed) elements
		$$('select', 'object', 'embed').each(function(node){ node.style.visibility = 'visible' });
    }

}
document.observe('dom:loaded', function () { var myImgZoom = new ImgZoom(); });
