// this file contains functions for the pv (pictureviewer)
// author:    Dominik Scholz, schlotzz@go4u.de
// changed:   2010-04-10


var GALLERY = {
	
	// different settings
	timeout: 15,
	steps: 15,
	border: 90,

	srcX: null,
	srcY: null,
	srcW: null,
	srcH: null,

	dstX: null,
	dstY: null,
	dstW: null,
	dstH: null,

	href: null,
	loaded: false,
	neighbours: [],


	// execute, if hyperlink is clicked
	go: function(o, fast)
	{
		if (!o)
			return true;

		this.loaded = false;

		if (fast == null)
			fast = false;

		if (!document.getElementById('pv_image'))
			this.start();
			
		this.hideControls();

		var child = o.firstChild;
		var pos = this.position(child);

		// check neighbours
		var container = o.parentNode;
		this.neighbours = [];
		var others = container.getElementsByTagName('a');
		for (var i=0; i<others.length; i++)
		{
			var item = others[i];
			var ext = item.href;
			ext = ext.substr(ext.length-4, 4).toLowerCase();

			// skip if not a picture
			if (ext != '.jpg' && ext != '.gif' && ext != '.png' && ext != '.bmp')
				continue;

			this.neighbours.push(item);
		}

		// get data of source image
		this.srcX= pos[0];
		this.srcY = pos[1];
		this.srcW = child.offsetWidth;
		this.srcH = child.offsetHeight;

		// get url of image
		this.href = o.href;

		// show loading box
		var de = document.documentElement;
		var windowWidth  = window.innerWidth  || self.innerWidth  || (de&&de.clientWidth)  || document.body.clientWidth;
		var windowHeight = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
		var windowLeft   = window.pageXOffset || self.pageXOffset || (de&&de.scrollLeft)   || document.body.scrollLeft;
		var windowTop    = window.pageYOffset || self.pageYOffset || (de&&de.scrollTop)    || document.body.scrollTop;

		var loadbox = document.getElementById('pv_loadbox');
		loadbox.style.left = (parseInt(windowWidth/2) + windowLeft-25)+'px';
		loadbox.style.top  = (parseInt(windowHeight/2) + windowTop-25)+'px';
		loadbox.style.display = 'block';
		this.loadAnimation(0, fast);

		// set image for preload
		var preload = document.getElementById('pv_image');
		preload.style.left    = '-9999px';
		preload.style.top     = '-9999px';
		preload.style.width   = '';
		preload.style.height  = '';
		preload.style.display = 'block';
		preload.src = '';
		preload.src = this.href;

		return false;
	},


	// execute if image is preloaded
	preloaded: function (fast)
	{
		var de = document.documentElement;
		var windowWidth  = window.innerWidth  || self.innerWidth  || (de&&de.clientWidth)  || document.body.clientWidth;
		var windowHeight = window.innerHeight || self.innerHeight || (de&&de.clientHeight) || document.body.clientHeight;
		var windowLeft   = window.pageXOffset || self.pageXOffset || (de&&de.scrollLeft)   || document.body.scrollLeft;
		var windowTop    = window.pageYOffset || self.pageYOffset || (de&&de.scrollTop)    || document.body.scrollTop;
		var preload = document.getElementById('pv_image');

		// get width and height from image
		var w = preload.offsetWidth;
		var h = preload.offsetHeight;

		// maximal width and height
		var maxw = windowWidth  - this.border*2;
		var maxh = windowHeight - this.border*2;

		if (w > maxw)
		{
			h *= maxw/w;
			w = maxw;
		}

		if (h > maxh)
		{
			w *= maxh/h;
			h = maxh;
		}

		// round width and height
		w = parseInt(w);
		h = parseInt(h);

		// get data of destination image
		this.dstX = windowWidth/2  - parseInt(w/2) + windowLeft;
		this.dstY = windowHeight/2 - parseInt(h/2) + windowTop;
		this.dstW = w;
		this.dstH = h;

		this.open(fast);
	},


	// if page is loaded, insert images to preload preloading-animation
	startPreload: function()
	{
		// select body tag
		var insertBody = document.getElementsByTagName('body')[0];

		// if not loaded, try again later
		if (insertBody == null)
		{
			window.setTimeout(GALLERY.startPreload, 250);
			return;
		}

		// create divs for all preloading classes
		var insertDiv = document.createElement("div");
		insertDiv.style.position = 'absolute';
		insertDiv.style.left     = '-9999px';
		insertDiv.style.top      = '-9999px';

		insertBody.insertBefore(insertDiv, insertBody.firstChild);

		// create column
		for (var i=1; i<=8; i++)
		{
			var insertSubdiv = document.createElement("div");
			insertSubdiv.className = 'loadstate'+i;
			insertDiv.appendChild(insertSubdiv);
		}
	},


	// insert html objects
	start: function()
	{
		// select body tag
		var insertBody = document.getElementsByTagName('body')[0];

		// loading bar
		var insertLoad = document.createElement('div');
		insertLoad.setAttribute('id', 'pv_loadbox');
		insertLoad.style.position   = 'absolute';
		insertLoad.style.left       = '10px';
		insertLoad.style.top        = '10px';
		insertLoad.style.display    = 'none';
		insertLoad.style.zIndex     = '1000';
		insertBody.insertBefore(insertLoad, insertBody.firstChild);

		// moving image
		var insertImage = document.createElement('img');
		insertImage.setAttribute('id', 'pv_image');
		insertImage.style.position  = 'absolute';
		insertImage.style.left      = '10px';
		insertImage.style.top       = '10px';
		insertImage.style.display   = 'none';
		insertImage.style.zIndex    = '1000';
		insertBody.insertBefore(insertImage, insertBody.firstChild);
		insertImage.onload = function() { GALLERY.loaded = true; };

		// close button
		var insertClose = document.createElement('a');
		insertClose.setAttribute('id', 'pv_closebox');
		insertClose.style.position  = 'absolute';
		insertClose.style.left      = '10px';
		insertClose.style.top       = '10px';
		insertClose.style.display   = 'none';
		insertClose.style.zIndex    = '1001';
		insertBody.insertBefore(insertClose, insertBody.firstChild);
		insertClose.href = 'javascript:GALLERY.close();';

		// previous button
		var insertClose = document.createElement('a');
		insertClose.setAttribute('id', 'pv_previousbox');
		insertClose.style.position  = 'absolute';
		insertClose.style.left      = '10px';
		insertClose.style.top       = '10px';
		insertClose.style.display   = 'none';
		insertClose.style.zIndex    = '1001';
		insertBody.insertBefore(insertClose, insertBody.firstChild);
		insertClose.href = 'javascript:GALLERY.previous();';

		// next button
		var insertClose = document.createElement('a');
		insertClose.setAttribute('id', 'pv_nextbox');
		insertClose.style.position  = 'absolute';
		insertClose.style.left      = '10px';
		insertClose.style.top       = '10px';
		insertClose.style.display   = 'none';
		insertClose.style.zIndex    = '1001';
		insertBody.insertBefore(insertClose, insertBody.firstChild);
		insertClose.href = 'javascript:GALLERY.next();';

		// image shadow
		var insertShadow = document.createElement('table');
		insertShadow.setAttribute('id', 'pv_shadow');
		insertShadow.style.position = 'absolute';
		insertShadow.style.left     = '10px';
		insertShadow.style.top      = '10px';
		insertShadow.style.display  = 'none';
		insertShadow.style.zIndex   = '999';
		insertShadow.cellPadding    = '0';
		insertShadow.cellSpacing    = '0';
		insertBody.insertBefore(insertShadow, insertBody.firstChild);

		var insertShadowTbody = document.createElement("tbody");
		insertShadow.appendChild(insertShadowTbody);

		// create rows and columns
		for (var row=0; row<=2; row++)
		{
			// create rows
			var insertRow = document.createElement("tr");
			insertShadowTbody.appendChild(insertRow);

			// create column
			for (var col=1; col<=3; col++)
			{
				var insertCol = document.createElement("td");
				insertCol.id = 'pv_shadow'+(row*3+col);
				insertRow.appendChild(insertCol);
			}
		}
	},


	// cycle loading animation
	loadAnimation: function(s, fast)
	{
		if (this.loaded)
		{
			this.preloaded(fast);
			return;
		}

		var o = document.getElementById('pv_loadbox');
		o.className  = 'loadstate'+s;
		o.innerHTML = '<div style="display: block; width: 50px; height: 50px;">&nbsp;</div>';

		s = (s<8)? (s+1):1;

		if (o.style.display == 'block')
			window.setTimeout('GALLERY.loadAnimation('+s+', '+fast+')', 100);
	},


	// do open animation
	open: function(fast, p)
	{
		var o = document.getElementById('pv_image');

		// view image and hide the other stuff
		if (p==null)
		{
			this.hideControls();
			o.style.display = 'block';
			p = 0;
		}

		p += 100/this.steps;

		if (fast)
			p = 100;

		var m = this.magic(p/100);

		var x = this.srcX + (this.dstX - this.srcX) * m;
		var y = this.srcY + (this.dstY - this.srcY) * m;
		var w = this.srcW + (this.dstW - this.srcW) * m;
		var h = this.srcH + (this.dstH - this.srcH) * m;

		o.style.left   = parseInt(x)+'px';
		o.style.top    = parseInt(y)+'px';
		o.style.width  = parseInt(w)+'px';
		o.style.height = parseInt(h)+'px';

		this.opacity(o.style, 25+p/100*75);

		if (p<100)
			window.setTimeout('GALLERY.open('+fast+', '+p+')', this.timeout);
		else
			this.showControls();
	},


	// do close animation
	close: function(p)
	{
		var o = document.getElementById('pv_image');

		if (p==null)
		{
			p = 0;
			this.hideControls();
		}

		p += 300/this.steps; // three times as fast
		var m = this.magic(p/100);

		var x = this.dstX - m*20;
		var y = this.dstY - m*20;
		var w = this.dstW + m*40;
		var h = this.dstH + m*40;

		o.style.left   = parseInt(x)+'px';
		o.style.top    = parseInt(y)+'px';
		o.style.width  = parseInt(w)+'px';
		o.style.height = parseInt(h)+'px';

		this.opacity(o.style, 100-p);

		if (p<100)
			window.setTimeout('GALLERY.close('+p+')', this.timeout);
		else
			o.style.display = 'none';
	},


	// show closebutton and shadow of image
	showControls: function()
	{
		document.getElementById('pv_image').onclick = function() { GALLERY.close(); };

		var o0 = document.getElementById('pv_closebox');
		o0.style.left    = parseInt(this.dstX-12)+'px';
		o0.style.top     = parseInt(this.dstY-14)+'px';
		o0.style.display = 'block';

		var o1 = document.getElementById('pv_previousbox');
		o1.style.left    = parseInt(this.dstX-12+30)+'px';
		o1.style.top     = parseInt(this.dstY-14)+'px';
		o1.style.display = 'block';

		var o2 = document.getElementById('pv_nextbox');
		o2.style.left    = parseInt(this.dstX-12+60)+'px';
		o2.style.top     = parseInt(this.dstY-14)+'px';
		o2.style.display = 'block';

		var o4 = document.getElementById('pv_shadow');
		o4.style.left    = parseInt(this.dstX-12)+'px';
		o4.style.top     = parseInt(this.dstY-7)+'px';
		o4.style.display = 'block';

		var o5 = document.getElementById('pv_shadow5');
		o5.style.width   = parseInt(this.dstW-32)+'px';
		o5.style.height  = parseInt(this.dstH-28)+'px';
	},


	// hide controls
	hideControls: function()
	{
		document.getElementById('pv_closebox').style.display = 'none';
		document.getElementById('pv_previousbox').style.display = 'none';
		document.getElementById('pv_nextbox').style.display = 'none';
		document.getElementById('pv_loadbox').style.display  = 'none';
		document.getElementById('pv_shadow').style.display = 'none';
		document.getElementById('pv_image').onclick = null;
	},


	// return the position of current image in gallery
	neighboursPosition: function()
	{
		for (var i=0; i<this.neighbours.length; i++)
			if (this.neighbours[i].href == this.href)
				return i;
		return 0;
	},


	// show previous image in gallery
	previous: function()
	{
		if (this.neighbours.length <= 1)
			return;

		var pos = this.neighboursPosition() - 1;

		if (pos < 0)
			pos = this.neighbours.length-1;

		this.hideControls();
		this.go(this.neighbours[pos], true);
	},


	// show next image in gallery
	next: function()
	{
		if (this.neighbours.length <= 1)
			return;

		var pos = this.neighboursPosition() + 1;

		if (pos >= this.neighbours.length)
			pos = 0;

		this.hideControls();
		this.go(this.neighbours[pos], true);
	},


	// get pixel position of any element on a page
	position: function(o)
	{
		var x = 0;
		var y = 0;
		do
		{
			x += o.offsetLeft;
			y += o.offsetTop;
		} while (o = o.offsetParent)

		return Array(x, y);
	},


	// set opacity of any element, use (element.style, 0-100)
	opacity: function(o, p)
	{
		var pInt       = Math.ceil(p);
		o.filter       = 'Alpha(opacity='+pInt+')';
		o.MozOpacity   = '' + pInt/100;
		o.KTHMLOpacity = '' + pInt/100;
		o.opacity      = '' + pInt/100;
	},


	// convert with sinus-function for smoother animation
	magic: function(pos)
	{
		return ((-Math.cos(pos*Math.PI)/2) + 0.5);
	}

};

GALLERY.startPreload();
