/*depedencies
    <dependencies>
        <item note = "this script utilizes the functions GetStyle, SetFilter, And Set_Filter in shared.js" domain = "sabreindustriesinc.com" name = "Shared.js">2</item>
    </dependencies>
dependencies*/

// ALWAYS PUT THE FADE OUT ELEMENT IN YOUR CODE. RELYING ON THE CODE TO CREATE IT CAN BE HAZARDOUS
// BECAUSE IE WON'T ALWAYS ALLOW CODE TO ADD AN ELEMENT TO THE BODY IF THE CODES NOT A DIRECT
// CHILD OF THE BODY ELEMENT

/* TO USE, JUST PASS THE ELEMENT THAT IS GOING TO BE FADED IN AND OUT INTO THE CONSTRUCTOR.
   INSTANCE.SPEED() GETS/SETS THE SPEED OF THE INTERVAL
   THIS IS THE SAME FOR ALL PROPERTIES.
   
   ELEMENT BEING FADED MAY NEED TO HAVE A WIDTH SPECIFIED TO WORK IN IE
   */

function Fade(ItemToFade, UseFilterIfAvailable) {

    /* private members*/
    var opaq;                               /* interval to make item fade in/out*/
    var intervalSpeed = 60;                 /* speed to fade in/out*/
    var self = this;                        /* holds this instance of fade*/
    var end = 1;                            /* the default end for opacity - Defaults to all browsers but IE*/
    var add = 0.1;                          /* the default increment rate for opacity. - Defaults to all browsers but IE*/
    var filterDuration = 0.5;               /* the default duration of the IE filter, if it is used. */

    // IE filter strings.
    var opacityFilterString = "DXImageTransform.Microsoft.Alpha";
    var randomDissolveFilterString = "DXImageTransform.Microsoft.RandomDissolve";

    /* public properties*/

    /* GETS/SETS THE SPEED OF THE INTERVAL*/
    this.Speed = function(value) { if (value == null) { return intervalSpeed; } else { value = parseInt(value); if (!isNaN(value)) intervalSpeed = value; } }
    /* GETS/SETS THE END DETERMINING WHEN THE OPACITY HAS REACHED IT'S INTENDED LIMIT.*/
    this.End = function(value) { if (value == null) { return end; } else { value = parseInt(value); if (!isNaN(value)) end = value; } }

    /* GETS/SETS THE VALUE TO ADD TO THE OPACITY EACH TIME THE INTERVAL IS EXECUTED*/
    this.Add = function(value) { if (value == null) { return add; } else { value = parseFloat(value); if (!isNaN(value)) add = value; } }

    /* GETS/SETS THE DURATION OF THE IE FILTER*/
    this.FilterDuration = function(value) { if (value == null) { return filterDuration; } else { value = parseFloat(value); if (!isNaN(value)) filterDuration = value; } }

    this.Hide = function() {

        ItemToFade.style.display = "none";
        self.setOpacity(0);

    }

    /*-------------------------------
    METHODS
    --------------------------------*/

    /* STARTS THE FADING PROCESS. TRUE MEANS FADE IN, FALSE MEANS FADE OUT.*/
    this.Start = function(bool) {

        // determine what to use, IE's random dissolve filter, or opacity based on browser.
        var useFilter = (UseFilterIfAvailable && bool && ItemToFade.filters ? true : false);

        // if using the random dissolve filter, apply it now and return.
        if (useFilter) {

            ItemToFade.style.display = "none";
            self.setOpacity(100);

            // try to set the filter.
            try { ItemToFade.filters.item(randomDissolveFilterString).duration = filterDuration; }

            // filter doesn't exist. add it.
            catch (x) {

                ItemToFade.style.filter += " progid:" + randomDissolveFilterString + "(duration=" + filterDuration.toString() + ")";
                //ItemToFade.filters.item(randomDissolveFilterString).duration = filterDuration; 

            }

            //ItemToFade.style.filter = "progid:DXImageTransform.Microsoft.RandomDissolve(duration=" + filterDuration.toString() + ")";

            Shared.SetFilter(ItemToFade, "block");
            self.Complete();
            //alert("dont");
            return;

        }

        var fadeOutTimerSpan = self.FadeOutElement();  /* ELEMENT THAT STORES THE INTERVAL SPEED TO ENSURE FADE OUT IS THE SAME RATE AS FADE IN.*/
        if (bool) { ItemToFade.style.display = "block"; fadeOutTimerSpan.innerHTML = intervalSpeed; }
        else {

            end = 0; add *= -1;
            intervalSpeed = parseInt(fadeOutTimerSpan.innerHTML);
        }

        /* IE*/
        if (ItemToFade.filters) {

            end *= 100; add *= 100;

        }

        opaq = setInterval(
            function() {
                if (Fade) { self.setOpac(bool); }
                else { clearInterval(opaq); }

            }, intervalSpeed);
    }

    // Returns the element containinng the fade speed. If it doesn't exist, one is created.
    this.FadeOutElement = function() {

        var fadeID = ItemToFade.id + "FadeOutRate";
        var fadeElement = document.getElementById(fadeID);
        if (fadeElement == null) {

            fadeElement = document.createElement("SPAN");
            fadeElement.id = fadeID;
            fadeElement.style.display = "none";
            fadeElement.innerHTML = intervalSpeed;
            document.body.appendChild(fadeElement);

        }
        return fadeElement;

    }

    this.GetElement = function () { return ItemToFade; }

    // Set by user to execute some code after an element has faded in.
    this.Complete = function() { /*place holder */ }


    /* SETS OPACITY*/
    this.setOpac = function(bool) {

        var iOpacity = self.getNumericOpacity();

        try {
            //if(ItemToFade.id == "img1_0") {alert(iOpacity);  }        
            if ((!bool && iOpacity > 0) || (bool && iOpacity < end)) {

                self.setOpacity(iOpacity + add);

            } else {

                if (!bool) { ItemToFade.style.display = "none"; }
                self.ClearIntervals();
                self.Complete();

            }

        } catch (e) { }

    }

    /* SETS THE STYLE FOR OPACITY ACCORDING TO BROWSER*/
    this.setOpacity = function(iOpacity) {

        if (ItemToFade.filters) {

            // try to set the filter.
            try { ItemToFade.filters.item(opacityFilterString).opacity = iOpacity; }

            // filter doesn't exist. add it.
            catch (x) { ItemToFade.style.filter += " progid:" + opacityFilterString; ItemToFade.filters.item(opacityFilterString).opacity = iOpacity; /*+ "(opacity=" + iOpacity.toString() + ")";*/ }
            //ItemToFade.style.filter = "alpha(opacity=" + m + ")";

        }
        else ItemToFade.style.opacity = iOpacity;

    }

    /* RETURNS THE CORRECT NUMERIC OPACITY BASED ON BROWSER*/
    this.getNumericOpacity = function() {

        var iOpacity = 0;
        try {

            /*IE*/
            if (ItemToFade.filters) { iOpacity = parseInt(ItemToFade.filters.item(opacityFilterString).opacity); /*var filter = Shared.GetStyle(ItemToFade, "filter"); iOpacity = parseInt(filter.substring(14, filter.length - 1));*/ }
            /*NON-IE*/
            else iOpacity = parseFloat(Shared.GetStyle(ItemToFade, "opacity"));

        } catch (e) { }

        return iOpacity;

    }

    /* CLEARS INTERVALS IN THIS CLASS*/
    this.ClearIntervals = function() {

        clearInterval(opaq);

    }

}
