/*
 * sIFR - jQuery plugin for accessible, unobtrusive flash image replacement.
 *
 * Based upon the work of Mike Davidson, Shaun Inman, Tomas Jogin and Mark
 * Wubben. Mike Davidson released his software under the CC-GNU LGPL
 * http://creativecommons.org/licenses/LGPL/2.1/
 *
 * Since this is my own rewrite of his implementation, (ONLY) this plugin
 * is licensed under thesame conditions as other plugins from jQuery.
 *
 * NOTE: Transparency is not supported in Opera 7.x, Safari < 1.2 & Flash 6,
 * in Linux, and in very old (pre 1.0) Mozilla versions. (NOT CHECKED FOR!!)
 *
 * I choose NOT to do so many checks on the passed parameters, since i think
 * we can assume people have the right browser if they are running jQuery.
 *
 * For more configuration options, see the original sifr documentation at the
 * website of Mike Davidson: http://www.mikeindustries.com/sifr/
 *
 * Copyright (c) 2006 Gilles van den Hoven (webunity.nl)
 * Dual licensed under the MIT and GPL licenses:
 *   http://www.opensource.org/licenses/mit-license.php
 *   http://www.gnu.org/licenses/gpl.html
 *
 * v0.1
 */

jQuery.sifr =   {
    blnFlashValid: null,
    /**
     * Trys to retreive the Flash version from the visitor's browser
     * @acces private
     * @param integer major version
     * @param integer minor version
     * @param integer revision version
     */
    _checkFlash: function(intMajor, intMinor, intRevision) {
        var arrFlash = null;
        var strFlash = '';

        // First check
        if (navigator.plugins && navigator.mimeTypes.length) {
            var objFlash = navigator.plugins["Shockwave Flash"];
            if (objFlash && objFlash.description)
                arrFlash = objFlash.description.replace(/([a-zA-Z]|\s)+/, "").replace(/(\s+r|\s+b[0-9]+)/, ".").split(".");
            objFlash = null;
        }

        // Second attempt
        if (!arrFlash) {
            try {
                var objFlash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
            } catch(errB) {
                try {
                    arrFlash = [6, 0, 21];

                    // Create object
                    var objFlash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");

                    // Throws if player version < 6.0.47
                    objFlash.AllowScriptAccess = "always";

                    // If we came here, we can do a version lookup
                    if (objFlash && objFlash.major)
                        arrFlash = [objFlash.major, objFlash.minor, objFlash.revision];
                    objFlash = null;
                } catch(errC) {
                }
            }

            // Third attempt (geez!)
            if (!arrFlash) {
                try {
                    objFlash = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
                    arrFlash = objFlash.GetVariable("$version").split(" ")[1].split(",");
                    objFlash = null;
                } catch(errA) {
                    arrFlash = [0, 0, 0];
                }
            }
        }

        //alert('<DEBUG> Your flash version is: ' + arrFlash[0] + '.' + arrFlash[1] + '.' + arrFlash[2]);

        // Set variable
        jQuery.sifr.blnFlashValid = ((arrFlash[0] >= intMajor) &&
                                                                (arrFlash[1] >= intMinor) &&
                                                                (arrFlash[2] >= intRevision));
    },
    /**
     * Escape the input value
     * @acces private
     * @param string to convert
     */
    _escapeHex: function(strInput){
        if(jQuery.browser.msie){ /* The RegExp for IE breaks old Gecko's, the RegExp for non-IE breaks IE 5.01 */
            return strInput.replace(new RegExp("%\d{0}", "g"), "%25");
        }
        return strInput.replace(new RegExp("%(?!\d)", "g"), "%25");
    },
    /**
     * Retreives and rebuilds the contents of this node.
     * @acces private
     */
    _fetchContent: function(objNode, objNodeNew, strCase, intLinks, strLinkVars) {
        var strContent = "";
        var objSearch = objNode.firstChild;
        var objRemove, objNodeRemoved, objTemp, sValue;

        if (intLinks == null)
            intLinks = 0;

        if (strLinkVars == null)
            strLinkVars = "";

        while (objSearch) {
            if (objSearch.nodeType == 3) {
                sValue = objSearch.nodeValue.replace("<", "&lt;");
                switch(strCase) {
                    case "lower":
                        strContent+= sValue.toLowerCase();
                        break;
                    case "upper":
                        strContent+= sValue.toUpperCase();
                        break;
                    default:
                        strContent+= sValue;
                }
            } else if(objSearch.nodeType == 1) {
                if (jQuery.sifr._matchNodeName(objSearch, "a") && !objSearch.getAttribute("href") == false) {
                    if (objSearch.getAttribute("target"))
                        strLinkVars+= "&sifr_url_" + intLinks + "_target=" + objSearch.getAttribute("target");

                    strLinkVars+= "&sifr_url_" + intLinks + "=" + jQuery.sifr._escapeHex(objSearch.getAttribute("href")).replace(/&/g, "%26");
                    strContent+= '<a href="asfunction:_root.launchURL,' + intLinks + '">';
                    intLinks++;
                } else if (jQuery.sifr._matchNodeName(objSearch, "br")) {
                    strContent+= "<br/>";
                }

                // Fetch information about the childnodes
                if (objSearch.hasChildNodes()) {
                    // The childNodes are already copied with this node, so objNodeNew = null
                    objTemp = jQuery.sifr._fetchContent(objSearch, null, strCase, intLinks, strLinkVars);
                    strContent+= objTemp.strContent;
                    intLinks = objTemp.intLinks;
                    strLinkVars = objTemp.strLinkVars;
                    objTemp = null;
                }

                // Add the closing tag
                if (jQuery.sifr._matchNodeName(objSearch, "a")){
                    strContent+= "</a>";
                }
            }
            objRemove = objSearch;
            objSearch = objSearch.nextSibling;

            if (objNodeNew != null){
                objNodeRemoved = objRemove.parentNode.removeChild(objRemove);
                objNodeNew.appendChild(objNodeRemoved);
            }
        }

        return { 'strContent': strContent, 'intLinks': intLinks, 'strLinkVars': strLinkVars };
    },
    /**
     * Look if the matched node matches
     * @acces private
     * @param object to check
     * @param string to match
     */
    _matchNodeName: function(objNode, strMatch){
        return (strMatch == "*") ? true : (objNode.nodeName.toLowerCase().replace("html:", "") == strMatch.toLowerCase());
    },
    /**
     * Helper function to support older browsers!
     */
    _normalize: function(strInput) {
        return strInput.replace(/\s+/g, " ");
    },
    /**
     * Main build function
     * @acces public
     * @param hash of options
     */
    build: function(arrConfig) {
        var arrOptions = jQuery.extend({
            intRequiredFlashVersion: [6, 0, 0],
            strSWF: '',
            strColor: '#000000',
            strBgColor: '',
            strLinkColor: '',
            strHoverColor: '',
            intPadding: [0, 0, 0, 0],   // Left, top, right, bottom
            strFlashVars: '',
            strCase: '',
            strWmode: ''                            // empty/'transparent'/'opaque'
        }, arrConfig || {});

        // Check config
        if (arrOptions.intPadding.length != 4) {
            alert('Wrong number of arguments for the padding!');
            return;
        }

        // helper to check for required flash version (do this only once per pageload)
        if (!jQuery.sifr.blnFlashValid) {
            jQuery.sifr._checkFlash(arrOptions.intRequiredFlashVersion[0], arrOptions.intRequiredFlashVersion[1], arrOptions.intRequiredFlashVersion[2]);
        }

        // Initialize flashvars
        if(arrOptions.strFlashVars != '')
            arrOptions.strFlashVars = jQuery.sifr._normalize(arrOptions.strFlashVars);

        // Remove & from the start
        if (arrOptions.strFlashVars.substr(0, 1) == '&')
            arrOptions.strFlashVars = arrOptions.strFlashVars.substr(1, arrOptions.strFlashVars.length);

        // Initialize colors
        if(arrOptions.strColor != '')
            arrOptions.strFlashVars+= "textcolor=" + arrOptions.strColor + '&';

        if (arrOptions.strHoverColor != null)
            arrOptions.strFlashVars+= 'hovercolor=' + arrOptions.strHoverColor + '&';

        if ((arrOptions.strLinkColor != null) || (arrOptions.strHoverColor != null))
            arrOptions.strFlashVars+= 'linkcolor=' + (arrOptions.strLinkColor || arrOptions.strColor) + '&';

      // initialize sIFR
      return this.each(function() {
        // Handle to object
        jqThis = jQuery(this);

        // Only continue if we support flash and haven't replaced allready
        if (jQuery.sifr.blnFlashValid && !jqThis.is('.sIFR-flash')) {
            // Calculate new width and height
            intWidth = parseInt(this.offsetWidth);
            intHeight = parseInt(this.offsetHeight);

            // If this fails, we don't have a width and height set, WHICH MUST BE THE CASE
            if (isNaN(intWidth) || isNaN(intHeight)) {
                alert('fook it');
                return;
            }

                // Remove padding
            intWidth-= (arrOptions.intPadding[0] +  arrOptions.intPadding[2]);
            intHeight-= (arrOptions.intPadding[1] +  arrOptions.intPadding[3]);

                // Make sure an & is at the end of the flashvars
                if (arrOptions.strFlashVars.substr(arrOptions.strFlashVars.length, 1) != '&')
                    arrOptions.strFlashVars+= '&';

            // Build variables
                objAlternate = jQuery('<span class="sIFR-alternate"></span>')[0];
            objContent = jQuery.sifr._fetchContent(this, objAlternate, arrOptions.strCase);
                strVars = "txt=" + jQuery.sifr._normalize(jQuery.sifr._escapeHex(objContent.strContent).replace(/\+/g, "%2B").replace(/&/g, "%26").replace(/\"/g, "%22")) + '&';
                strVars+= arrOptions.strFlashVars;
                strVars+= "w=" + intWidth + "&h=" + intHeight + objContent.strLinkVars;
                objContent = null;

                // Generate!
                if (!jQuery.browser.msie) {
                    strHTML = '<embed type="application/x-shockwave-flash" src="' + arrOptions.strSWF + '" quality="best" ';
                    strHTML+= (arrOptions.strWmode != '') ? 'wmode="' + arrOptions.strWmode + '" ' : '';
                    strHTML+= (arrOptions.strBgColor != '') ? 'bgcolor="' + arrOptions.strBgColor + '" ' : '';
                    strHTML+= 'flashvars="' + strVars + '" width="' + intWidth + '" height="' + intHeight + '"></embed>';
                } else {
                    strHTML = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="' + intWidth + '" height="' + intHeight + '">';
                    strHTML+= '<param name="movie" value="' + arrOptions.strSWF + "?" + strVars + '"></param>';
                    strHTML+= '<param name="quality" value="best"></param>';
                    strHTML+= (arrOptions.strWmode != '') ? '<param name="wmode" value="' + arrOptions.strWmode + '"></param>' : '';
                    strHTML+= (arrOptions.strBgColor != '') ? '<param name="bgcolor" value="' + arrOptions.strBgColor + '"></param>' : '';
                    strHTML+= '</object>';
                }

                // Build the sifr tag
            jqThis.addClass('sIFR-flash').empty().append(objAlternate).append(strHTML);

            // Fix MSIE flash issue
            if (jQuery.browser.msie) {
                this.outerHTML = this.outerHTML;
            }
        }
      });
    }
};

// Extend jQuery
jQuery.fn.extend( {
        sifr : jQuery.sifr.build
});