
var MultiBlockFaderData = new Object;
MultiBlockFaderData.eBlockArray = new Array();
MultiBlockFaderData.eFadingIn = new Array();
MultiBlockFaderData.eFadingOut = new Array();
MultiBlockFaderData.ePause = new Array();
MultiBlockFaderData.eContinue = new Array();
MultiBlockFaderData.tmTimeout = new Array();
MultiBlockFaderData.tmFadeTimeout = new Array();
MultiBlockFaderData.iCurrentIdx = new Array();

function MBF__findAbolutePos(obj) {
    var curleft = curtop = 0;
    if (obj.offsetParent) {
        do {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
            // code below combines assignment with test on whether
            // parent available
        } while (obj = obj.offsetParent);
    }
    return [curleft, curtop];
}

function MBF__AddToOnLoad(f) {
    var currOnLoad = window.onload;

    if (typeof currOnLoad == 'function') {
        window.onload =
            function() {
                if (currOnLoad) {
                    currOnLoad();
                }
                f();
            }
    }
    else {
        window.onload = f;
    }
}

function MBF__SetOpacity(elem, opacityAsInt) {
    var opacityAsDecimal = opacityAsInt;

    if (opacityAsInt > 100)
        opacityAsInt = opacityAsDecimal = 100;
    else if (opacityAsInt < 0)
        opacityAsInt = opacityAsDecimal = 0;

    opacityAsDecimal /= 100;
    if (opacityAsInt < 1)
        opacityAsInt = 1; // IE7 bug, text smoothing cuts out if 0

    elem.style.opacity = (opacityAsDecimal);

    // for ie
    elem.style.filter = "alpha(opacity=" + opacityAsInt + ")";
    elem.style.zoom = 1;
}

function MBF__WrapUpFade(iDataIdx) {
    if (MultiBlockFaderData.tmFadeTimeout[iDataIdx]) {
        clearTimeout(MultiBlockFaderData.tmFadeTimeout[iDataIdx]);
    }

    var eFadingIn = MultiBlockFaderData.eFadingIn[iDataIdx];
    var eFadingOut = MultiBlockFaderData.eFadingOut[iDataIdx];

    eFadingOut.style.visibility = 'hidden';

    // Make visible after you've made hidden, in case eFadingIn and eFadingOut 
    // are the same.
    
    // Make eFadingIn completely visible.
    eFadingIn.style.visibility = 'visible';
    
    // Remove any FireFox fading
    eFadingIn.style.opacity = 100;

    // Remove IE fading, by removing the IE filter. 
    // The filter causes text to look
    // crappy - ok during the fade, but not while the text
    // is stable.

    if (eFadingIn.style.removeAttribute) {
            eFadingIn.style.removeAttribute('filter');
    }
}

function MBF__Fade(iDataIdx, fromOpacity, toOpacity, time, fps) {
    var steps = Math.ceil(fps * (time / 1000));
    var delta = (toOpacity - fromOpacity) / steps;

    MBF__FadeStep(iDataIdx, 0, steps, fromOpacity, delta, (time / steps));
}

function MBF__FadeStep(
    iDataIdx, stepNum, steps, fromOpacity, delta, timePerStep) {

    var eFadingIn = MultiBlockFaderData.eFadingIn[iDataIdx];
    var eFadingOut = MultiBlockFaderData.eFadingOut[iDataIdx];

    MBF__SetOpacity(
        eFadingOut,
        Math.round(parseInt(fromOpacity) + (delta * (steps - stepNum))));

    MBF__SetOpacity(
        eFadingIn,
        Math.round(parseInt(fromOpacity) + (delta * stepNum)));

    eFadingIn.style.visibility = 'visible';

    if (stepNum < steps) {
        eFadingOut.style.visibility = 'visible';
        MultiBlockFaderData.tmFadeTimeout[iDataIdx] = 
            setTimeout(
                "MBF__FadeStep(" +
                iDataIdx + ", " +
                (stepNum + 1) + ", " +
                steps + ", " +
                fromOpacity + ", " +
                delta + ", " +
                timePerStep + ");", timePerStep);
    }
    else {
        MBF__WrapUpFade(iDataIdx);
    }
}

