﻿// IFR - inline flash replacement (modifies text with flash equivalents)
// Modified from sIFR v2.0 RC4 SOURCE to use css properties and work with prototype/behaviour
// Copyright 2007 Brian R. Miedlar
// PreReq: flash.js must be loaded before page load

var Script_Name = 'ifr.js';
var Ifr = Class.create();

Ifr.prototype = {
    'initialize': function() {
        this.isLoaded = true;
        this.isSupported = false;
        this.fixFragIdBug = false;

        //Check flash support
        this.hasFlash = swfobject.hasPlayerVersion('6');

        //Get user agent 
        this.userAgent = swfobject.getUserAgent;

        /*	Disable sIFR for non-Flash or old browsers
        Also disable it for IE and KHTML browsers in XML mode, since we are using innerHTML for those browsers */
        if (!this.hasFlash || !document.createElement || !document.getElementById) return;
        this.isSupported = true;
    },
    'apply': function(selector, options, isForced) {
        //var options = Object.extend({}, options);
        this.isLoaded = true;
        $$(selector).each(function(element) {
            if (isForced) {
                if (Element.hasClassName(element, 'sIFR-replaced')) {
                    var bAlternateExists = false;
                    $$('sIfr-alternate').each(function(alternate) {
                        bAlternateExists = true;
                    });
                    if (!bAlternateExists) Element.removeClassName(element, 'sIFR-replaced');
                }
            }
            if (element.offsetWidth == 0) return;
            this.replaceElement(element, options);
        } .bind(this));
    },
    'replaceElement': function(element, options) {
        var options = Object.extend({}, options);

        if (Element.hasClassName(element, 'sIFR-replaced')) return;

        //Get the arguments from the Css
        //var sFlashSrc = Element.getStyle(element, 'font-flash-file');
        if (!options.src) return;
        sFlashSrc = options.src;
        var sLinkColor = '#000000';
        if (options.linkColor) sLinkColor = options.linkColor;
        var sHoverColor = '#000000';
        if (options.hoverColor) sHoverColor = options.hoverColor;
        var pFlashVars = {};
        if (options.extraVars) pFlashVars = options.extraVars;
        var sWmode = 'opaque';
        if (options.wmode) sWmode = options.wmode;
        var bSelectable = 'false';
        if (options.isSelectable) bSelectable = options.isSelectable;

        //The rest is from the element style        
        var sColorCss = Element.getStyle(element, 'color');
        var oColor = new Color(sColorCss);
        var sColor = '#000000';
        if (oColor.isValid) sColor = oColor.toHex();
        var sBgColor = Element.getStyle(element, 'background-color');
        var nPaddingTop = parseInt(Element.getStyle(element, 'padding-top')) || 0;
        var nPaddingRight = parseInt(Element.getStyle(element, 'padding-right')) || 0;
        var nPaddingBottom = parseInt(Element.getStyle(element, 'padding-bottom')) || 0;
        var nPaddingLeft = parseInt(Element.getStyle(element, 'padding-left')) || 0;
        var sCase = Element.getStyle(element, 'text-transform');

        //Set Flash vars
        Object.extend(pFlashVars, { isSelectable: bSelectable });
        if (sColor) Object.extend(pFlashVars, { textcolor: sColor });
        if (sLinkColor) Object.extend(pFlashVars, { linkcolor: sLinkColor });
        if (sHoverColor) Object.extend(pFlashVars, { hovercolor: sHoverColor });
        if (nPaddingTop) nPaddingTop = 0;
        if (nPaddingRight) nPaddingRight = 0;
        if (nPaddingBottom) nPaddingBottom = 0;
        if (nPaddingLeft) nPaddingLeft = 0;
        if (sBgColor) sBgColor = "#ffffff";
        if (sWmode == "transparent") {
            //            if (!this.userAgent.bHasTransparencySupport) {
            //                sWmode = "opaque";
            //            } else {
            //                sBgColor = "transparent";
            //            };
        };
        if (!sWmode) sWmode = "";

        //Get size on screen
        var iWidth = element.offsetWidth - nPaddingLeft - nPaddingRight;
        var iHeight = element.offsetHeight - nPaddingTop - nPaddingBottom;

        //Create an alternate text containing the original
        var eAlternate = document.createElement('SPAN');
        Element.addClassName(eAlternate, 'sIFR-alternate');

        //Build the content
        var oContent = this.fetchContent(element, eAlternate, sCase);
        pFlashVars = Object.extend(pFlashVars, {
            txt: Ifr.EscapeHex(this.userAgent, oContent.sContent).replace(/\+/g, "%2B").replace(/&/g, "%26").replace(/\"/g, "%22").strip(),
            w: iWidth,
            h: iHeight
        });
        //if(element.onclick) alert(eval(eval(eval(element.onclick))));
        //if(element.onclick) sFlashVars += '&onclick=' + Ifr.EscapeHex(this.userAgent, element.onclick.toString()).replace(/\+/g, "%2B").replace(/&/g, "%26").replace(/\"/g, "%22").strip()
        Element.removeChildren(element);
        element.appendChild(eAlternate);

        swfobject.embedSWF(sFlashSrc, Element.identify(element), iWidth, iHeight, '6', 'flash/expressInstall.swf', pFlashVars, { wmode: sWmode }, null);
        Element.addClassName(element, 'sIFR-replaced');
    },
    'fetchContent': function(node, nodeNew, sCase, nLinkCount, sLinkVars) {
        var sContent = "";
        var oSearch = node.firstChild;
        var oRemove, nodeRemoved, oResult, sValue;

        if (nLinkCount == null) { nLinkCount = 0 };
        if (sLinkVars == null) { sLinkVars = "" };

        while (oSearch) {
            if (oSearch == nodeNew) {
                oSearch = oSearch.nextSibling;
                continue;
            }
            if (oSearch.nodeType == 3) {
                sValue = oSearch.nodeValue.replace("<", "&lt;");
                switch (sCase) {
                    case "lowercase":
                        sContent += sValue.toLowerCase();
                        break;
                    case "uppercase":
                        sContent += sValue.toUpperCase();
                        break;
                    default:
                        sContent += sValue;
                };
            } else if (oSearch.nodeType == 1) {
                if (oSearch.nodeName.toLowerCase() == "a" && !oSearch.getAttribute("href") == false) {
                    if (oSearch.getAttribute("target")) {
                        sLinkVars += "&sifr_url_" + nLinkCount + "_target=" + oSearch.getAttribute("target");
                    };
                    sLinkVars += "&sifr_url_" + nLinkCount + "=" + Ifr.EscapeHex(oSearch.getAttribute("href")).replace(/&/g, "%26");
                    sContent += '<a href="asfunction:_root.launchURL,' + nLinkCount + '">';
                    nLinkCount++;
                } else if (oSearch.nodeName.toLowerCase() == "br") {
                    sContent += "<br/>";
                };
                if (oSearch.hasChildNodes()) {
                    /*	The childNodes are already copied with this node, so nodeNew = null */
                    oResult = this.fetchContent(oSearch, null, sCase, nLinkCount, sLinkVars);
                    sContent += oResult.sContent;
                    nLinkCount = oResult.nLinkCount;
                    sLinkVars = oResult.sLinkVars;
                };
                if (oSearch.nodeName.toLowerCase() == "a") {
                    sContent += "</a>";
                };
            };
            oRemove = oSearch;
            oSearch = oSearch.nextSibling;
            if (nodeNew != null) {
                nodeRemoved = oRemove.parentNode.removeChild(oRemove);
                nodeNew.appendChild(nodeRemoved);
            };
        };

        return { "sContent": sContent, "nLinkCount": nLinkCount, "sLinkVars": sLinkVars };
    }
}

Ifr.EscapeHex = function(userAgent, hex) {
    if (userAgent.bIsIE) { /* The RegExp for IE breaks old Gecko's, the RegExp for non-IE breaks IE 5.01 */
        return hex.replace(new RegExp("%\d{0}", "g"), "%25");
    }
    return hex.replace(new RegExp("%(?!\d)", "g"), "%25");
};


// Color object representation
// Modified from Stoyan Stefanov 
// Copyright Brian R Miedlar <bmiedlar@gmail.com>

var Color = Class.create();
Color.Definitions = [
    {
        regex: /^rgb\((\d{1,3}),\s*(\d{1,3}),\s*(\d{1,3})\)$/,
        example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'],
        process: function(bits) {
            return [
                parseInt(bits[1]),
                parseInt(bits[2]),
                parseInt(bits[3])
            ];
        }
    },
    {
        regex: /^(\w{2})(\w{2})(\w{2})$/,
        example: ['#00ff00', '336699'],
        process: function(bits) {
            return [
                parseInt(bits[1], 16),
                parseInt(bits[2], 16),
                parseInt(bits[3], 16)
            ];
        }
    },
    {
        regex: /^(\w{1})(\w{1})(\w{1})$/,
        example: ['#fb0', 'f0f'],
        process: function(bits) {
            return [
                parseInt(bits[1] + bits[1], 16),
                parseInt(bits[2] + bits[2], 16),
                parseInt(bits[3] + bits[3], 16)
            ];
        }
    }
];
Color.prototype = {
    'initialize': function(value) {
        this.isValid = false;

        // strip any leading #
        if (value.charAt(0) == '#') value = value.substr(1, 6);

        value = value.replace(/ /g, '');
        value = value.toLowerCase();

        // search through the definitions to find a match
        Color.Definitions.each(function(definition) {
            var processor = definition.process;
            var bits = definition.regex.exec(value);
            if (bits) {
                channels = processor(bits);
                this.r = channels[0];
                this.g = channels[1];
                this.b = channels[2];
                this.isValid = true;
                throw $break;
            }
        } .bind(this));

        // validate/cleanup values
        this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r);
        this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g);
        this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b);
    },
    'toRgb': function() {
        return 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')';
    },
    'toHex': function() {
        var r = this.r.toString(16);
        var g = this.g.toString(16);
        var b = this.b.toString(16);
        if (r.length == 1) r = '0' + r;
        if (g.length == 1) g = '0' + g;
        if (b.length == 1) b = '0' + b;
        return '#' + r + g + b;
    }
}

Element.removeChildren = function(element) {
    element.innerHTML = '';
}
