﻿/*
    v1.0 - Crossfades various values.
*/

ContainerFader = function() {
    this.Containers = {};
    this.Fades = [];
    this.CurrentFadeItem = 0;
    this.ActiveChild = 0;
    this.LastActiveChild = 0;
    this.BeforeFadeCallback = null;
    this.AnimationDelay = 0;
    this.InitialAnimationDelay = 0;
    this.AnimationInterval = null;
    this.PendingAnimations = 0;
}

ContainerFader.prototype = {
    // ######################
    // ## Configuration
    // ## [MB]
    // ######################

    // Register containers for later usage.
    // [MB]
    RegisterContainer: function(name, containerId, fadeInitials, width, centerContent) {
        containerFader.Containers[name] = jqnc("#" + containerId).get(0);

        if (containerFader.Containers[name]) {
            // Verifying the container position.
            // [MB]
            if (containerFader.Containers[name].style.position != "relative") {
                alert("Containers must be relative.");
            }

            // Creating two new inner items
            // [MB]
            var newFirstChild = document.createElement("div");
            var newSecondChild = document.createElement("div");

            // Making the inner items absolute for cross-fading.
            // [MB]
            newFirstChild.style.position = "absolute";
            newSecondChild.style.position = "absolute";
            jqnc(newSecondChild).css("opacity", "0");

            if (width) {
                newFirstChild.style.width = width;
                newSecondChild.style.width = width;
            }

            // Adding the initial value.
            // [MB]
            newFirstChild.innerHTML = fadeInitials.newContent;

            // Adding initial value for looping.
            // [MB]
            if (!containerFader.Fades[0])
                containerFader.Fades[0] = {};

            containerFader.Fades[0][name] = fadeInitials;
            containerFader.CurrentFadeItem = 1;

            // Adding the inner items.
            // [MB]
            containerFader.Containers[name].appendChild(newFirstChild);
            containerFader.Containers[name].appendChild(newSecondChild);

            if (centerContent) {
                containerFader.Containers[name].CenterContent = centerContent;

                newFirstChild.style.top = (containerFader.Containers[name].offsetHeight / 2) - (newFirstChild.offsetHeight / 2) + "px";
            }
        }
    },

    // Adds a new fade-details-set to the animation queue.
    // [MB]
    AddNewFade: function(fadeDetails, overrideAnimationInterval) {
        if (fadeDetails) {
            var newFadeIdx = containerFader.Fades.length;
            containerFader.Fades[newFadeIdx] = fadeDetails;

            if (overrideAnimationInterval) {
                containerFader.Fades[newFadeIdx].OverrideAnimationInterval = overrideAnimationInterval;
            }
        }
    },

    // Setting interval for fading the containers.
    // [MB]
    StartAnimation: function(animationDelay, beforeFadeCallback) {
        if (animationDelay) {
            containerFader.InitialAnimationDelay = animationDelay;
            containerFader.AnimationDelay = animationDelay;
            containerFader.InitializeAnimationInterval();

            containerFader.BeforeFadeCallback = beforeFadeCallback;
        }
    },

    GoToFade: function(overrideCurrentFadeItem) {
        if (containerFader.AnimationInterval) {
            window.clearInterval(containerFader.AnimationInterval);

            containerFader.CurrentFadeItem = overrideCurrentFadeItem;
            containerFader.RunAnimation();
            containerFader.InitializeAnimationInterval();
        }
    },

    InitializeAnimationInterval: function() {
        if (containerFader.AnimationInterval) {
            window.clearInterval(containerFader.AnimationInterval);
        }

        containerFader.AnimationInterval = window.setInterval("containerFader.RunAnimation()", containerFader.AnimationDelay);
    },



    // ######################
    // ## Animation itself
    // ## [MB]
    // ######################
    RunAnimation: function() {
        if (containerFader.Fades[containerFader.CurrentFadeItem]) {
            // Checking for callback.
            // [MB]
            if (containerFader.BeforeFadeCallback)
                eval("containerFader.BeforeFadeCallback(" + containerFader.CurrentFadeItem + ", " + containerFader.LastActiveChild + ")");

            var cFade = containerFader.Fades[containerFader.CurrentFadeItem];

            // Replacing the content of each container.
            // [MB]
            for (var containerName in cFade) {
                containerFader.PendingAnimations++;
                window.setTimeout("containerFader.Animate(" + (containerFader.ActiveChild == 0) + ", '" + containerName + "');", (cFade[containerName]) ? cFade[containerName].fadeDelay : 0);
            }
        }
    },

    Animate: function(isEvenRun, containerName) {
        var fadeContainer = containerFader.Containers[containerName];

        if (fadeContainer) {
            var cFade = containerFader.Fades[containerFader.CurrentFadeItem];
            var firstChild = fadeContainer.childNodes[0];
            var secondChild = fadeContainer.childNodes[1];

            if (isEvenRun) {
                secondChild.innerHTML = cFade[containerName].newContent;

                if (fadeContainer.CenterContent)
                    secondChild.style.top = (fadeContainer.offsetHeight / 2) - (secondChild.offsetHeight / 2) + "px";

                jqnc(firstChild).animate({ "opacity": "0" }, cFade[containerName].fadeDuration);
                jqnc(secondChild).animate({ "opacity": "1" }, cFade[containerName].fadeDuration);
            }
            else {
                firstChild.innerHTML = cFade[containerName].newContent;

                if (fadeContainer.CenterContent)
                    firstChild.style.top = (fadeContainer.offsetHeight / 2) - (firstChild.offsetHeight / 2) + "px";

                jqnc(firstChild).animate({ "opacity": "1" }, cFade[containerName].fadeDuration);
                jqnc(secondChild).animate({ "opacity": "0" }, cFade[containerName].fadeDuration);
            }
        }

        containerFader.PendingAnimations--;
        containerFader.FinishAnimation();
    },

    FinishAnimation: function() {
        if (containerFader.PendingAnimations == 0) {
            var cFade = containerFader.Fades[containerFader.CurrentFadeItem];
            containerFader.AnimationDelay = (cFade.OverrideAnimationInterval) ? cFade.OverrideAnimationInterval : containerFader.InitialAnimationDelay;
            containerFader.InitializeAnimationInterval();

            // Toggle next container.
            // [MB]
            containerFader.ActiveChild = (containerFader.ActiveChild == 0) ? 1 : 0;

            containerFader.LastActiveChild = containerFader.CurrentFadeItem;
            containerFader.CurrentFadeItem++;
            if (containerFader.CurrentFadeItem >= containerFader.Fades.length) {
                containerFader.CurrentFadeItem = 0;
            }
        }
    }
}

var containerFader = new ContainerFader();