
var Itemnum = -1 ;               // to start at item 0 - init from cookie in <head>
var Interval = 5 ;               // the time between a picture and the next in seconds in Auto mode - init from cookie
var Status = 'auto' ;            // {manual,auto} - init from cookie

var Helpstatus = 'help' ;      // help is on by default, value nohelp means it's off

var Interval2 = 4 ;              // speed of appear and fade in seconds, depends on Interval speed
var Timer1 = 0 ;                 // admin for setTimeout
var Timer2 = 0 ;                 // admin for setTimeout

var Items = new Array() ;        // list of Items
var Itemselector = new Array() ; // list of Item numbers in the array Items, for random presentation

var Preloading = true ;
var Preloadnum = -1 ;            // to start preload at item 0 - init from Itemnum during <head>
var Preloadstop = -1 ;           // to end preload at item 0   - init from Itemnum during <head>
var Preloadquant = 1 ;           // to preload 1 img per item
// the above values don't do anything - there is an init() function

var Doctitle = '' ;              // document title in <head><title> - set in the page-specific js
var Picid = '' ;                 // picture number unique to the while website - set in the page-specific js
var Randompresentation = false ; // type of ordering on the items - set in the page-specific js
var Defaults = new Array() ;     // defaults for every Item - set in the page-specific js

var isIE = (navigator.appName == "Microsoft Internet Explorer");
if (Helpstatus == 'help' && isIE) {document.title += 'IE :-('} // for developer only

//------------------------- admin of order of presentation

function nextitems() {                    // automatic mode
 Interval2 = Interval ;                   // at every cycle check whether user has changed Interval
                                          // not in setinterval() or nextitem() because Interval can be changed in more than one way
 if (Interval2 > 4) {Interval2 = 4}       // long Interval must not cause very slow effect
 if (Interval2 < 2) {Interval2 = 2}       // short Interval must not cause very fast effect
 nextitem(1) ;                                       // first
 Timer1 = setTimeout("nextitems()", 1000*Interval) ; // rest
}

function nextitem(direction) {                              // one item
 Itemnum = (Itemnum - 0 + direction) % Items.length ;       // previous or next item
 // note in the above statement how one disambiguates '+' to numerical addition... it's really necessary
 if (Itemnum < 0) {Itemnum = Items.length - 1} ;            // first.previous is last
 if (Randompresentation && Itemnum == 0) {randomselector()} ;
 if (Preloading) {preloadsome(Preloadquant)} // preload some imgs if necessary
 Effect.Fade('theitem',{ duration: Interval2/12 }) ;        // the item fades
 Timer2 = setTimeout("displaynext()", 1000*Interval2/12) ;  // wait with new item until fade is done
}

function displaynext(){
// window.scrollTo(0,0) ; was meant to prevent scrolling (see next line) but doesn't work properly
// because it makes jumpy transitions
 applysettings(Defaults) ;
 applysettings(Items[Itemselector[Itemnum]]) ;
 document.getElementById("theinterval").innerHTML = '' ;
// document.title = Doctitle + ' (' + (Itemselector[Itemnum] - 0 + 1) + '/' + Items.length + ')' + Picid;
 document.title = Doctitle + ' (' + (Itemnum - 0 + 1) + '/' + Items.length + ')' + Picid;
 Effect.Appear('theitem',{ duration: Interval2/8 }) ; // next item appears
}

function applysettings(item){
var i ;
var setting ;
 Picid = '' ;
 for (i=0; i<item.length; i++) {
  setting = item[i] ;
  if (setting.length == 1) {
   Picid = ' - Picture ID: ' + setting[0] ;
  }
  if (setting.length == 3) {
   document.getElementById(setting[0])[setting[1]] = setting[2] ;
  }
  if (setting.length == 4) { // css, setting[1] eq 'style'
   document.getElementById(setting[0])[setting[1]][setting[2]] = setting[3] ;
  }
 }
}

// random presentation
// the use of this Itemselector array is for random presentation
// in nonrandom mode Itemselector[i]==i for all i
// in random mode the Itemselector does 2 things:
// - each item maintains its fixed number, for reference
// - manual moves forward or backwards maintain the random order
//   ** except after a reshuffle
// random vs fixed order is not visitor-settable, this may still change

function initselector(){
var i ;
 for (i=0;i<Items.length;i++) {Itemselector[i]=i} ;
 if (Randompresentation) {randomselector()} ;
}
function randomselector(){
 Itemselector = shuffle(Itemselector)
}

function shuffle(r) {
// from http://michiel.wordpress.com/2009/03/23/how-to-shuffle-an-array/
// modified to keep the very first item first - typically the intro or title page
// could be generalised to keep the first n items in front
var pos;
var out = [];
 out.push(r[0]);
 r = r.slice(0,0).concat(r.slice(1, r.length));
 while (r.length > 0)	{
  pos = parseInt(Math.random()*r.length);
  out.push(r[pos]);
  r = r.slice(0,pos).concat(r.slice(pos+1, r.length));
 }
 return out;
}

