﻿// Time (in ms) the divs should be visible
var TimeVisible = 3000;

// Time (in ms) the fading should take
var TimeToFade = 1000;

// Variable to hold the total time of the loop
var TimeLoop;

// Objects to hold the timer ID's. This is neccesary to stop them
var timer; // First run
var timerLoop; // Loop call
var timerLoop2; // timer in the loop
var timer11; // timer on first fade out
var timer12; // timer on first fade in
var timer21; // timer on second fade out
var timer22; // timer on second fade in
var timer31; // timer on third fade out
var timer32; // timer on third fade in
var manualTimer1; // timer on manual fade out
var manualTimer2; // timer on manual fade in
var timerFade1; // 1st timer in the fade function
var timerFade2; // 2nd timer in the fade function

// Object to hold the id of the element currently visible/fading out
var currentlyVisibleID;

// Objects to hold the ID's of the elements in the entire script
var elId1;
var elId2;
var elId3;

// Time (in ms) after which the entire fade should repeat itself
// This is always (3 * TimeVisible) + (3 * TimeToFade).
function GetTimeLoop(id1, id2, id3)
{
    if (id3 != null)
    {
        TimeLoop = (3 * TimeVisible) + (3 * TimeToFade);
    }
    else
    {
        TimeLoop = (2 * TimeVisible) + (2 * TimeToFade);
    }
}

// Function to setup the variables. This is called from the DebicHeaderAnimationControl usercontrol
function SetupFade(id1, id2, id3, firstTime, timeVisible)
{
    // If it's the first run, set opacity of the extra elements
    if (firstTime)
    {
        TimeVisible = timeVisible;
        GetTimeLoop(id1, id2, id3);

        var element1 = document.getElementById(id1);
        element1.FadeState = "2";

        // This has to be done to enable the script to identify these properties (otherwise they're null)
        var element2 = document.getElementById(id2);
        element2.style.opacity = "0";
        element2.FadeState = "-2";
        element2.style.filter = "alpha(opacity = 0)";

        if (id3 != null)
        {
            var element3 = document.getElementById(id3);
            element3.style.opacity = "0";
            element3.FadeState = "-2";
            element3.style.filter = "alpha(opacity = 0)";
        }

        // First run is different as the first Div is already visible
        timer = window.setTimeout("StartFade(\"" + id1 + "\", \"" + id2 + "\", \"" + id3 + "\");", 0);

        // Start the loop
        timerLoop = window.setTimeout("loop(\"" + id1 + "\", \"" + id2 + "\", \"" + id3 + "\");", 0);
    }
    else
    {
        // First run is different as the first Div is already visible
        timer = window.setTimeout("StartFade(\"" + id1 + "\", \"" + id2 + "\", \"" + id3 + "\");", TimeVisible);

        // Start the loop
        timerLoop = window.setTimeout("loop(\"" + id1 + "\", \"" + id2 + "\", \"" + id3 + "\");", TimeVisible);
    }

    // Link the local ID's to global objects
    elId1 = id1;
    elId2 = id2;
    elId3 = id3;

    // Link the currently visible elementID to the global object
    currentlyVisibleID = id1;
}

