//******************************************************
// IXF1.11 :: Image cross-fade 
// DOM scripting by brothercake -- http://www.brothercake.com/
//******************************************************

//global object
var ixf = { 'clock' : null, 'count' : 1 }

//List the images that need to be cached
ixf.imgs = [];

//cache the images
ixf.imgsLen = ixf.imgs.length;
ixf.cache = [];
for(var i=0; i<ixf.imgsLen; i++)
{
	ixf.cache[i] = new Image;
	ixf.cache[i].src = ixf.imgs[i];
}

//crossfade setup function
function crossfade()
{
	//if the timer is not already going
	if(ixf.clock == null) 
	{
		//copy the image object 
		ixf.obj = arguments[0];
		
		//copy the image src argument 
		ixf.src = arguments[1];
		
		//store the supported form of opacity
		if(typeof ixf.obj.style.opacity != 'undefined')
		{
			ixf.type = 'w3c';
		}
		else if(typeof ixf.obj.style.MozOpacity != 'undefined')
		{
			ixf.type = 'moz';
		}
		else if(typeof ixf.obj.style.KhtmlOpacity != 'undefined')
		{
			ixf.type = 'khtml';
		}
		else if(typeof ixf.obj.filters == 'object')
		{
			ixf.type = (ixf.obj.filters.length > 0 && typeof ixf.obj.filters.alpha == 'object' && typeof ixf.obj.filters.alpha.opacity == 'number') ? 'ie' : 'none';
		}
		else
		{
			ixf.type = 'none';
		}
		
		//change the image alt text if defined
		if(typeof arguments[3] != 'undefined' && arguments[3] != '')
		{
			ixf.obj.alt = arguments[3];
		}
		
		//if any kind of opacity is supported
		if(ixf.type != 'none')
		{
			//create a new image object and append it to body
			ixf.newimg = document.getElementsByTagName('body')[0].appendChild((typeof document.createElementNS != 'undefined') ? document.createElementNS('http://www.w3.org/1999/xhtml', 'img') : document.createElement('img'));

			//set positioning classname
			ixf.newimg.className = 'idupe';
			
			//set src to new image src
			ixf.newimg.src = ixf.src

			//move it to superimpose original image
			//#JdJ# Added 1 pixel
			ixf.newimg.style.left = (ixf.getRealPosition(ixf.obj, 'x') + 1) + 'px';
			ixf.newimg.style.top = (ixf.getRealPosition(ixf.obj, 'y') + 1) + 'px';
			
			//copy and convert fade duration argument 
			ixf.length = parseInt(arguments[2], 10) * 1000;
			
			//create fade resolution argument as 20 steps per transition
			ixf.resolution = parseInt(arguments[2], 10) * 20;
			
			//start the timer
			ixf.clock = setInterval('ixf.crossfade()', ixf.length/ixf.resolution);
		}
		
		//otherwise if opacity is not supported
		else
		{
			//just do the image swap
			ixf.obj.src = ixf.src;
		}
	}
};

//crossfade timer function
ixf.crossfade = function()
{
	//decrease the counter on a linear scale
	ixf.count -= (1 / ixf.resolution);
	
	//if the counter has reached the bottom
	if(ixf.count < (1 / ixf.resolution))
	{
		//clear the timer
		clearInterval(ixf.clock);
		ixf.clock = null;
		
		//reset the counter
		ixf.count = 1;
		
		//set the original image to the src of the new image
		ixf.obj.src = ixf.src;
	}
	
	//set new opacity value on both elements
	switch(ixf.type)
	{
		case 'ie' :
			ixf.obj.filters.alpha.opacity = ixf.count * 100;
			ixf.newimg.filters.alpha.opacity = (1 - ixf.count) * 100;
			break;
			
		case 'khtml' :
			ixf.obj.style.KhtmlOpacity = ixf.count;
			ixf.newimg.style.KhtmlOpacity = (1 - ixf.count);
			break;
			
		case 'moz' : 
			//restrict max opacity to prevent a visual popping effect in firefox
			ixf.obj.style.MozOpacity = (ixf.count == 1 ? 0.9999999 : ixf.count);
			ixf.newimg.style.MozOpacity = (1 - ixf.count);
			break;
			
		default : 
			//restrict max opacity to prevent a visual popping effect in firefox
			ixf.obj.style.opacity = (ixf.count == 1 ? 0.9999999 : ixf.count);
			ixf.newimg.style.opacity = (1 - ixf.count);
	}
	
	//now that we've gone through one fade iteration 
	//we can show the image that's fading in
	ixf.newimg.style.visibility = 'visible';
	
	//keep new image in position with original image
	//in case text size changes mid transition or something
	ixf.newimg.style.left = ixf.getRealPosition(ixf.obj, 'x') + 'px';
	ixf.newimg.style.top = ixf.getRealPosition(ixf.obj, 'y') + 'px';
	
	//if the counter is at the top, which is just after the timer has finished
	if(ixf.count == 1)
	{
		//remove the duplicate image
		ixf.newimg.parentNode.removeChild(ixf.newimg);
	}
};

