// slideshow.js

var UNDEF='undefined';
var d = true;
if(d && typeof console == UNDEF) d=false;
if (typeof console == UNDEF){ 
	window.console = new Object();
	window.console.log = function() {};
}
safari=(navigator.userAgent.indexOf('Safari')!=-1);

var slideshowArr = new Array();


function slideshowLoop(i){

	var s = slideshowArr[i];

if(d)dbg('<hr>in Loop Timeout .. i=' +i+ ' stpd='+s.stopped);

	if (s.stopped) return;

	var nslide = s.slideArr[ s.current ];
	if (nslide.image.complete == false){
if(d)dbg('<li>still waiting for slide.'+s.current);
    		s.timer = setTimeout('slideshowLoop('+i+')',100)
		return;
	}

	if (!nslide.alreadyShown) s.advanceSlide(0);
	else s.advanceSlide();
		
	s.keepGoing();
}


function slideshowGoto(i,n)
{
if(d)dbg('<hr>in Goto Timeout .. i=' +i+ ' n='+n);
	var s = slideshowArr[i];
	var nslide = s.getSlide(n);
	if (nslide.image.complete == false){
if(d)dbg('<li>still waiting for slide.'+nslide.n);
		s.timer = setTimeout('slideshowGoto('+i+','+nslide.n+')',100);
		return;
	}
	s.advanceSlide(0);
}


//==================================================
function slide(src,link,text,target,attr) 	// constructor
{

  this.src = src;	// url of image

  this.text = text;	// text to display w img

  // Create an image object for the slide
  if (document.images) {
    this.image = new Image();
  }

  this.alreadyPreloaded = false;
  this.alreadyShown = false;


  //--------------------------------------------------
  this.preload = function(n) {

    if (document.images && !this.alreadyPreloaded){

if(d)dbg(' ... preloading slide.'+n);

      this.image.src = this.src;
      this.alreadyPreloaded = true;
    }
  }
}