// Function for the buttonclicks
function ManualFade(id)
{
    // Stop the timeouts
    ClearTimeOuts();

    // Place the element ID's in an array to change the show order
    var fadeContentBlocks = new Array(elId1, elId2, elId3);

    // Check which element the new element is and set the place of the element in the array to the variable.
    var currentElementPlace = 0;
    if (id == elId1)
    {
        currentElementPlace = 0;
    }
    else if (id == elId2)
    {
        currentElementPlace = 1;
    }
    else if (id == elId3)
    {
        currentElementPlace = 2;
    }

    // Setup the fade with the new show order
    if (id != currentlyVisibleID)
    {
        // Set the currentlyVisibleID to the new element id
        currentlyVisibleID = id;

        // To prevent the element from disappearing when the autofade is in progress
        if (document.getElementById(id).FadeState != 1)
        {
            // Start the fade of the new element
            manualTimer2 = window.setTimeout("fade(\"" + id + "\")", 0);

            // Fade out the not selected and restart the fade cycle with the new order
            switch (currentElementPlace)
            {
                case 0:
                    FadeOutOthers(elId2, elId3);
                    SetupFade(fadeContentBlocks[0], fadeContentBlocks[1], fadeContentBlocks[2], false, TimeVisible);
                    break;
                case 1:
                    FadeOutOthers(elId1, elId3);
                    SetupFade(fadeContentBlocks[1], fadeContentBlocks[2], fadeContentBlocks[0], false, TimeVisible);
                    break;
                case 2:
                    FadeOutOthers(elId1, elId2);
                    SetupFade(fadeContentBlocks[2], fadeContentBlocks[0], fadeContentBlocks[1], false, TimeVisible);
                    break;
                default:
                    break;
            }
        }
    }
    else
    {
        // If the element is not already visible (2) or fading to visible (1) start the fade. This is to ensure the 
        // selected item doesn't stop mid-fade or disappears.
        if (document.getElementById(id).FadeState != "2" && document.getElementById(id).FadeState != "1")
        {
            manualTimer2 = window.setTimeout("fade(\"" + id + "\")", 0);
        }

        // Restart the fade cycle with the new order
        switch (currentElementPlace)
        {
            case 0:
                SetupFade(fadeContentBlocks[0], fadeContentBlocks[1], fadeContentBlocks[2], false, TimeVisible);
                break;
            case 1:
                SetupFade(fadeContentBlocks[1], fadeContentBlocks[2], fadeContentBlocks[0], false, TimeVisible);
                break;
            case 2:
                SetupFade(fadeContentBlocks[2], fadeContentBlocks[0], fadeContentBlocks[1], false, TimeVisible);
                break;
            default:
                break;
        }
    }
}

// Function to fade out the elements not selected 
function FadeOutOthers(id1, id2)
{
    if (document.getElementById(id1).FadeState != null)
    {
        // Only fade when not already faded out (-2) or fading out (-1)
        if (document.getElementById(id1).FadeState != "-2" && document.getElementById(id1).FadeState != "-1")
        {
            window.setTimeout("fade(\"" + id1 + "\")", 0);
        }
    }

    if (document.getElementById(id2) != null && document.getElementById(id2).FadeState != null)
    {
        // Only fade when not already faded out (-2) or fading out (-1)
        if (document.getElementById(id2).FadeState != "-2" && document.getElementById(id2).FadeState != "-1")
        {
            window.setTimeout("fade(\"" + id2 + "\")", 0);
        }
    }
}

// Function to stop all timers in the script
function ClearTimeOuts()
{
    clearTimeout(timer);
    clearTimeout(timerLoop);
    clearTimeout(timer11);
    clearTimeout(timer12);
    clearTimeout(timer21);
    clearTimeout(timer22);
    clearTimeout(timer31);
    clearTimeout(timer32);
    clearTimeout(manualTimer1);
    clearTimeout(manualTimer2);
    clearTimeout(timerLoop2);
}

// Function that regulates the fades
// examples behind timeVisibleVar are made with the following settings:
// TimeVisible = 3000
// TimeToFade = 1000
// TimeLoop = 12000
function StartFade(id1, id2, id3)
{
    // Fade out first div and fade in second div
    var timeVisibleVar = TimeVisible; // 3000
    timer11 = window.setTimeout("fade(\"" + id1 + "\")", timeVisibleVar);
    timer12 = window.setTimeout("fade(\"" + id2 + "\")", timeVisibleVar);

    // Fade out the second div and fade in the third
    timeVisibleVar += TimeVisible + TimeToFade; // 7000
    timer21 = window.setTimeout("fade(\"" + id2 + "\")", timeVisibleVar);

    if (id3 != "null")
    {
        timer22 = window.setTimeout("fade(\"" + id3 + "\")", timeVisibleVar);

        // Fade out the third div and fade in the first
        timeVisibleVar += TimeVisible + TimeToFade; // 11000
        timer31 = window.setTimeout("fade(\"" + id3 + "\")", timeVisibleVar);
        timer32 = window.setTimeout("fade(\"" + id1 + "\")", timeVisibleVar);
    }
    else
    {
        timer22 = window.setTimeout("fade(\"" + id1 + "\")", timeVisibleVar);
    }
}

