﻿// Javascript Slideshow

function setOpacity(elem, opacity){
    /// <summary>Sets the required opacity on element elem</summary>
    /// <param name="elem">The element to change the opacity</param>
    /// <param name="opacity" type="float">The wanted opacity, between 0 and 1</param>
    elem.style.opacity = opacity; // For standard browsers, value between 0 to 1
	elem.style.filter = 'alpha(opacity=' + opacity * 100 + ')'; // for IE (needs value from 1 to 100)
}

var SlideshowImage = function(path, link){
/// <summary>Constructor for SlideshowImage</summary>
/// <param name="path" type="string">The path to the SlideshowImage</param>
/// <param name="link" type="string">A link for the image, or left empty</param>
/// <returns type="void"></returns>
    this.Path = path;
    this.Link = link;
}

SlideshowImage.prototype.HasLink = function(){
    /// <summary>Checks whether the SlideshowImage has a link or not</summary>
    /// <returns type="bool">Returns true if the SlideshowImage has a link, false otherwise</returns>
    
    return (this.Link != null && this.Link != "");
}

SlideshowImage.prototype.GetImagePath = function(){
    return this.Path;
}

SlideshowImage.prototype.GetImageLink = function(){
    return this.Link;
}

SlideshowImage.prototype.GetImageDimensions = function(){
    var tmpImg = new Image();
    tmpImg.src = this.GetImagePath();
    return { width: tmpImg.width, height: tmpImg.height };
}

var SlideshowSettings = function(interval, fadeTime, repeat){
/// <summary>Constructor for SlideshowSettings</summary>
/// <param name="interval" type="int">The interval between image switching, in seconds</param>
/// <param name="fadeTime" type="int">The time it takes the slideshow to fade the image, in milliseconds (0 if no fading is desired)</param>
/// <param name="repeat" type="bool">Sets whether the Slideshow goes back to the beginning</param>
/// <returns type="void"></returns>
    this.Interval = interval * 1000; // Change to milliseconds
    this.FadeTime = fadeTime;
    this.NumOfFades = 10; // Fade 10 times, reducing the percentage of the opacity by 10 each time
    this.Repeat = repeat;
    this.AnchorTarget = "_self";
    this.RenderAsBackground = false;
    this.BackgroundDivID = "SlideshowBackgroundDiv";
}

var Slideshow = function(settings, slideshowImages, container) {
/// <summary>Constructor for Slideshow</summary>
/// <param name="settings" type="SlideshowSettings">The SlideshowSettings</param>
/// <param name="slideshowImages">The list of images</param>
/// <param name="container">The container for the images</param>
/// <returns type="void"></returns>

    // Settings members
    this.Interval = settings.Interval;
    this.FadeTime = settings.FadeTime;
    this.Repeat = settings.Repeat;
    this.NumOfFades = settings.NumOfFades;
    this.RenderAsBackground = settings.RenderAsBackground;
    
    // Extra members
    this.SlideshowImages = slideshowImages;
    if(!this.RenderAsBackground)
    {
        this.ImageObject = new Image();
        this.ImageObject.src = this.SlideshowImages[0].GetImagePath();
    }
    else
    {
        this.ImageObject = document.createElement("div");
        this.ImageObject.style.backgroundImage = "url(" + this.SlideshowImages[0].GetImagePath() + ")";
        var dimensions = this.SlideshowImages[0].GetImageDimensions();
        this.ImageObject.style.width = dimensions.width + "px";
        this.ImageObject.style.height = dimensions.height + "px";
        this.ImageObject.setAttribute("id", settings.BackgroundDivID);
    }
    setOpacity(this.ImageObject, 0); // Initialize the image opacity to 0
    this.Anchor = document.createElement("a");
    this.Anchor.setAttribute("target", settings.AnchorTarget);
    this.Container = container;
    
    // Initialize the opacity to 0
    this.CurrentOpacity = 0;
    this.CurrentImageIndex = 0;
    this.CurrentFade = 0;
    
    // Events
    this.ImageChanging = function(){};
    this.ImageChanged = function(){};
    
    // Initialize the Slideshow
    this.PreloadImages();
    this.Anchor.appendChild(this.ImageObject);
    this.Container.appendChild(this.Anchor);
}