//get real position method
ixf.getRealPosition = function()
{
	this.pos = (arguments[1] == 'x') ? arguments[0].offsetLeft : arguments[0].offsetTop;
	this.tmp = arguments[0].offsetParent;
	while(this.tmp != null)
	{
		this.pos += (arguments[1] == 'x') ? this.tmp.offsetLeft : this.tmp.offsetTop;
		this.tmp = this.tmp.offsetParent;
	}
	
	return this.pos;
};


/*==================================================*
 $Id: slideshow.js,v 1.16 2003/10/14 12:39:00 pat Exp $
 Copyright 2000-2003 Patrick Fitzgerald
 http://slideshow.barelyfitz.com/
 *==================================================*/
 
// slide object
function slide(src,link,text,target,attr) {

  // Image URL
  this.src = src;

  // Custom duration for the slide (optional), in milliseconds.
  // this.timeout = 3000;

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

  // Flag to tell when load() has already been called
  this.loaded = false;

  this.load = function() {
    // This method loads the image for the slide

    if (!document.images) { return; }

    if (!this.loaded) {
      this.image.src = this.src;
      this.loaded = true;
    }
  }
}

// slideshow object
function slideshow( slideshowname ) {

  // Name of this object (required if you want your slideshow to auto-play)
  this.name = slideshowname;

  // When we reach the last slide, should we loop around?
  this.repeat = true;
  this.cycles = 0; //#JdJ#

  // Number of images to pre-fetch
  // -1 = preload all images.
  //  0 = load each image as it is used.
  //  n = pre-fetch n images ahead of the current image.
  this.prefetch = 1;

  // IMAGE element on your HTML page
  this.image;

  // Milliseconds to pause between slides.
  // Individual slides can override this.
  this.timeout = 6000;

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

  // Private variables
  this.slides = new Array();
  this.current = 0;
  this.timeoutid = 0;
  this.currentcycle = 0; //#JdJ#
  this.total = 0; //#JdJ#

  //--------------------------------------------------
  // Public methods
  //--------------------------------------------------
  this.add_slide = function(slide) {
    // Add a slide to the slideshow.
  
    var i = this.slides.length;
  
    // Prefetch the slide image if necessary
    if (this.prefetch == -1) {
      slide.load();
    }

    this.slides[i] = slide;
  }

  //--------------------------------------------------
  this.play = function(timeout) {
    // This method implements the automatically running slideshow.
  
    // Make sure we're not already playing
    this.pause();
  
    // If the timeout argument was specified (optional)
    // then make it the new default
    if (timeout) {
      this.timeout = timeout;
    }
  
    // If the current slide has a custom timeout, use it;
    // otherwise use the default timeout
    if (typeof this.slides[ this.current ].timeout != 'undefined') {
      timeout = this.slides[ this.current ].timeout;
    } else {
      timeout = this.timeout;
    }
	
	//#JdJ# Compensate for crossfade duration for very first slide
	if (this.total == 0) timeout -= 1000;

    // After the timeout, call this.loop()
    this.timeoutid = setTimeout( this.name + ".loop()", timeout);
  }

  //--------------------------------------------------
  this.pause = function() {
    // This method stops the slideshow if it is automatically running.
  
    if (this.timeoutid != 0) {

      clearTimeout(this.timeoutid);
      this.timeoutid = 0;

    }
  }

  //--------------------------------------------------
  this.update = function() {
    // This method updates the slideshow image on the page

    // Make sure the slideshow has been initialized correctly
    if (! this.valid_image()) { return; }
  
    // Call the pre-update hook function if one was specified
    if (typeof this.pre_update_hook == 'function') {
      this.pre_update_hook();
    }
	//#JdJ Do pre-update stuff:
	// Reset all tokens
    for (var i = 0; i < this.slides.length; i++) {
      myToken = this.getElementById('token'+(i + 1));
      if (myToken) { myToken.className = 'token'; }
    }
    
    // Convenience variable for the current slide
    var slide = this.slides[ this.current ];
	
    // Load the slide image if necessary
    slide.load();
  
    // Update the image
	//this.image.src = slide.image.src;
	//#JdJ#
	// Verhoog de div alvast zodat de tekst eronder verspringt voordat de fade plaatsvindt
	var h = slide.image.height;
	if (h) document.getElementById('slideshow').style.height = h + 'px';
	if (this.total == 0) {
	  // Do not crossfade the very first slide!
	  this.image.src = slide.image.src;
	}else{
	  // Mozilla Crossfade by Brothercake
	  crossfade(this.image, slide.image.src, '1', '');
    }
	
    // Call the post-update hook function if one was specified
    if (typeof this.post_update_hook == 'function') {
      this.post_update_hook();
    }
	//#JdJ Do post-update stuff:
	// Hilite current token
	myToken = this.getElementById('token'+(this.current + 1));
    if (myToken) { myToken.className = 'token selected'; }

    // Do we need to pre-fetch images?
    if (this.prefetch > 0) {

      var next, prev, count;

      // Pre-fetch the next slide image(s)
      next = this.current;
      prev = this.current;
      count = 0;
      do {

        // Get the next and previous slide number
        // Loop past the ends of the slideshow if necessary
        if (++next >= this.slides.length) next = 0;
        if (--prev < 0) prev = this.slides.length - 1;

        // Preload the slide image
        this.slides[next].load();
        this.slides[prev].load();

        // Keep going until we have fetched
        // the designated number of slides

      } while (++count < this.prefetch);
    }
  }

  //--------------------------------------------------
  this.goto_slide = function(n) {
  
    //#JdJ Disable goto button for slide that is already showing
    if (n == this.current){
  	  this.pause();
	}else{
	
      //#JdJ# Disable goto button when fade is in progress
	  if(ixf.clock == null) {  //if the timer is not already going
	
        if (n == -1) {
          n = this.slides.length - 1;
        }
  
        if (n < this.slides.length && n >= 0) {
          this.current = n;
        }
  
  	    this.total++; //#JdJ#
	  
        this.pause();  //#JdJ#
        this.update();
	  
	  }
	}
  }

  
  //--------------------------------------------------
  this.next = function() {
    // This method advances to the next slide.

    // Increment the image number
    if (this.current < this.slides.length - 1) {
      this.current++;
    } else if (this.repeat) {
	  this.currentcycle++; //#JdJ#
      this.current = 0;
    }
	this.total++; //#JdJ#
	
    this.update();
  }


  //--------------------------------------------------
  this.previous = function() {
    // This method goes to the previous slide.
  
    // Decrement the image number
    if (this.current > 0) {
      this.current--;
    } else if (this.repeat) {
      this.current = this.slides.length - 1;
    }
  
    this.update();
  }


  //==================================================
  // Private methods
  //==================================================

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

    // Make sure the next slide image has finished loading
    if (this.current < this.slides.length - 1) {
      next_slide = this.slides[this.current + 1];
      if (next_slide.image.complete == null || next_slide.image.complete) {
        this.next();
      }
    } else { // we're at the last slide
      this.next();
    }
    
    // Keep playing the slideshow
	//this.play();
	//#JdJ#
	if (this.cycles){
	  if (this.currentcycle < this.cycles){
	    this.play();
	  }else{
	    // Desired number of cycles reached, stop the loop
	    this.pause();
	    this.cycles = 0; //no more cycle limit if the user clicks play after this
	  }
	}else{
	  this.play();
	}
  }

  //--------------------------------------------------
  this.valid_image = function() {
    // Returns 1 if a valid image has been set for the slideshow
  
    if (!this.image)
    {
      return false;
    }
    else {
      return true;
    }
  }
  
  //--------------------------------------------------
  this.getElementById = function(element_id) {
    // This method returns the element corresponding to the id

    if (document.getElementById) {
      return document.getElementById(element_id);
    }
    else if (document.all) {
      return document.all[element_id];
    }
    else if (document.layers) {
      return document.layers[element_id];
    } else {
      return undefined;
    }
  }

}