// Function that loops the StartFade function.
// setInterval keeps running until programmatically stopped > this keeps the loop running.
function loop(id1, id2, id3)
{
    timerLoop2 = window.setInterval("StartFade(\"" + id1 + "\", \"" + id2 + "\", \"" + id3 + "\");", TimeLoop);
}

// Function to set the fade state and keep track of it
// States:
// 2 > Visible
// -2 > not Visible
// -1, 1 > Changing
function fade(eid)
{
    // Resolve element id to object
    var element = document.getElementById(eid);

    // Stop if element doesn't exists
    if (element == null)
    {
        return;
    }

    // If fade state doesn't exist, try to get it from css
    if (element.FadeState == null)
    {
        if (element.style.opacity == null || element.style.opacity == '' || element.style.opacity == '1')
        {
            element.FadeState = 2;
        }
        else
        {
            element.FadeState = -2;
        }
    }

    // if: Flip direction.
    // else: Change state
    if (element.FadeState == 1 || element.FadeState == -1)
    {
        element.FadeState = element.FadeState == 1 ? -1 : 1;
        element.FadeTimeLeft = TimeToFade - element.FadeTimeLeft;
    }
    else
    {
        element.FadeState = element.FadeState == 2 ? -1 : 1;
        element.FadeTimeLeft = TimeToFade;
        timerFade1 = setTimeout("animateFade(" + new Date().getTime() + ",'" + eid + "')", 33);
    }

    if (element.FadeState == 2)
    {
        // Set the currentlyVisibleID to the new element id
        currentlyVisibleID = id;
    }
}

// Function that performs the actual fade
function animateFade(lastTick, eid)
{
    // First check the time that has passed since the last animation
    var curTick = new Date().getTime();
    var elapsedTicks = curTick - lastTick;

    var element = document.getElementById(eid);

    // if fadetime left is passed by time, then set animation to endstate (completely transparent or visible) and stop the function
    if (element.FadeTimeLeft <= elapsedTicks)
    {
        element.style.opacity = element.FadeState == 1 ? '1' : '0';
        element.style.filter = 'alpha(opacity = ' + (element.FadeState == 1 ? '100' : '0') + ')';
        element.FadeState = element.FadeState == 1 ? 2 : -2;

        // Change display style to hide the layers with opacity 0 (the fadestate of those layers is 2).
        if (element.FadeState == -2)
        {
            element.style.display = "none";
        }
        else
        {
            element.style.display = "block";
        }

        return;
    }
    else
    {
        // All other cases, display style should be "block" to show the items during fading
        element.style.display = "block";
    }

    // Use the time to check the percentage of fading that should be set at the current time.
    // This is done by dividing the time left with the fade time
    // when fading out, this will generate the percentage needed.
    // When fading in, this has to be substracted from 1 to get the correct percentage.
    element.FadeTimeLeft -= elapsedTicks;
    var newOpVal = element.FadeTimeLeft / TimeToFade;

    if (element.FadeState == 1)
    {
        newOpVal = 1 - newOpVal;
    }

    element.style.opacity = newOpVal;
    element.style.filter = 'alpha(opacity = ' + (newOpVal * 100) + ')';

    timerFade2 = setTimeout("animateFade(" + curTick + ",'" + eid + "')", 33);
}