//------------------------- user action: manual/auto, next/previous, speed, and help screen

 var Focus = true ;
 var Activeelement ;
// The use of activeElement was suggested by
// http://odondo.wordpress.com/2007/08/28/javascript-and-cross-browser-window-focus/
//
// He says it's for Firefox but elsewhere I read that activeElement is defined only for IE
// In practice, it seems to be necessary for IE, without it IE has many
// problems with mouse clicks. I don't understand what this does though.

function setFocusEvents() {
 Activeelement = document.activeElement;
 if (isIE){
  document.onfocusout = function() {onwindowblur() ; }
  document.onfocusin = function()  {onwindowfocus(); }
//  window.onblur = document.onfocusout ;
//  window.onfocus = document.onfocusin ;
 }
 else {
  window.onblur = function() {onwindowblur() ; }
  window.onfocus = function(){onwindowfocus() ; }
  document.onblur = window.onblur;  // experimental
  document.onfocus = window.onfocus;
 }
}

function onwindowblur() {
  if (!Focus || Status != 'auto') {return} ;
  if (Activeelement != document.activeElement) {
   Activeelement = document.activeElement ;
   return ;
  }
  if (Helpstatus == 'help') {document.title += 'b' ;}
  Focus = false ;
  clearTimeout(Timer1) ;
//  document.getElementById("thestatusline").innerHTML = 'This page is now in automatic mode, but suspended.' ;
}

function onwindowfocus(){
  if (Focus || Status != 'auto') {return}
  if (Helpstatus == 'help') {document.title += 'f' ;}
  Focus = true ;
  Timer1 = setTimeout("nextitems()", 1000*Interval) ;
 if (Helpstatus == 'help') {help()}          // to show modified Status in help screen
}

document.onkeydown = checkKeycode ;
function checkKeycode(e) {
 var keycode;
 if (window.event) keycode = window.event.keyCode;
 else if (e) keycode = e.which;
// alert(keycode) ;
 if (keycode == '77' || keycode == '65') {switchstate(keycode)}
 else if (keycode == '37') {switchstate(-1)}
 else if (keycode == '32' || keycode == '39') {switchstate(1)}
 else if (keycode == '40') {setinterval(-1)}
 else if (keycode == '38') {setinterval(1)}
 else if (keycode == '49') {Itemnum = -1 ; if (Status == 'manual') {nextitem(1)} else {clearTimeout(Timer1); nextitems()}}
 else if (keycode == '72') {if (Helpstatus == 'nohelp') {help()} else {closehelp()}}
 if (Helpstatus == 'help') {help()}          // to show modified Status in help screen
 document.getElementById("hack").focus() ;   // for unclear reason I have to repeat this
                                             // the problem occurred after I added the help()
 }

function setinterval(x){
 if (Status == 'manual') {return} ;
 Interval += (x - 0) ;
 if (Interval < 1) { Interval = 1 }
 document.getElementById("theinterval").innerHTML = 'Interval: ' + Interval + ' seconds' ;
}

function switchstate(direction) {
 if (direction == '65' && Status == 'auto') {return} ;
 clearTimeout(Timer1);                                     // stops the recursion
 if (direction == '65') {                                  // 'a'
  Status = 'auto' ;
  Timer1 = setTimeout("nextitems()", 1000*Interval) ;
 }
 else  if (direction == '77') {                           // 'm'
   Status = 'manual' ;
   Interval2 = 2 ;                                        // speedy transitions in Manual mode
 }
 else {                                                   // left arrow or right arrow or space bar
  Interval2 = 2 ;                                         // speedy transitions in Manual mode
  nextitem(direction) ;
  if (Status == 'auto') {Timer1 = setTimeout("nextitems()", 1000*Interval) ; } ;
 }
}

function help(){
 document.getElementById("thehelptextl").innerHTML = helptextl() ;
 document.getElementById("thehelptextr").innerHTML = helptextr(Status,Interval) ;
 document.getElementById("thehelplink").innerHTML = '<a onclick="closehelp()" href="#">Hide text</a>' ;
 document.getElementById("popup").style.display = '' ;
 Helpstatus = 'help' ;
}

function closehelp(){
  document.getElementById("popup").style.display = 'none' ;
  document.getElementById("thehelplink").innerHTML = '<a onclick="help()" href="#">Show text</a>' ;
  Helpstatus = 'nohelp' ;
}


function helptextl(){
return('To make this text disappear, press \'Hide text\'. You can always make it reappear. \
<br /><br />All pictures have a Picture ID which is displayed in the top title bar of your browser. \
This ID is unique w.r.t. the whole website and can be used for reference. \
<br /><br />The photography on these pages is by  Louis des Tombe (unless indicated otherwise) and is licensed under a \
<a rel="license" href="http://creativecommons.org/licenses/by-nc-nd/3.0/">Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License</a>. \
This means that you can copy and distribute it but you have to mention me as the photographer, and \
you cannot modify it or use it for commercial purposes. \
<br /><br />If you have any questions or comments, <a href="' + m() + '">send me an email!</a> \
') ;
}

