// this file contains functions for the pv (pictureviewer)
// author:    Dominik Scholz, schlotzz@go4u.de
// changed:   2009-10-20

// global variables
	// create temporary data array
	var pva = new Array();

	// different settings
	pva.timeout = 5;
	pva.steps   = 15;
	pva.border  = 90;

	// source image size
	pva.src   = new Array();
	pva.src.x = null;
	pva.src.y = null;
	pva.src.w = null;
	pva.src.h = null;

	// destination image size
	pva.dst   = new Array();
	pva.dst.x = null;
	pva.dst.y = null;
	pva.dst.w = null;
	pva.dst.h = null;

	// image href
	pva.href = null;

	// image loaded
	pva.loaded = false;

	// other images
	pva.neighbours = new Array();
// end of global variables




// start preloading
pv_start_preload();




// execute, if hyperlink is clicked
function pv(o, fast)
{
	if (!o)
		return true;

	pva.loaded = false;

	if (fast == null)
		fast = false;

	if (!document.getElementById('pv_image'))
		pv_start();
		
	pv_hide_controls();

	var child = o.firstChild;
	var pos = pv_position(child);

	// check neighbours
	var container = o.parentNode;
	pva.neighbours = new Array();
	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;

		pva.neighbours.push(item);
	}

	// get data of source image
	pva.src.x = pos[0];
	pva.src.y = pos[1];
	pva.src.w = child.offsetWidth;
	pva.src.h = child.offsetHeight;

	// get url of image
	pva.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';
	pv_loadani(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 = pva.href;

	return false;
}


// execute if image is preloaded
function pv_preloaded(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  - pva.border*2;
	var maxh = windowHeight - pva.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
	pva.dst.x = windowWidth/2  - parseInt(w/2) + windowLeft;
	pva.dst.y = windowHeight/2 - parseInt(h/2) + windowTop;
	pva.dst.w = w;
	pva.dst.h = h;

	pv_open(fast);
}


// if page is loaded, insert images to preload preloading-animation
function pv_start_preload()
{
	// select body tag
	var insertBody = document.getElementsByTagName('body')[0];

	// if not loaded, try again later
	if (insertBody == null)
	{
		window.setTimeout("pv_start_preload();", 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
function pv_start()
{
	// 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() { pva.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:pv_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:pv_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:pv_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
function pv_loadani(s, fast)
{
	if (pva.loaded)
	{
		pv_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('pv_loadani('+s+', '+fast+');', 100);
}


// do open animation
function pv_open(fast, p)
{
	var o = document.getElementById('pv_image');

	// view image and hide the other stuff
	if (p==null)
	{
		pv_hide_controls();
	    o.style.display = 'block';
	    p = 0;
	}

	p += 100/pva.steps;

	if (fast)
		p = 100;

	var m = pv_magic(p/100);

	var x = pva.src.x + (pva.dst.x - pva.src.x) * m;
	var y = pva.src.y + (pva.dst.y - pva.src.y) * m;
	var w = pva.src.w + (pva.dst.w - pva.src.w) * m;
	var h = pva.src.h + (pva.dst.h - pva.src.h) * 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';

	pv_opacity(o.style, 25+p/100*75);

	if (p<100)
		window.setTimeout('pv_open('+fast+', '+p+');', pva.timeout);
	else
		pv_show_controls();
}




// do close animation
function pv_close(p)
{
    var o = document.getElementById('pv_image');

	if (p==null)
	{
		p = 0;
		pv_hide_controls();
	}

	p += 300/pva.steps; // three times as fast
	var m = pv_magic(p/100);

	var x = pva.dst.x - m*20;
	var y = pva.dst.y - m*20;
	var w = pva.dst.w + m*40;
	var h = pva.dst.h + 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';

	pv_opacity(o.style, 100-p);

	if (p<100)
		window.setTimeout('pv_close('+p+');', pva.timeout);
	else
		o.style.display = 'none';
}


// show closebutton and shadow of image
function pv_show_controls()
{
    document.getElementById('pv_image').onclick = function() { pv_close(); };

    var o0 = document.getElementById('pv_closebox');
    o0.style.left    = parseInt(pva.dst.x-12)+'px';
    o0.style.top     = parseInt(pva.dst.y-14)+'px';
    o0.style.display = 'block';

    var o1 = document.getElementById('pv_previousbox');
    o1.style.left    = parseInt(pva.dst.x-12+30)+'px';
    o1.style.top     = parseInt(pva.dst.y-14)+'px';
    o1.style.display = 'block';

    var o2 = document.getElementById('pv_nextbox');
    o2.style.left    = parseInt(pva.dst.x-12+60)+'px';
    o2.style.top     = parseInt(pva.dst.y-14)+'px';
    o2.style.display = 'block';

    var o4 = document.getElementById('pv_shadow');
    o4.style.left    = parseInt(pva.dst.x-12)+'px';
    o4.style.top     = parseInt(pva.dst.y-7)+'px';
    o4.style.display = 'block';

    var o5 = document.getElementById('pv_shadow5');
    o5.style.width   = parseInt(pva.dst.w-32)+'px';
    o5.style.height  = parseInt(pva.dst.h-28)+'px';
}


// hide controls
function pv_hide_controls()
{
	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
function pv_neighbourspos()
{
	for (var i=0; i<pva.neighbours.length; i++)
		if (pva.neighbours[i].href == pva.href)
			return i;
	return 0;
}


// show previous image in gallery
function pv_previous()
{
	if (pva.neighbours.length <= 1)
		return;

	var pos = pv_neighbourspos() - 1;

	if (pos < 0)
		pos = pva.neighbours.length-1;

	pv_hide_controls();
	pv(pva.neighbours[pos], true);
}


// show next image in gallery
function pv_next()
{
	if (pva.neighbours.length <= 1)
		return;

	var pos = pv_neighbourspos() + 1;

	if (pos >= pva.neighbours.length)
		pos = 0;

	pv_hide_controls();
	pv(pva.neighbours[pos], true);
}


// get pixel position of any element on a page
function pv_position(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)
function pv_opacity(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
function pv_magic(pos)
{
	return ((-Math.cos(pos*Math.PI)/2) + 0.5);
}
