﻿
function ElementFader(Element, FadePeriod)
{
    // default values
    this.FadePeriod = 500; // half a second

    // private members
    this.Element = null;
    this.FadeThread = null;
    this.MinStepSize = 0.01;
    this.MinInterval = 10;

    this.constructor = function(Element, FadePeriod)
    {
        this.Element = Element;

        if (FadePeriod != undefined)
        {
            this.FadePeriod = FadePeriod;
        }
    };

    this.FadeOut = function(FadePeriod)
    {
        if (FadePeriod == undefined)
        {
            FadePeriod = this.FadePeriod;
        }
        this.CancelFadeThread();
        var _this = this;
        var StepSize = this.MinStepSize;
        var Interval = FadePeriod * StepSize;
        if (Interval < this.MinInterval)
        {
            Interval = this.MinInterval;
            StepSize = Interval / FadePeriod;
        }
        this.FadeOutStep(StepSize);
        this.FadeThread = setInterval(function() { _this.FadeOutStep(StepSize); }, Interval);
    };

    this.FadeIn = function(FadePeriod)
    {
        if (FadePeriod == undefined)
        {
            FadePeriod = this.FadePeriod;
        }
        this.CancelFadeThread();
        var _this = this;
        var StepSize = this.MinStepSize;
        var Interval = FadePeriod * StepSize;
        if (Interval < this.MinInterval)
        {
            Interval = this.MinInterval;
            StepSize = Interval / FadePeriod;
        }
        this.FadeInStep(StepSize);
        this.FadeThread = setInterval(function() { _this.FadeInStep(StepSize); }, Interval);
    };

    this.Show = function()
    {
        this.Element.style.visibility = 'visible';
        this.SetOpacity(1.0);
    }

    this.Hide = function()
    {
        this.Element.style.visibility = 'hidden';
        this.SetOpacity(0.0);
    }

    this.GetOpacity = function()
    {
        return parseFloat(this.Element.style.opacity);
    }

    this.SetElementOpacityRecursively = function(Element, Opacity)
    {
        this.SetElementOpacity(Element, Opacity);

        for (var i = 0; i < Element.childNodes.length; i++)
        {
            this.SetElementOpacityRecursively(Element.childNodes[i], Opacity);
        }
    };

    this.SetElementOpacity = function(Element, Opacity)
    {
        if (Element.style)
        {
            Element.style.opacity = Opacity;
            Element.style.MozOpacity = Opacity;
            Element.style.KhtmlOpacity = Opacity;
            Element.style.filter = "alpha(opacity=" + Math.round(Opacity * 100) + ")";
        }
    };

    this.SetOpacity = function(Opacity)
    {
        if (navigator.userAgent.toLowerCase().indexOf('msie') != -1)
        {
            this.SetElementOpacityRecursively(this.Element, Opacity);
        }
        else
        {
            this.SetElementOpacity(this.Element, Opacity);
        }
    }

    this.AlterOpacity = function(Opacity)
    {
        this.SetOpacity(this.GetOpacity() + Opacity);
    }

    this.FadeOutStep = function(StepSize)
    {
        if (this.GetOpacity() > 0.0)
        {
            this.AlterOpacity(-StepSize);
        }
        else
        {
            this.Element.style.visibility = 'hidden';
            this.CancelFadeThread();
        }
    };

    this.FadeInStep = function(StepSize)
    {
        if (this.GetOpacity() < 1.0)
        {
            this.Element.style.visibility = 'visible';
            this.AlterOpacity(StepSize);
        }
        else
        {
            this.CancelFadeThread();
        }
    };

    this.CancelFadeThread = function()
    {
        if (this.FadeThread != null)
        {
            clearInterval(this.FadeThread);
            this.FadeThread = null;
        }
    };

    this.constructor(Element, FadePeriod);
};