Slideshow.prototype.PreloadImages = function(){
/// <summary>Loads all the images in the slideshow to the browser's cache</summary>
    var i;
    var tmpImage;
    for(i = 0; i < this.SlideshowImages.length; i++)
    {
        tmpImage = new Image();
        // Set the source of the image for it to be virtually loaded
        tmpImage.src = this.SlideshowImages[i].GetImagePath();
    }
}

Slideshow.prototype.Begin = function(){
    // Show the first image
    this.ChangeImage();
    this.FadeIn();
}

Slideshow.prototype.GetCurrentImage = function(){
    /// <summary>Get the current image path in the slideshow</summary>
    /// <returns type="Image">Returns the current image in the slideshow</returns>
    return this.SlideshowImages[this.CurrentImageIndex];
}

Slideshow.prototype.ChangeImage = function(){
    /// <summary>Inserts the current image into the container, and raises the ImageChanged event</summary>
    
    // Raise ImageChanging event
    this.ImageChanging();
    if(!this.RenderAsBackground)
    {
        // Change the image
        this.ImageObject.src = this.GetCurrentImage().GetImagePath();
    }
    else
    {
        // Change backgroud
        this.ImageObject.style.backgroundImage = "url(" + this.GetCurrentImage().GetImagePath() + ")";
        var dimensions = this.GetCurrentImage().GetImageDimensions();
        this.ImageObject.style.width = dimensions.width + "px";
        this.ImageObject.style.height = dimensions.height + "px";
    }
    // Change the link
	var link = this.GetCurrentImage().GetImageLink();
	if(link == "")
	{
		this.Anchor.removeAttribute("href");
	}
	else
	{
    	this.Anchor.setAttribute("href", link);
	}
    // Raise ImageChanged event
    this.ImageChanged();
}


Slideshow.prototype.NextImage = function(){
    /// <summary>Moves to the next image in the list, or returns to the beginning if it's the end, and repeating is enabled</summary>
    this.CurrentImageIndex++;
    
    if(this.CurrentImageIndex == this.SlideshowImages.length)
    {
        this.CurrentImageIndex = 0;
    }
}

Slideshow.prototype.PreviousImage = function(){
    this.CurrentImageIndex--;
    
    if(this.CurrentImageIndex < 0)
    {
        this.CurrentImageIndex = this.SlideshowImages.length - 1;
    }
}

Slideshow.prototype.FadeIn = function(){
    var currImg = this.ImageObject;
    this.CurrentFade++;
    this.CurrentOpacity = this.CurrentFade / this.NumOfFades; // returns something like 0.5
    setOpacity(currImg, this.CurrentOpacity);
	
	// If the image hasn't been shown entirely yet, recurse
	if(this.CurrentFade != this.NumOfFades)
	{
	    setTimeout(createObjectCallback(this, this.FadeIn, []), this.FadeTime / this.NumOfFades);
	}
	else
	{
	    // Reset values
	    this.ResetFadingValues();
	    // If the image is completely shown, set the timeout to start fading it
	    setTimeout(createObjectCallback(this, this.FadeOut, []), this.Interval);
	}
}

Slideshow.prototype.FadeOut = function(){
    var currImg = this.ImageObject;
    this.CurrentFade++;
    this.CurrentOpacity = 1 - this.CurrentFade / this.NumOfFades; // returns something like 0.5
    setOpacity(currImg, this.CurrentOpacity);
	
	// If the image hasn't been shown entirely yet, recurse
	if(this.CurrentFade != this.NumOfFades)
	{
	    setTimeout(createObjectCallback(this, this.FadeOut, []), this.FadeTime / this.NumOfFades);
	}
	else
	{
	    // If the image is completely faded, start showing the next image
	    this.NextImage();
	    this.ChangeImage();
	    // Reset values
        this.ResetFadingValues();
	    // Start immediately
	    setTimeout(createObjectCallback(this, this.FadeIn, []), 0);
	}
}

Slideshow.prototype.ResetFadingValues = function(){
    this.CurrentFade = 0;
}