function MBF__InternalMoveToNextBlock(bPrevious, iDataIdx) {
    var eBlockArray = MultiBlockFaderData.eBlockArray[iDataIdx];
    var earrBlocks = eBlockArray.getElementsByTagName("div");

    var eVisibleFound = false;
    var eNextFound = false;

    var iEnd = earrBlocks.length;
    var iIncrement = 1;
    var iLoopAround = 0;
    if (bPrevious) {
        iEnd = -1;
        iIncrement = -1;
        iLoopAround = earrBlocks.length - 1;
    }

    // ----

    var iIdxVisible = MultiBlockFaderData.iCurrentIdx[iDataIdx];
    var e = earrBlocks.item(iIdxVisible);
    MultiBlockFaderData.eFadingOut[iDataIdx] = e;

    // ----

    var i = iIdxVisible + iIncrement;

    while (true) {
        if (i == iEnd) {
            i = iLoopAround;
        }

        // If you loop back onto the now visible list element,
        // there is only one list element! In that case, get out now.
        if (i == iIdxVisible) {
            return;
        }

        var e = earrBlocks.item(i)
        if (e.className.match(/\bMultiBlockFaderListElement\b/)) {
            MultiBlockFaderData.eFadingIn[iDataIdx] = e;
            MultiBlockFaderData.iCurrentIdx[iDataIdx] = i;
            return;
        }

        i += iIncrement;
    }
}

function MBF__JumpToNextBlock(
            bContinueTimer,
            bPrevious,
            iDataIdx,
            timeBetweenFades,
            timeFade, 
            fpsFade) {

   clearTimeout(MultiBlockFaderData.tmTimeout[iDataIdx]);

    // Wrap up any current fade
    MBF__WrapUpFade(iDataIdx);

    // MBF__InternalMoveToNextBlock moves to the next item in the internal
    // data structure, and MBF__WrapUpFade translates that to the HTML DOM.
    MBF__InternalMoveToNextBlock(bPrevious, iDataIdx);
    MBF__WrapUpFade(iDataIdx);

    if (bContinueTimer) {

        var strCall =
            "MBF__FadeToNextBlock(false," +
            iDataIdx + "," +
            timeBetweenFades + "," +
            timeFade + "," +
            fpsFade + ");";
        
        MultiBlockFaderData.tmTimeout[iDataIdx] =
            setTimeout(
                strCall, 
                parseInt(timeBetweenFades, 10) + parseInt(timeFade, 10));
    }
}

function MBF__FadeToNextBlock(bPrevious, iDataIdx, timeBetweenFades, timeFade, fpsFade) {

    MBF__InternalMoveToNextBlock(bPrevious, iDataIdx);
    
    MBF__Fade(iDataIdx, 1, 100, timeFade, fpsFade);

    var strCall =
        "MBF__FadeToNextBlock(false," +
        iDataIdx + "," +
        timeBetweenFades + "," +
        timeFade + "," +
        fpsFade + ");"; 

    MultiBlockFaderData.tmTimeout[iDataIdx] = 
        setTimeout(
            strCall, 
            parseInt(timeBetweenFades, 10) + parseInt(timeFade, 10));
}

function MBF__ManualMove(bPrevious, iDataIdx, timeBetweenFades, timeFade, fpsFade) {
    var eFadingIn = MultiBlockFaderData.eFadingIn[iDataIdx];
    var eFadingOut = MultiBlockFaderData.eFadingOut[iDataIdx];

    var ePause = MultiBlockFaderData.ePause[iDataIdx];
    var bPauseAvail = (ePause != null);

    MBF__JumpToNextBlock(
        !bPauseAvail,
        bPrevious,
        iDataIdx,
        timeBetweenFades,
        timeFade, 
        fpsFade);

    // If visitor clicks Next or Prev, they probably
    // want to go through animation at their own pace.
    // So pause the automatic progression.

    if (bPauseAvail) {
        ePause.onclick();
    }
}

