/*
 *  main_image.js
 *  This code creates a bottom image, then after a timeout, it creates a
 *  top image, slowly fades the top image into view (with opacity), then
 *  makes it the new bottom image.
 *  The active image can't be faded out because the new image would be fully
 *  visible under the former image;  the new image must be faded in.
 *  http://www.splintered.co.uk/experiments/archives/javascript_cross_fade/crossfade.js
 *  http://brainerror.net/scripts/javascript/blendtrans/
 */

"use strict";

/* http://www.javascriptlint.com/index.htm */
/*jsl:option explicit*/
/*jsl:declare document*/
/*jsl:declare window*/
/*jsl:declare navigator*/
/*jsl:declare setTimeout*/

// open anonymous function
(function()
{

// consts
// IE 7 doesn't support 'const' and it is not in the new javascript standard
// vars

var top_image = {}, bottom_image = {}, action = {};

var auto_switch = {
	cycles		: 10,
	count		: 0,
	timeout		: null,
	msecs		: 10000, // 10 seconds
	enable		: true
};

var fade = {
	loops		: 15, // fade changes per switch
	msecs		: 50, // delay between fade changes
	timeout		: null
};

// array of objects
var image		= [
	{
		file	: 'euro_train.jpg',
		location: 'France, 2008',
		author	: 'Luke Momjian',
		url	: '/main/events/conferences/2008.html#February_23-24_2008'
	},	
	{
		file	: 'ottawa.jpg',
		location: 'Ottawa, 2007',
		author	: 'Michael Glaesemann',
		url	: '/main/events/conferences/2007.html#May_21-24_2007'
	},	
	{
		file	: 'moscow.jpg',
		location: 'Moscow, 2007',
		author	: 'Teodor Sigaev',
		url	: '/main/events/conferences/2007.html#September_24-25_2007'
	},	
	{
		file	: 'eastern2.jpg',
		location: 'Philadelphia, 2008',
		author	: 'Christine Momjian',
		url	: '/main/news/2008.html#January_15_2008'
	},	
	{
		file	: 'oscon.jpg',
		location: 'Portland, Oregon, 2010',
		author	: 'Robert "r0ml" Lefkowitz',
		url	: '/main/events/conferences/2010.html#July_19-23_2010'
	},	
	{
		file	: 'rambler.jpg',
		location: 'Moscow, 2007',
		author	: 'Nikolay Samokhvalov',
		url	: '/main/events/conferences/2007.html#September_24-25_2007'
	},	
	{
		file	: 'eastern1.jpg',
		location: 'Philadelphia, 2008',
		author	: 'Christine Momjian',
		url	: '/main/news/2008.html#January_15_2008'
	},	
	{
		file	: 'seaworld.jpg',
		location: 'Florida, 2009',
		author	: 'Christine Momjian',
		url	: '/main/news/2009.html#November_8_2009'
	},	
	{
		file	: 'deck.jpg',
		location: 'Pennsylvania, 2003',
		author	: 'Jan Wieck',
		url	: ''
	},	
	{
		file	: 'slacker.jpg',
		location: 'Ottawa, 2008',
		author	: "Magnus Hagander and Derek Rodner",
		url	: '/main/events/conferences/2008.html#May_22-23_2008'
	},	
	{
		file	: 'waterfall.jpg',
		location: 'Costa Rica, 2007',
		author	: 'Christine Momjian',
		url	: '/main/news/2007.html#March_17_2007'
	},	
	{
		file	: 'elephants.jpg',
		location: 'Sri Lanka, 2005',
		author	: 'Greg Stein',
		url	: '/main/events/conferences/2005.html#September_7-10_2005'
	},	
	{
		file	: 'ellis_island.jpg',
		location: 'New York City, 2007',
		author	: 'Christine Momjian',
		url	: '/main/news/2007.html#September_6_2007'
	},	
	{
		file	: 'oscon2.jpg',
		location: 'Portland, Oregon, 2010',
		author	: 'Robert "r0ml" Lefkowitz',
		url	: '/main/events/conferences/2010.html#July_19-23_2010'
	},	
	{
		file	: 'toronto.jpg',
		location: 'Toronto, 2006',
		author	: 'Alvaro Herrera',
		url	: '/main/events/conferences/2006.html#July_8-9_2006'
	},	
	{
		file	: 'uk_train.jpg',
		location: 'England, 2008',
		author	: 'Luke Momjian',
		url	: '/main/events/conferences/2008.html#February_23-24_2008'
	},	
	{
		file	: 'hedgerow_gala.jpg',
		location: 'Pennsylvania, 2007',
		author	: 'Rick Preiur',
		url	: '/main/news/2007.html#November_17_2007_2'
	},	
	{
		file	: 'ottawa3.jpg',
		location: 'Ottawa, 2007',
		author	: "Devrim G\xFCnd\xFCz",
		url	: '/main/events/conferences/2007.html#May_21-24_2007'
	},	
	{
		file	: 'pgcon2009-devmeeting-2.jpg',
		location: 'Ottawa, 2009',
		author	: 'Oleg Bartunov',
		url	: '/main/events/conferences/2009.html#May_21-22_2009'
	},	
	{
		file	: 'montage.jpg',
		location: '',
		author	: '',
		url	: ''
	}
];


function set_image_opacity(opacity, obj)
{
	if (obj.style)
	{
		/* test for different browsers */
		if (obj.style.opacity != null)
			/* CSS3 compatible */
			obj.style.opacity = (opacity / 100);
		else if (obj.style.MozOpacity != null)
			/* Mozilla's pre-CSS3 proprietary rule */
			obj.style.MozOpacity = (opacity / 100);
		else if (obj.style.filter != null)
			/* IE's proprietary filter */
			obj.style.filter = 'alpha(opacity=' + opacity + ')';
	}
}

top_image.set_opacity = function(loop)
{
	var pct;

	if (fade.loops != 0)
		pct = 100 * loop / fade.loops;
	else
		pct = 100;
	// Amazing that you fade the new image in but don't fade out the old one
	set_image_opacity(pct, this.div);
}

top_image.load = function()
{
	// pre-load next image
	this.img.src = '/main/img/main/' + image[top_image.slot].file;

	// image border?
	if (image[this.slot].file != 'slacker.jpg' &&
	    image[this.slot].file != 'montage.jpg')
		this.img.className = 'full-width border';
	else
		this.img.className = 'full-width';

	// Use greyscale image with 20% probability. Do this after border is chosen
	if (Math.random() < 0.20)
	{
		this.img.src = this.img.src.replace(/[^.]*$/, 'BW.$&');
	}

	this.location.a.href = image[top_image.slot].url;
	this.location.a.firstChild.nodeValue = image[top_image.slot].location;
	this.author.firstChild.nodeValue =
		(image[top_image.slot].author != '') ? 'photo by ' + image[top_image.slot].author : '';
}

top_image.copy_to_bottom = function()
{
	bottom_image.slot = this.slot;

	bottom_image.img.src = this.img.src;
	// image border
	bottom_image.img.className = this.img.className;
	bottom_image.location.a.href = this.location.a.href;
	bottom_image.location.a.firstChild.nodeValue = this.location.a.firstChild.nodeValue;
	bottom_image.author.firstChild.nodeValue = this.author.firstChild.nodeValue;

	bottom_image.location.style.display = 'block';
	bottom_image.author.style.display = 'block';

	// We made this invisible in main.html, so we display it now
	if (bottom_image.div.style.display == 'none')
		bottom_image.div.style.display = 'block';
}

top_image.prepare = function()
{
	// make top image invisible;  zero opaque is not enough because
	// 'view image' shows top image and links on short images are inactive
	this.div.style.display = 'none';

	this.slot = (bottom_image.slot + 1) % image.length;
	this.load();
}

// Fade in top image over bottom image
fade.activate = function(loop)
{
	this.timeout = null;
	auto_switch.timeout = null;
	if (auto_switch.count == 1)
		action.child.nodeValue = '';

	top_image.set_opacity(loop);

	// first time in fade loop
	if (loop == 0)
	{
		top_image.div.style.display = 'block';

		// do not display description of bottom image as we fade in top image
		bottom_image.location.style.display = 'none';
		bottom_image.author.style.display = 'none';
	}

	if (loop + 1 < this.loops) // do not bother with 100% for top
		// sleep before fading in more
		this.timeout =
			setTimeout(function() {fade.activate(loop + 1); }, this.msecs);
	else
		top_image.display();
}

auto_switch.schedule = function()
{
	if (this.enable)
	{
		if (++this.count < image.length * this.cycles)
	 		this.timeout = setTimeout(
				function() {fade.activate(0); }, this.msecs);
		else
		{
			action.child.nodeValue = 'Slideshow Finished';
			action.div.onclick = function() {auto_switch.resume(); return false;};
			// exit Javascript, prevent infinite looping over pictures
		}
	}
	// else exit
}

auto_switch.force = function()
{
	if (this.timeout != null)
		clearTimeout(this.timeout);
	if (fade.timeout != null)
		clearTimeout(fade.timeout);

	this.enable = false;

	fade.loops = 0;
	action.child.nodeValue = '';
	fade.activate(0);
}

auto_switch.setup = function()
{
	this.count = 0;
	action.child.nodeValue = 'Click on image to advance';
	bottom_image.img.onclick = function() {auto_switch.force(); return false;};
}

auto_switch.resume = function()
{
	this.setup();
	fade.activate(0);
}

top_image.display = function()
{
	this.copy_to_bottom();
	this.prepare();

	auto_switch.schedule();
}

top_image.load_doms = function()
{
	this.div = document.getElementById('main-top-div');
	this.img = document.getElementById('main-top-image');
	this.location = document.getElementById('main-top-location');
	this.location.a = document.getElementById('main-top-location-a');
	this.author = document.getElementById('main-top-author');

	this.author.appendChild(document.createTextNode(""));
	this.location.a.appendChild(document.createTextNode(""));
}

bottom_image.load_doms = function()
{
	this.div = document.getElementById('main-bottom-div');
	this.img = document.getElementById('main-bottom-image');
	this.location = document.getElementById('main-bottom-location');
	this.location.a = document.getElementById('main-bottom-location-a');
	this.author = document.getElementById('main-bottom-author');
}

top_image.set_start = function()
{
	// getTime() is used so page refresh displays the same image
	// cyle time is auto_switch.msecs plus fade time
	// top and bottom images are the same when initializing
	// assume half-way through time span on start
	top_image.slot = Math.floor(new Date().getTime() /
			(auto_switch.msecs + (fade.msecs * fade.loops)) + 0.5) %
			image.length;
}

action.prepare = function()
{
	this.div = document.getElementById('main-action-div');
	this.div.appendChild(document.createTextNode(""));
	this.child = this.div.firstChild;
}


top_image.load_doms();
bottom_image.load_doms();
action.prepare();

auto_switch.setup();

top_image.set_start();

// load top image and then force it to the bottom
top_image.load();

top_image.display();

// close anonymous function
})();
