/*
 *  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
};


var image = momjian_us_image;


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].location_url;
	this.photographer.a.href = image[top_image.slot].photographer_url;
	this.location.a.firstChild.nodeValue = image[top_image.slot].location;
	this.photographer.a.firstChild.nodeValue =
		(image[top_image.slot].photographer != '') ? 'photographer ' + image[top_image.slot].photographer : '';

	// turn off anchor highlighting if there is no href value
	// we have to test the variable because an href of '' defaults to our hostname
	if (image[top_image.slot].location_url === '')
		this.location.a.className = 'no-href';
	else
		this.location.a.className = '';
	if (image[top_image.slot].photographer_url === '')
		this.photographer.a.className = 'no-href';
	else
		this.photographer.a.className = '';
}

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.photographer.a.href = this.photographer.a.href;
	bottom_image.location.a.firstChild.nodeValue = this.location.a.firstChild.nodeValue;
	bottom_image.photographer.a.firstChild.nodeValue = this.photographer.a.firstChild.nodeValue;
	bottom_image.location.a.className = this.location.a.className;
	bottom_image.photographer.a.className = this.photographer.a.className;

	bottom_image.location.style.display = 'block';
	bottom_image.photographer.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.photographer.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';
	// Turn off dotted outline on click?  blur() does not work
	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.photographer = document.getElementById('main-top-photographer');

	this.location.a = document.getElementById('main-top-location-a');
	this.photographer.a = document.getElementById('main-top-photographer-a');

	this.location.a.appendChild(document.createTextNode(""));
	this.photographer.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.photographer = document.getElementById('main-bottom-photographer');
	this.location.a = document.getElementById('main-bottom-location-a');
	this.photographer.a = document.getElementById('main-bottom-photographer-a');
}

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
})();