function m(){
var a = '&#109;a&#105;l';
var b = 'desto';
var c = 'mbe.nl';
return(a + 't&#111;:' + a + "&#64;" + b + c)
}

function helptextr(mode,interval){
var h1 = ' \
To minimize clutter, the page settings can be manipulated only by the keyboard: \
<br /><br />- Press \'a\' for automatic or \'m\' for manual page turning. \
<br />- (Currently the page is in ' ;

var h2 = (mode == 'manual')?'manual mode)':'automatic mode with an interval of ' + interval + ' seconds)' ;

var h3 = ' \
<br />- Use the arrow keys &larr; or &rarr; to go to the previous or next item. \
<br />- Use the arrow keys &uarr; or &darr; to change the speed in automatic mode. \
<br />- Press \'1\' to go to the first item. \
<br /><br />In automatic mode, the show is supposed to pause when you bring another window or tab into focus. \
Unfortunately it does not always work, sometimes the show keeps running when out of focus. Sorry for that. \
' ;
return(h1+h2+h3);
}

//------------------------- Cookies set/read from init() and exiting()
//------------------------- taken from http://www.quirksmode.org/js/cookies.html
// Cookie functions taken from http://www.quirksmode.org/js/cookies.html

function createcookie(name,value,days,path) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=" + path;
}

function readcookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return 0;  // little modification, was *null* but I'm afraid of null
}

//------------------------- preloading images
// preloads only some (Preloadquant) to avoid delays 'please wait....'
// typically preloads 2 per item until all are preloaded

function preloadsome(howmany){
// alert('Preloadnum ' + Preloadnum) ;
 for (var i=0;i<howmany;i++) {
  if (Helpstatus == 'help') {document.title += '+' + Itemselector[Preloadnum] ;}
  var item = Items[Itemselector[Preloadnum]] ;
  for (var j=0;j<item.length;j++) {
//    alert(item[j][1]) ;
    if (item[j][1] == 'src') {
     var img = new Image(1,1) ;
     img.src = item[j][2] ;
    }
  }
  Preloadnum++ ;
  if (Preloadnum == Items.length) {Preloadnum = 0}
  if (Preloadnum == Preloadstop) {
    Preloading = false ;
    return ;
  }
 }
}

//------------------------- init and exit


function init0(){   // gets initial values for global variables
 Helpstatus = readcookie('helpstatus') ;
 if (Helpstatus != 'nohelp'){Helpstatus = 'help'} ;
 Status = readcookie('status') ;
 if (Status != 'manual'){Status = 'auto'} ;
 Interval = readcookie('interval') ;
 if (isNaN(Interval) || Interval < 1 || Interval > 25){Interval = 7} ;
 Interval -= 0 ; // funny, this seems to tell JS that it's a number - for later disambiguation of '+'
 Interval2 = 2 ;
 Itemnum = readcookie('itemnum') ;
 if (isNaN(Itemnum) || Itemnum < 0 || Itemnum >= Items.length) {Itemnum = 0} ;
 initselector() ;
 if (Randompresentation) {Itemnum = 0 ; } ;
 Preloadquant = 2 ;
 Preloadnum = Itemnum ;
 Preloadstop = Itemnum ;
 preloadsome(2) ;
}

function init(){  // starts the process

// an alternative method for event listening, to be tested:
// var fld = document.getElementById("theitem") ;
// if (fld.addEventListener) {document.title += 'listener!'} ;
// if (fld.attachEvent) {document.title += 'IE-listener!'} ;

 if (Helpstatus == 'help') {help()} else {closehelp()} ;
 clearTimeout(Timer1) ;
 clearTimeout(Timer2) ;
 document.getElementById("hack").focus() ;
 // funny hack - prevents undesired scrolling when user presses a key (incl arrow keys),
 // scrolls still on mouse input
 // Source: http://www.webmasterworld.com/forum91/5658.htm guy called trevordixon
 // overbodig: document.getElementById("thehelplink").innerHTML = '<a onclick="help()" href="#">Hide text</a>' ;
 setFocusEvents() ;
 Focus = true ;
 document.getElementById("theitem").style.display = 'none' ;
 displaynext() ;
 if (Status == 'auto') {Timer1 = setTimeout("nextitems()", 1000*Interval) ;} ;
}

function exiting(){   // name chosen assuming 'exit()' might be reserved
 clearTimeout(Timer1) ;
 clearTimeout(Timer2) ;
 if (Status != 'manual'){Status = 'auto'} ;
 createcookie('status',Status,30,'') ;
 if (isNaN(Interval) || Interval < 1 || Interval > 25){Interval = 7} ;
 createcookie('interval',Interval,30,'') ;
 if (isNaN(Itemnum) || Itemnum < 0 || Itemnum >= Items.length) {Itemnum = 0}
 createcookie('itemnum',Itemnum,7,'') ;
 if (Helpstatus != 'help') {Helpstatus = 'nohelp'}
 createcookie('helpstatus',Helpstatus,30,'/') ;
}


