﻿/***********************************************************************
                 Angelwatt Image Viewer version 1.2.1
************************************************************************
Author: Kendall Conrad of Angelwatt.com
Home page: http://www.angelwatt.com/coding/image_viewer.php
Created: 2008-02-16
Updated: 2010-10-16
Description: Takes links to images and makes the links show the image on
the page rather than opening a new page.
License:
* This work is licensed under a Creative Commons Attribution-Share Alike
	3.0 United States License 
	http://creativecommons.org/licenses/by-sa/3.0/us/
***********************************************************************/
var AngelwattImageViewer = function()
{
	/**** User Settings ****/
	var vars = {
		id:          '',     // id attribute of HTML section to apply this script
		loadImg:     'http://johnsarcade.com/loading.gif', // loading image path
		textColor:   '#fff',  // Text color for loading message
		bgColor:     '#000',  // Background color for the slide
		bgOpacity:   0.8,     // Background opacity: 0-1
		borderSize:  1,      // Border for image, measured in pixels
		borderColor: '#fff',  // Border color
		fadeIn:      true,   // If image should fade in to appearance
		zoomIn:      true    // If image should zoom into appearance
	};
	/**** End User Settings ****/
	
	var slide, slideLoad, sBg;
	var img; // the image
	var y, yScroll, yPage, x, centerY, centerX;
	var regImg = /\.(jpg|jpeg|gif|png|bmp)$/i; // match image types
	var startOp = 0;
	var currOp = startOp;
	var fxTime = 0.3; // time duration of effects in seconds
	var dur = 60;
	var deltaOp = dur / fxTime / 1000;
	var imgX = 0;
	var imgY = 0;
	var currX = 0;
	var currY = 0;
	
	var CenterImg = function () {
		img.style.top = centerY - (img.height / 2) +"px";
		img.style.left = centerX - (img.width / 2) +"px";
		if (parseInt(img.style.top, 10) < yScroll) {
			img.style.top = yScroll +'px';
		}
	};
	var OpacityUp = function() {
		if (currOp >= 1) { return; }
		currOp += deltaOp;
		img.style.opacity = currOp;
		setTimeout(function(){ OpacityUp(); }, dur);
	};
	var ZoomUp = function() {
		if (currX >= imgX && currY >= imgY) { return; }
		if (currX < imgX) {
			currX += Math.ceil(imgX * deltaOp);
			img.width = currX;
		}
		if (currX > imgX) {
			img.width = currX = imgX;
		}
		if (currY < imgY) {
			currY += Math.ceil(imgY * deltaOp);
			img.height = currY;
		}
		if (currY > imgY) {
			img.height = currY = imgY;
		}
		//CenterImg();
		setTimeout(function(){ ZoomUp(); }, dur);
	};
	var ShowImg = function () {
		imgX = img.width;
		imgY = img.height;
		currX = Math.ceil(imgX / 4);
		currY = Math.ceil(imgY / 4);
		CenterImg();
		img.style.zIndex = 5;     // bring image to front
		slideLoad.innerHTML = ''; // remove loading message
		if (vars.fadeIn === true) {
			OpacityUp();
		}
		if (vars.zoomIn === true) {
			ZoomUp();
		}
	};
	var HideSlide = function () {
		slide.style.display = 'none';
		if (document.getElementById('slideImg')) {
			if (vars.fadeIn === true) {
				document.getElementById('slideImg').style.opacity = 0;
			}
			document.getElementById('slideImg').parentNode.removeChild(
				document.getElementById('slideImg'));
		}
	};
	var ChangeSlide = function (target) {
		currOp = startOp;
		img = new Image();
		if (vars.loadImg !== '') {
			slideLoad.innerHTML = ['<img src="', vars.loadImg ,'"',' alt="Loading" width="20" height="20"',' style="position:relative; display:inline; z-index:2;',' margin:0 auto; padding:0; border:none; cursor:default;" />','<br />Loading...'].join('');
		}
		else { slideLoad.innerHTML = 'Loading...'; }
		slide.style.display = 'block'; // put up slide with loading msg

		// Get screen height, viewport height
		y = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
		// Find horizontal page position
		yScroll = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
		// Get full height of the page
		yPage = self.innerHeight + window.scrollMaxY || document.body.scrollHeight || document.body.offsetHeight;
		// Set slide background to full height of page
		document.getElementById('slideBG').style.height =
			(yPage < y) ? '100%' : yPage + "px";
		// Get page width
		x = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
		centerY = Math.floor(y/2) + yScroll;
		centerX = Math.floor(x/2);
		// center loading image
		slideLoad.style.marginTop = centerY-64 +"px";

		img.onload = function()
		{
			/*** Create image tag and style it ***/
			img.id    = 'slideImg';
			img.alt   = '';
			img.title = 'Click to close';
			img.style.position = 'absolute';
			img.style.display  = 'block';
			img.style.margin   = '0 auto';
			img.style.border   = vars.borderSize +'px solid '+ vars.borderColor;
			img.style.cursor   = 'pointer';
			img.style.zIndex   = 0; // hide the image away until loaded
			img.style.opacity  = (vars.fadeIn === true) ? startOp : 1;
			img.onclick = HideSlide;

			CenterImg(img); // attempt to center it
			// add slide to page
			slide.insertBefore(img, slide.firstChild);
			ShowImg();
		};
		img.src = target.getAttribute('href');
	};
	function ImageClickHandle()
	{
		ChangeSlide(this);
		return false;
	}
	var FindLinkedImages = function(id) {
		var links;
		if (id !== '' && document.getElementById(id)) {
			links = document.getElementById(id).getElementsByTagName('a');
		}
		else { links = document.getElementsByTagName('a'); }
		for (var a=0, l=links.length; a < l; a++) {
			if (regImg.test(links[a].href)) {
				links[a].onclick = ImageClickHandle;
			}
		}
	};
	// Get any query string on javascript url for any user setting overrides
	var ParseJSArgs = function(vars) {
		var scripts = document.getElementsByTagName('script');
		for (var x=0; x < scripts.length; x++) {
			// Looking for script with source to this file
			if (!scripts[x].src || !/image\-viewer/.test(scripts[x].src)) {
				continue;
			}
			// Check if any arguments were entered
			if (!/\?.+/.test(scripts[x].src)) {
				continue;
			}
			var args = scripts[x].src.split('?')[1].split('&');
			for (var y=0; y < args.length; y++) {
				var pair = args[y].split('=');
				// skip if not a pair or not a known var
				if (pair.length != 2 || vars[pair[0]] === undefined) {
					continue;
				}
				vars[pair[0]] = pair[1];
			}
		}
	};
	var Init = function() {
		ParseJSArgs(vars);
		// Create slide HTML and assign styling
		slide = document.createElement('div');
		slide.id             = 'slide';
		slide.style.display  = 'none';
		slide.style.position = 'absolute';
		slide.style.top      = '0px';
		slide.style.left     = '0px';
		slide.style.width    = '100%';
		slide.style.height   = '100%';
	
		// Create and style background
		sBg = document.createElement('div');
		sBg.id                    = 'slideBG';
		sBg.style.position        = 'absolute';
		sBg.style.top             = '0px';
		sBg.style.left            = '0px';
		sBg.style.margin          = '0 auto';
		sBg.style.width           = '100%';
		sBg.style.textAlign       = 'center';
		sBg.style.backgroundColor = vars.bgColor;
		sBg.style.opacity         = vars.bgOpacity;
		sBg.style.zIndex          = '2';
		sBg.onclick               = HideSlide;
	
		// Create and style loading message
		slideLoad = document.createElement('p');
		slideLoad.style.margin    = '0 auto';
		slideLoad.style.fontSize  = '2em';
		slideLoad.style.color     = vars.textColor;
		slideLoad.style.textAlign = 'center';
	
		// Build slide
		sBg.appendChild(slideLoad);
		slide.appendChild(sBg);
		var body = document.getElementsByTagName('body')[0];
		body.appendChild(slide);
		body.style.height = "100%";
		FindLinkedImages(vars.id); // Find links and attach events
	};
	function appendOnLoad(fx) { 
		try { // For browsers that know DOMContentLoaded (FF, Safari, Opera)
			document.addEventListener('DOMContentLoaded', fx, false);
		} catch(e) { // for IE and older browser
			try {
				document.addEventListener('load', fx, false);
			}
			catch(ee) {
				window.attachEvent('onload', fx);
			}
		}
	}
	appendOnLoad(Init);
}();