function setNavElment(
    e, 
    iDataIdx, 
    timeBetweenFades, 
    timeFade, 
    fpsFade)
{
    var strClass = e.className;

    if (strClass.match(/\bMultiBlockFaderPause\b/)) {
        MultiBlockFaderData.ePause[iDataIdx] = e;
        e.style.display = 'inline';

        e.onclick = function() {
            if (MultiBlockFaderData.tmTimeout[iDataIdx] != null) {
                clearTimeout(MultiBlockFaderData.tmTimeout[iDataIdx]);
            }

            // If a fade is happening now, wrap it up now.
            MBF__WrapUpFade(iDataIdx);

            var ePause = MultiBlockFaderData.ePause[iDataIdx];
            if (ePause != null) {
                ePause.style.display = 'none';
            }

            var eContinue = MultiBlockFaderData.eContinue[iDataIdx];
            if (eContinue != null) {
                eContinue.style.display = 'inline';
            }

            return (false);
        }
    }

    // -----

    if (strClass.match(/\bMultiBlockFaderContinue\b/)) {
        MultiBlockFaderData.eContinue[iDataIdx] = e;
        e.style.display = 'none';

        e.onclick = function() {
            MBF__JumpToNextBlock(
                true, 
                false,
                iDataIdx,
                timeBetweenFades,
                timeFade,
                fpsFade);

           // e.style.display = 'none';
            var eContinue = MultiBlockFaderData.eContinue[iDataIdx];
            if (eContinue != null) {
                eContinue.style.display = 'none';
            }

            var ePause = MultiBlockFaderData.ePause[iDataIdx];
            if (ePause != null) {
                ePause.style.display = 'inline';
            }

            return (false);
        }

    }

    // -----

    if (strClass.match(/\bMultiBlockFaderNext\b/)) {
        e.onclick = function() {
            MBF__ManualMove(false, iDataIdx, timeBetweenFades, timeFade, fpsFade);
        }
    }

    // -----

    if (strClass.match(/\bMultiBlockFaderPrevious\b/)) {
        e.onclick = function() {
            MBF__ManualMove(true, iDataIdx, timeBetweenFades, timeFade, fpsFade);
        }
    }
}

function MBF__StartSingleArray(iDataIdx, timeBetweenFades, timeFade, fpsFade) {
    var eBlockArray = MultiBlockFaderData.eBlockArray[iDataIdx];
    var earrBlocks = eBlockArray.getElementsByTagName("div");

    var i = 0;
    var bFound = false;

    for (i = 0; i < earrBlocks.length; i++) {
        var e = earrBlocks.item(i);
        var strClass = e.className;

        if (strClass.match(/\bMultiBlockFaderListElement\b/)) {
            var absPos = MBF__findAbolutePos(e);
            var absPos0;
            var e0;
            if (!bFound) {
                absPos0 = absPos;
                e0 = e;
                e.style.visibility = 'visible';
                bFound = true;
                MultiBlockFaderData.iCurrentIdx[iDataIdx] = i;
            }
            else {
                e.style.position = 'absolute';
                e.style.top = absPos0[1] + 'px';
                e.style.visibility = 'hidden';

                if (e.offsetHeight > e0.offsetHeight) {
                    e0.style.height = e.offsetHeight + "px";
                }

                MBF__SetOpacity(e, 0);
            }

            e.style.display = 'block';
        }
    }
    
    earrBlocks = eBlockArray.getElementsByTagName("input");

    for (i = 0; i < earrBlocks.length; i++) {
        var e = earrBlocks.item(i);

        if (e.type == 'button')
        {
            setNavElment(
                e,
                iDataIdx,
                timeBetweenFades,
                timeFade,
                fpsFade);
        }
    }

    earrBlocks = eBlockArray.getElementsByTagName("a");

    for (i = 0; i < earrBlocks.length; i++) {
        var e = earrBlocks.item(i);

        setNavElment(
            e,
            iDataIdx,
            timeBetweenFades,
            timeFade,
            fpsFade);
    }

    MultiBlockFaderData.tmTimeout[iDataIdx] = setTimeout(
        "MBF__FadeToNextBlock(false," +
        iDataIdx + "," +
        timeBetweenFades + "," +
        timeFade + "," +
        fpsFade + ");", timeBetweenFades);
}

function MBF__FindAndStartFaderArrays() {
    var earrAllDivs = document.getElementsByTagName("div");
    var iDataIdx = 0;

    var i = 0;

    for (i = 0; i < earrAllDivs.length; i++) {
        var e = earrAllDivs.item(i)
        var strClass = e.className;
        var p = /\bMultiBlockFaderList\((\d+),(\d+),(\d+)\)/ ;
        var m = strClass.match(p);
        
        if (m) {
            var timeBetweenFades = m[1];
            var timeFade = m[2];
            var fpsFade = m[3];

            MultiBlockFaderData.eBlockArray[iDataIdx] = e;
            MBF__StartSingleArray(iDataIdx, timeBetweenFades, timeFade, fpsFade);

            iDataIdx += 1;
        }
    }
}

function MBF__Init() {
    MBF__FindAndStartFaderArrays();
}

// -------
// start fader

// Will not work if the body tag on the page has an onload.
// In that case, include a JavaScript block at the end of the page
// that calls the MBF__Init function.
MBF__AddToOnLoad(MBF__Init);