function slideshow( slideshowname ) 	// constructor
{


  // store this in global array - for easier handling of timeouts
  this.index = slideshowArr.length;
  this.id = slideshowArr.length;
  slideshowArr.push(this);

  this.name = slideshowname;

  // When we reach the last slide, should we loop around to start the
  // slideshow again?
  this.repeat = true;

  // Number of images to pre-fetch.
  // -1 = preload all images.
  //  0 = load each image is it is used.
  //  n = pre-fetch n images ahead of the current image.
  // I recommend preloading all images unless you have large
  // images, or a large amount of images.
  this.prefetch = -1;

  this.imgEl;	// element shere image is to be placed
  this.txtEl;	// element where slide text is to be placed

  this.playSpeed = 3000; // msecs

  // Hook functions to be called before and after updating the slide
  // this.updateCb = function() { }
  // this.toolbarCb = function() {}

  // These are private variables
  this.slideArr = new Array();
  this.current = 0;
  this.timer = 0;
  this.stopped = true;

  //--------------------------------------------------
  // Public methods
  //--------------------------------------------------
  this.add_slide = function(slide) {
    // Add a slide to the slideshow.
    // For example:
    // SLIDES1.add_slide(new slide("s1.jpg", "link.html"))
  
    var i = this.slideArr.length;
    this.slideArr[i] = slide;
  
    // Prefetch the slide image if necessary
    if (this.prefetch == -1) {
      slide.preload(i);
    }

  }

  //--------------------------------------------------
  this.toggleMode = function(){

//if(d)console.log('toggleMode stopped is ',this.stopped);

	if (this.stopped){ 
		//this.next(); 
		this.keepGoing(100); 
	}
	else  	this.pause();

	this.toolbarCb();
  }

  //--------------------------------------------------
  this.start = function() {
	this.current = 0;
	this.restart();
  }

  //--------------------------------------------------
  this.restart = function() {
	this.stopped = false;
	this.preloadSlide(0);
	this.keepGoing(100);
	this.toolbarCb(100);	// auto-play et al
	this.updateCb(100);	// slide numbers
  }


  //--------------------------------------------------
  this.keepGoing = function(msec) {

    // make sure there are not timeouts in progress
    this.clearTimeout();
    this.stopped = false;

    if (typeof msec == UNDEF) msec = this.playSpeed;
  
    // If the current slide has a custom playSpeed, use it;
    // otherwise use the default timeout
    if (typeof this.slideArr[ this.current ].playSpeed != UNDEF ) 
      msec = this.slideArr[ this.current ].playSpeed;

    this.timer = setTimeout('slideshowLoop('+this.index+')',msec)

if(d)dbg('<li>keepGoing new.tid='+this.timer + ' in ' + msec + ' msec.');
	

  }

  //--------------------------------------------------
  this.clearTimeout = function() {

    // remove pending timeout
    // usually called when stopping, or for safety
	

//if(d)console.log('ss.pause tid=',this.timer);
//if(d)console.log('ss.pause, this.stopped: ',this.stopped); 
  
    if (this.timer != 0) {

//if(d)console.log('ss.pause . . . . . . clearing tid=',this.timer);
if(d)dbg('<li>pause.clearing tid='+this.timer);
      clearTimeout(this.timer);
      this.timer = 0;

    }
  }


  //--------------------------------------------------
  this.pause = function() {
if(d)console.log(this.id,' STOP tid=',this.timer);
	this.stopped = true;
	this.clearTimeout();
	this.toolbarCb();
  }

  //--------------------------------------------------
  this.faster = function() {
	// increase speed
	var i = this.playSpeed;
	this.playSpeed = parseInt(i*0.66);
if(d)console.log('new faster playSpeed ',this.playSpeed);
	this.advanceSlide();
  }

  //--------------------------------------------------
  this.slower = function() {
	var i = this.playSpeed;
	this.playSpeed = parseInt(i*1.5);
if(d)console.log('new slower playSpeed ',this.playSpeed);
  }
  







  //--------------------------------------------------
  this.update = function() {

    	if (! this.imgEl) return;
  
    	var slide = this.getSlide(this.current); 
    	var n = slide.n;

if(d)dbg(slide);
if(d)dbg(slide.image);

if(d)dbg('<br> . . . slide.'+n+'.complete='+slide.image.complete + ' :: ' + slide.image.src);

  
    	if (!slide.image.complete){
if(d)dbg('<li>cannot update. waiting for image.'+n+' to complete');
		return;
    	}
        if (safari) {
             //http://www.quirksmode.org/bugreports/archives/2005/03/Safari_Image_src_swap_resize_bug.html
             this.imgEl.src ="dot_clear.gif"
	}
    	this.imgEl.src = slide.image.src;
    	slide.alreadyShown = true;

    	if (typeof this.updateCb == 'function') this.updateCb();

    	// Update the text
	var el = this.txtEl;
	if (el && typeof el.innerHTML !=UNDEF){
		el.innerHTML = slide.text;
	}

  }

  //--------------------------------------------------
  this.gotoSlide = function(n) {

if(d)dbg('<li>gotoSlide ' + n);

    if (typeof n == UNDEF) n = this.current;

    if (n < this.slideArr.length && n >= 0) {
      this.current = n;
if(d)dbg('<li>setting current slide to ' + n);
    }

    var slide = this.getSlide(this.current)
    if (!slide.alreadyPreloaded || slide.image.complete == false){
    	this.preloadSlide(n);
	slideshowGoto(this.index,this.current);
    }
    else {
    	this.update();
    }
  }


  //--------------------------------------------------
  this.next = function() {
    this.pause();
    this.current++; if (this.current >= this.slideArr.length) this.current=0;
    this.gotoSlide(this.current);
  }


  //--------------------------------------------------
  this.preloadSlide = function(n) {
	if (typeof n == UNDEF) n = this.current;
	var slide = this.getSlide(n);
	slide.preload(n);
  }

  //--------------------------------------------------
  this.getSlide = function(n) {
if(d)dbg('<li>getSlide n='+n);

	if (typeof n == UNDEF) n = this.current;

	if (n >=  this.slideArr.length)   n =0;
	if (n < 0) 			  n =0;
if(d)dbg(' ... '+n);
	var slide = this.slideArr[n];
	slide.n = n;
	return slide;
  }

  this.prefetchSlides = function() {

	var nx = this.current;
	var ny = this.current;
	for (j=0; j<this.prefetch; j++){
		nx += 1; ny-=1;
		this.preloadSlide(nx);
		this.preloadSlide(ny);
	}
  }


  //--------------------------------------------------
  this.advanceSlide = function(delta) {


	if (typeof delta == UNDEF) delta = 1 ;

	var nslide = this.getSlide(this.current+delta);
	n = nslide.n;

	// preload a few slides while we are here
	this.prefetchSlides();


if(d)dbg('<li>in advanceSlide from '+this.current + ' to'+n);

    	// Make sure the new slide image has finished loading
    	var bool = false;

	if (nslide.image.complete == null 
			|| nslide.image.complete) bool = true;

    	if(bool){
		this.current = n;
	
		this.update();
	}
	else { 
if(d)dbg('<br>... still waiting for slide.'+n+' to complete--'+nslide.image.src);
	}


  }


  //--------------------------------------------------
  this.previous = function() {
    this.pause();
    this.current--; 
    if (this.current < 0) this.current = this.slideArr.length - 1;
    this.gotoSlide(this.current);
  }


}
  

