﻿/*
 * @copyright 2008, Curators of the University of Missouri 

 * @version 0.5.2009.04.14 

 */

var muIconInserter = new Class({
    Implements: Options,
    options: {
        ElementsToSearch: [document.body],
        IconSeparator: "&nbsp;",
        FireOnDomReady: true,
        Debug: false,
        SubDomainsAreExternal: true,
        ExternalExceptions: [],
        CookieOptions: {
            Enabled: true,
            Name: "mu-icon-inserter",
            Duration: 7
        },
        EmailPattern: "^mailto:*?",
        DocPattern: ".*?.{extension}$"
    },
    initialize: function(b, a) {
        this.boolEmail = false;
        this.boolExternal = false;
        this.boolDocuments = false;
        this.boolExceptions = false;
        this.boolBaseDomainSet = false;
        this.aryRequiredProperties = ["imagesource", "alttext", "styleclass", "location"];
        this.aryRequiredDocProperties = ["extension"];
        this.aryValidTypes = ["email", "external", "document"];
        this.strClassName = "MU Icon Inserter";
        this.strBaseErrMsg = "A problem has been encountered with the " + this.strClassName + ". \n";
        this.setOptions(a);
        if (this.options.FireOnDomReady) {
            window.addEvent("domready", function() {
                this.loadDefinitions(b);
            }.bind(this));
        } else {
            this.loadDefinitions(b);
        }
    },
    begin: function(a) {
        if (this.options.Debug) {
            this.testForErrors(a);
        } else {
            this.startInsertion(a);
        }
    },
    startInsertion: function(a) {
        this.__setInternalParameters(a);
        this.options.ElementsToSearch.each(function(b) {
            $(b).getElements("a").each(function(e) {
                if ($chk(e.href) && e.getElements("img").length == 0) {
                    if (e.href.test(this.options.EmailPattern)) {
                        if (this.boolEmail) {
                            this.__insertIcon(e, this.objEmail);
                        }
                    } else {
                        if (this.boolExternal && !e.href.contains(document.domain)) {
                            var d = true;
                            if (this.boolExceptions) {
                                boolMatch = false;
                                intExceptionslen = a.external.exception.length;
                                var c = 0;
                                while (c < intExceptionslen && !boolMatch) {
                                    if (e.href.contains(a.external.exception[c])) {
                                        boolMatch = true;
                                        d = false;
                                    }++c;
                                }
                            }
                            if (!this.options.SubDomainsAreExternal && d) {
                                strBaseDomain = this.__extractBaseDomain(document.domain);
                                if (e.href.contains(strBaseDomain)) {
                                    d = false;
                                }
                            }
                            if (d) {
                                this.__insertIcon(e, this.objExternal);
                            }
                        }
                        if (this.boolDocuments) {
                            this.__insertDocumentIcon(e, this.aryDocuments);
                        }
                    }
                }
            }.bind(this));
        }.bind(this));
    },
    loadDefinitions: function(b) {
        if ($type(b) != "object") {
            if (this.options.CookieOptions.Enabled && Cookie.read(this.options.CookieOptions.Name) != null) {
                b = JSON.decode(iconCookie);
                this.begin(b);
            } else {
                var a = new Request({
                    method: "get",
                    url: b,
                    onComplete: function(c) {
                        this.convertXMLtoJSON(c);
                    }.bind(this)
                }).send();
            }
        } else {
            this.begin(b);
        }
    },
    __setInternalParameters: function(a) {
        if ($defined(a.email && $type(a.email) == "object")) {
            this.boolEmail = true;
            this.objEmail = a.email;
        }
        if ($defined(a.external) && $type(a.external) == "object") {
            this.boolExternal = true;
            this.objExternal = a.external;
            if ($defined(a.external.exception) && $type(a.external.exception) == "array" && a.external.exception.length > 0) {
                this.boolExceptions = true;
            }
        }
        if ($defined(a.document) && $type(a.document) == "array" && a.document.length > 0) {
            this.boolDocuments = true;
            this.aryDocuments = a.document;
        }
        this.elmSpacer = new Element("span", {
            html: this.options.IconSeparator
        });
    },
    __insertIcon: function(d, c) {
        var b = this.elmSpacer.clone();
        var a = this.__createImageElement(c.imagesource, c.alttext, c.styleclass);
        switch (c.location) {
        case "after":
            b.inject(d, "after");
            a.inject(b, "after");
            break;
        case "into":
            d.adopt(b);
            d.adopt(a);
            break;
        }
    },
    __insertDocumentIcon: function(d, a) {
        var b = 0;
        var c = false;
        intDocumentsLen = a.length;
        while (b < intDocumentsLen && !c) {
            objExtensionDef = {
                extension: a[b].extension
            };
            strPattern = this.options.DocPattern.substitute(objExtensionDef);
            if (d.href.test(strPattern)) {
                this.__insertIcon(d, a[b]);
                c = true;
            }++b;
        }
    },
    __createImageElement: function(b, a, c) {
        return new Element("img", {
            src: b,
            alt: a,
            title: a,
            "class": c
        });
    },
    loadErrorReporter: function(c, a) {
        if (typeof(muErrorReporter) == "undefined") {
            var b = "I need to report an error, but the muErrorReporter class is not available.  Will attempt to dump out errors messages via alert instead.";
            alert(b);
            if ($type(c) == "array") {
                c.each(function(d) {
                    alert(d);
                });
            } else {
                this.ErrorReporter = new Object();
                this.ErrorReporter.boolError = false;
                this.ErrorReporter.aryErrMsgs = new Array();
                this.ErrorReporter.RecordError = function(d) {
                    this.aryErrMsgs.include(d);
                    if (!this.boolError) {
                        this.boolError = true;
                    }
                };
                this.ErrorReporter.ErrorsEncountered = function() {
                    return this.boolError;
                };
                this.ErrorReporter.DisplayErrors = function() {
                    this.aryErrMsgs.each(function(d) {
                        alert(d);
                    });
                };
            }
        } else {
            if (!$defined(this.ErrorReporter)) {
                this.ErrorReporter = new muErrorReporter();
            }
        }
    },
    testForErrors: function(objDefinitions) {
        if (!$defined(this.ErrorReporter)) {
            this.loadErrorReporter();
        }
        this.aryValidTypes.each(function(strType) {
            var objItem = eval("objDefinitions." + strType);
            if ($defined(objItem)) {
                if (strType == "document") {
                    var aryReqProps = this.aryRequiredProperties;
                    aryReqProps.extend(this.aryRequiredDocProperties);
                    intDocCount = 0;
                    objItem.each(function(objDocument) {
                        this.testForRequiredProperties(objDocument, strType + " " + intDocCount, aryReqProps); ++intDocCount;
                    }.bind(this));
                } else {
                    this.testForRequiredProperties(objItem, strType, this.aryRequiredProperties);
                }
            }
        }.bind(this));
        if (this.ErrorReporter.ErrorsEncountered()) {
            this.ErrorReporter.DisplayErrors();
        } else {
            this.startInsertion(objDefinitions);
        }
    },
    testForRequiredProperties: function(objItem, strType, aryRequiredProperties) {
        var msgErrorMessage = "The {property} for {type} must be defined and can not be left blank";
        aryRequiredProperties.each(function(strProperty) {
            if (!$defined(eval("objItem." + strProperty)) || eval("objItem." + strProperty) == "") {
                var objOptions = {
                    property: strProperty,
                    type: strType
                };
                this.ErrorReporter.RecordError(msgErrorMessage.substitute(objOptions));
            }
        }.bind(this));
    },
    convertXMLtoJSON: function(c) {
        var a = new Array();
        if ($type(c) != "string" || c == "") {
            var b = "I was unable to load the xml data definitions. Please verify the path the xml file.";
            a.include(b);
        }
        if (typeof(xml2json) == "undefined") {
            var b = "I was unable to load the xml parser. Please verify the path to the source file.";
            a.include(b);
        }
        if (a.length == 0) {
            objDefinitions = xml2json.parser(c);
            if (this.options.CookieOptions.Enabled) {
                this.writeIconCookie(objDefinitions.definitions);
            }
            this.begin(objDefinitions.definitions);
        } else {
            this.reportXMLErrors(a);
        }
    },
    reportXMLErrors: function(a) {
        if (!$defined(this.ErrorReporter)) {
            this.ErrorReporter = this.loadErrorReporter();
        }
        a.each(function(b) {
            this.ErrorReporter.RecordError(b);
        }.bind(this));
        this.ErrorReporter.DisplayErrors();
    },
    writeIconCookie: function(a) {
        Cookie.write(this.options.CookieOptions.Name, JSON.encode(a), {
            domain: document.domain,
            duration: this.options.CookieOptions.Duration
        });
    },
    __extractBaseDomain: function(a) {
        aryDomainParts = a.split(".");
        intDomainPartslen = aryDomainParts.length;
        return aryDomainParts[intDomainPartslen - 2] + "." + aryDomainParts[intDomainPartslen - 1];
    }
});
var xml2json = {
    parser: function(e, d, b) {
        if (!d) {
            d = "";
        }
        e = e.replace(/\s*\/>/g, "/>");
        e = e.replace(/<\?[^>]*>/g, "").replace(/<\![^>]*>/g, "");
        if (!d.sort) {
            d = d.split(",");
        }
        var a = this.no_fast_endings(e);
        a = this.attris_to_tags(a);
        a = escape(a);
        a = a.split("%3C").join("<").split("%3E").join(">").split("%3D").join("=").split("%22").join('"');
        for (var c = 0; c < d.length; c++) {
            a = a.replace(new RegExp("<" + d[c] + ">", "g"), "*$**" + d[c] + "**$*");
            a = a.replace(new RegExp("</" + d[c] + ">", "g"), "*$***" + d[c] + "**$*");
        }
        a = "<JSONTAGWRAPPER>" + a + "</JSONTAGWRAPPER>";
        this.xmlobject = {};
        var f = this.xml_to_object(a).jsontagwrapper;
        if (b) {
            f = this.show_json_structure(f, b);
        }
        return f;
    },
    xml_to_object: function(xmlcode) {
        var x = xmlcode.replace(/<\//g, "???");
        x = x.split("<");
        var y = [];
        var level = 0;
        var opentags = [];
        for (var i = 1; i < x.length; i++) {
            var tagname = x[i].split(">")[0];
            opentags.push(tagname);
            level++;
            y.push(level + "<" + x[i].split("???")[0]);
            while (x[i].indexOf("???" + opentags[opentags.length - 1] + ">") >= 0) {
                level--;
                opentags.pop();
            }
        }
        var oldniva = -1;
        var objname = "this.xmlobject";
        for (var i = 0; i < y.length; i++) {
            var preeval = "";
            var niva = y[i].split("<")[0];
            var tagnamn = y[i].split("<")[1].split(">")[0];
            tagnamn = tagnamn.toLowerCase();
            var rest = y[i].split(">")[1];
            if (niva <= oldniva) {
                var tabort = oldniva - niva + 1;
                for (var j = 0; j < tabort; j++) {
                    objname = objname.substring(0, objname.lastIndexOf("."));
                }
            }
            objname += "." + tagnamn;
            var pobject = objname.substring(0, objname.lastIndexOf("."));
            if (eval("typeof " + pobject) != "object") {
                preeval += pobject + "={value:" + pobject + "};\n";
            }
            var objlast = objname.substring(objname.lastIndexOf(".") + 1);
            var already = false;
            for (k in eval(pobject)) {
                if (k == objlast) {
                    already = true;
                }
            }
            var onlywhites = true;
            for (var s = 0; s < rest.length; s += 3) {
                if (rest.charAt(s) != "%") {
                    onlywhites = false;
                }
            }
            if (rest != "" && !onlywhites) {
                if (rest / 1 != rest) {
                    rest = "'" + rest.replace(/\'/g, "\\'") + "'";
                    rest = rest.replace(/\*\$\*\*\*/g, "</");
                    rest = rest.replace(/\*\$\*\*/g, "<");
                    rest = rest.replace(/\*\*\$\*/g, ">");
                }
            } else {
                rest = "{}";
            }
            if (rest.charAt(0) == "'") {
                rest = "unescape(" + rest + ")";
            }
            if (already && !eval(objname + ".sort")) {
                preeval += objname + "=[" + objname + "];\n";
            }
            var before = "=";
            after = "";
            if (already) {
                before = ".push(";
                after = ")";
            }
            var toeval = preeval + objname + before + rest + after;
            eval(toeval);
            if (eval(objname + ".sort")) {
                objname += "[" + eval(objname + ".length-1") + "]";
            }
            oldniva = niva;
        }
        return this.xmlobject;
    },
    show_json_structure: function(d, a, b) {
        var h = "";
        if (d.sort) {
            h += "[\n";
        } else {
            h += "{\n";
        }
        for (var e in d) {
            if (!d.sort) {
                h += e + ":";
            }
            if (typeof d[e] == "object") {
                h += this.show_json_structure(d[e], false, 1);
            } else {
                if (typeof d[e] == "function") {
                    var m = d[e] + "";
                    h += m;
                } else {
                    if (typeof d[e] != "string") {
                        h += d[e] + ",\n";
                    } else {
                        h += "'" + d[e].replace(/\'/g, "\\'").replace(/\n/g, "\\n").replace(/\t/g, "\\t").replace(/\r/g, "\\r") + "',\n";
                    }
                }
            }
        }
        if (d.sort) {
            h += "],\n";
        } else {
            h += "},\n";
        }
        if (!b) {
            h = h.substring(0, h.lastIndexOf(","));
            h = h.replace(new RegExp(",\n}", "g"), "\n}");
            h = h.replace(new RegExp(",\n]", "g"), "\n]");
            var f = h.split("\n");
            h = "";
            var g = 0;
            for (var e = 0; e < f.length; e++) {
                if (f[e].indexOf("}") >= 0 || f[e].indexOf("]") >= 0) {
                    g--;
                }
                tabs = "";
                for (var c = 0; c < g; c++) {
                    tabs += "\t";
                }
                h += tabs + f[e] + "\n";
                if (f[e].indexOf("{") >= 0 || f[e].indexOf("[") >= 0) {
                    g++;
                }
            }
            if (a == "html") {
                h = h.replace(/</g, "&lt;").replace(/>/g, "&gt;");
                h = h.replace(/\n/g, "<BR>").replace(/\t/g, "&nbsp;&nbsp;&nbsp;&nbsp;");
            }
            if (a == "compact") {
                h = h.replace(/\n/g, "").replace(/\t/g, "");
            }
        }
        return h;
    },
    no_fast_endings: function(a) {
        a = a.split("/>");
        for (var c = 1; c < a.length; c++) {
            var b = a[c - 1].substring(a[c - 1].lastIndexOf("<") + 1).split(" ")[0];
            a[c] = "></" + b + ">" + a[c];
        }
        a = a.join("");
        return a;
    },
    attris_to_tags: function(a) {
        var g = " =\"'".split("");
        a = a.split(">");
        for (var e = 0; e < a.length; e++) {
            var b = a[e].split("<");
            for (var f = 0; f < 4; f++) {
                b[0] = b[0].replace(new RegExp(g[f], "g"), "_jsonconvtemp" + f + "_");
            }
            if (b[1]) {
                b[1] = b[1].replace(/'/g, '"');
                b[1] = b[1].split('"');
                for (var c = 1; c < b[1].length; c += 2) {
                    for (var f = 0; f < 4; f++) {
                        b[1][c] = b[1][c].replace(new RegExp(g[f], "g"), "_jsonconvtemp" + f + "_");
                    }
                }
                b[1] = b[1].join('"');
            }
            a[e] = b.join("<");
        }
        a = a.join(">");
        a = a.replace(/ ([^=]*)=([^ |>]*)/g, "><$1>$2</$1");
        a = a.replace(/>"/g, ">").replace(/"</g, "<");
        for (var f = 0; f < 4; f++) {
            a = a.replace(new RegExp("_jsonconvtemp" + f + "_", "g"), g[f]);
        }
        return a;
    }
};
if (!Array.prototype.push) {
    Array.prototype.push = function(a) {
        this[this.length] = a;
        return true;
    };
}
if (!Array.prototype.pop) {
    Array.prototype.pop = function() {
        var a = this[this.length - 1];
        this.length--;
        return a;
    };
}