(function(base) {
    var VERSION = "1.3";

    var _STATUS='staging';
    var _REVISION='11424';


    var button_obj =        null;
    var button_process =    false;
    var button_parse =      false;
    var button_loaded =     false;
    var page_loaded =       false;
    var scripts_loaded =    false;


    // base linker object
    var linker = base.linker = {
        getModuleScript: function(name) {
            var p = name.indexOf(".");
            name = (-1 == p) ? name : name.slice(0, p);
            return BUTTONAPPLICATION + "wikifier_" + name + ".js";
        },
        loadModuleScript: function(name) {
            loadxhr(linker.getModuleScript(name));
            return true;
        },

        utils: {
            addEvent: function(element, type, listener, once) {
                if (once) {
                    var handler = listener;
                    listener = function(event) {
                        handler.apply(this, arguments);
                        linker.utils.removeEvent(element, type, arguments.callee);
                    };
                }

                if (element.attachEvent) {
                    return element.attachEvent("on" + type, listener);
                } else if (element.addEventListener) {
                    element.addEventListener(type, listener, true);
                    return true;
                }

                return false;
            },
            removeEvent: function(element, type, listener) {
                if (element.detachEvent) {
                    element.detachEvent("on" + type, listener);
                } else if (element.removeEventListener) {
                    element.removeEventListener(type, listener, true);
                }

                return true;
            },
            createCookie: function(name, value, days) {
                var expires = "";
                if (days) {
                    var date = new Date();
                    date.setTime(date.getTime()+(days*24*60*60*1000));
                    expires = "; expires="+date.toGMTString();
                }
                base.document.cookie = name+"="+value+expires+"; path=/";
            },
            readCookie: function(name) {
                var nameEQ = name + "=";
                var ca = base.document.cookie.split(';');
                for(var i=0;i < ca.length;i++) {
                    var c = ca[i];
                    while (c.charAt(0)==' ') c = c.substring(1, c.length);
                    if (c.indexOf(nameEQ) === 0)
                        return c.substring(nameEQ.length, c.length);
                }
                return null;
            },
            eraseCookie: function(name) {
                linker.utils.createCookie(name, "", -1);
            }
        },

        panel: {
            toggle_visibility: function() {
                var show = base.document.getElementById('wikifier-legend');
                var hide = base.document.getElementById('wikifier-hide-legend');
                if(show.style.display == 'block') {
                    show.style.display = 'none';
                    hide.style.display = 'block';
                } else {
                    show.style.display = 'block';
                    hide.style.display = 'none';
                }
            },
            selectSemanticType: function(elt) {
                if (linker.utils.fireLinkerEvent)
                    linker.utils.fireLinkerEvent("linkerPanelChanged");
            }
        }
    };


    // getting information functions

    function getParam(url, name, value) {
        name += '=';

        var pos = url.lastIndexOf(name);
        if (-1 === pos)
            return value || '';

        value = url.substr(pos+name.length);
        pos = value.indexOf('&');
        if (-1 === pos)
            return value.replace(/%20/g, ' ');

        return value.substr(0, pos).replace(/%20/g, ' ');
    }

    var thisScript = (function(){
        var ScriptID = "ScriptID" + Math.round(100000*Math.random());
        base.document.write("<script id='"+ScriptID+"'></script>");
        return base.document.getElementById(ScriptID).previousSibling.getAttribute("src");
    })();


    // main constants
    var BUTTONAPPLICATION = thisScript.substring(0,thisScript.lastIndexOf('/')+1);
    var APPLICATION = linker.APPLICATION = getParam(thisScript, 'id');
    var ShowLabel =     base.ShowLabel = getParam(thisScript, 'showlabel', 'Show Semantic highlights');
    var HideLabel =     base.HideLabel = getParam(thisScript, 'hidelabel', 'Hide Semantic highlights');
    var BUTTONSTATUS =  getParam(thisScript, 'status').toLowerCase();
    var PAGE =          getParam(thisScript, 'page');


    var BUTTONPRELOAD = true;
    var BUTTONAUTOSTART = false;


    // top bar

    var topText =
            "<div id=\"wikifier-toolbar\">" +
            "   <div id=\"wikifier-logo\">" +
            "       <img title=\"ConceptWeb Linker Button" + "\" src=\"" + BUTTONAPPLICATION + "img/wikifier-logo.gif\" alt=\"img\" width=\"28\" height=\"21\"/>" +
            "   </div>" +
            "   <div id=\"wikifier-toolbar-place\">" +
            "       <div id=\"wikifier-enrichsection\">" +
            "           <input type=\"checkbox\" onclick=\"this.blur();linker.panel.selectSemanticType();\" checked=\"true\" id=\"wikifier-enrich\"/><label for=\"wikifier-enrich\" id=\"wikifier-enrichlabel\" onmouseover=\"this.style.color='#3e7670'\" onmouseout=\"this.style.color='#93bbb7'\">Highlighting</label>" +
            "       </div>" +
            "       <div id=\"wikifier-hide-legend\">" +
            "           <a onclick=\"linker.panel.toggle_visibility();\">show</a>" +
            "       </div>" +
            "       <div style=\"display: block;\" id=\"wikifier-legend\" onmouseover=\"this.style.backgroundColor='#dff1ef'\" onmouseout=\"this.style.backgroundColor=''\">" +
            "           <a onclick=\"linker.panel.toggle_visibility();\">hide</a>" +
            "           <span class=\"wikifier-orange\"><input type=\"checkbox\" id=\"wikifier-behavior\" checked=\"true\" onclick=\"linker.panel.selectSemanticType();\"/><label for=\"wikifier-behavior\">Behavior</label></span>" +
            "           <span class=\"wikifier-blue\"><input type=\"checkbox\" id=\"wikifier-anatomy\" checked=\"true\" onclick=\"linker.panel.selectSemanticType();\"/><label for=\"wikifier-anatomy\">Anatomy</label></span>" +
            "           <span class=\"wikifier-turquoise\"><input type=\"checkbox\" id=\"wikifier-chemicals\" checked=\"true\" onclick=\"linker.panel.selectSemanticType();\"/><label for=\"wikifier-chemicals\">Chemicals</label></span>" +
            "           <span class=\"wikifier-red\"><input type=\"checkbox\" id=\"wikifier-diseases\" checked=\"true\" onclick=\"linker.panel.selectSemanticType();\"/><label for=\"wikifier-diseases\">Diseases</label></span>" +
            "           <span class=\"wikifier-yellow\"><input type=\"checkbox\" id=\"wikifier-genes\" checked=\"true\" onclick=\"linker.panel.selectSemanticType();\"/><label for=\"wikifier-genes\">Genes</label></span>" +
            "           <span class=\"wikifier-pink\"><input type=\"checkbox\" id=\"wikifier-physiology\" checked=\"true\" onclick=\"linker.panel.selectSemanticType();\"/><label for=\"wikifier-physiology\">Physiology</label></span>" +
            "           <span class=\"wikifier-green\"><input type=\"checkbox\" id=\"wikifier-living\" checked=\"true\" onclick=\"linker.panel.selectSemanticType();\"/><label for=\"wikifier-living\">Living Being</label></span>" +
            "           <span class=\"wikifier-purple\"><input type=\"checkbox\" id=\"wikifier-new\" checked=\"true\" onclick=\"linker.panel.selectSemanticType();\"/><label for=\"wikifier-new\">New</label></span>" +
            "           <span class=\"wikifier-gray\"><input type=\"checkbox\" id=\"wikifier-other\" onclick=\"linker.panel.selectSemanticType();\"/><label for=\"wikifier-other\">Other</label></span>" +
            "       </div>" +
            "       <div id=\"wikifier-help\">" +
            "           <a onclick=\"openHelp()\">help</a>" +
            "       </div>" +
            "   </div>" +
            "</div>";

    function insertTopBar() {
        var iframeNode = base.document.getElementById("navigationframe");
        if (iframeNode === null) {
            iframeNode = base.document.createElement("div");
            iframeNode.name = "navigationframe";
            iframeNode.id = "navigationframe";
            iframeNode.style.frameBorder = 1;
            iframeNode.style.border = 0;
            iframeNode.style.padding = 0;
            iframeNode.style.display = linker.state.is_visible? "": "none";
            iframeNode.innerHTML = topText;

            var wikiDiv = base.document.createElement("div");
            wikiDiv.id = "wikifier-navigationframe";
            wikiDiv.appendChild(iframeNode);
            base.document.body.insertBefore(wikiDiv, base.document.body.firstChild);

            // load CSS style
            if (base.document.createStyleSheet) {
                base.document.createStyleSheet(HOST + "/css/stylesheet.css");
            } else {
                var fileref = base.document.createElement("link");
                fileref.setAttribute("rel", "stylesheet");
                fileref.setAttribute("type", "text/css");
                fileref.setAttribute("href", HOST + "/css/stylesheet.css");
                base.document.getElementsByTagName("head")[0].appendChild(fileref);
            }

            linker.utils.fireLinkerEvent("linkerPanelInit", [iframeNode]);
        }
    }


    // script loading functions

    var requests = [];

    function isAlreadyLoaded(uri) {
        for (var i=0; i<requests.length; i++) {
            if (requests[i].uri === uri)
                return requests[i].loaded;
        }

        return false;
    }

    function loadxhr(url, callback, force) {
        force = force || false;

        if (!force && isAlreadyLoaded(url))
            return;

        var i = requests.length;
        requests[i] = {'uri': url, 'loaded': false};
        var head = base.document.getElementsByTagName("head")[0];
        var script = base.document.createElement('script');
        script.setAttribute('id', url);
        script.setAttribute('src', url);
        script.setAttribute('type','text/javascript');

        script.onload = script.onreadystatechange = function() {
            if (!requests[i].loaded && (!this.readyState || "loaded" === this.readyState || "complete" === this.readyState)) {
                requests[i].loaded = true;

                if (callback) {
                    if ('string' === typeof callback)
                        callback = eval(callback);

                    callback();
                }
            }
        };

        head.appendChild(script);
    }

    function WaitForScripts(callback){
        var unloaded = false;
        for (var i=requests.length-1; i>=0; --i) {
            if (!requests[i].loaded) {
                unloaded = true;
                break;
            }
        }

        if (!unloaded && linker.isLoaded)
            unloaded = !linker.isLoaded();

        if (unloaded) {
            base.setTimeout(function() {
                WaitForScripts(callback);
            }, 100);
        } else {
            callback();
        }
    }


    // linker loading functions

    function loadJavascript(parse) {
        if (parse) {
            if (scripts_loaded) {
                button_enrich();
                return;
            }

            button_parse = !button_parse;
        }

        if (button_process || scripts_loaded)
            return;

        button_process = true;

        loadxhr(BUTTONAPPLICATION + "jquery.js");

        if (base.GOOGLE_ANALYTICS && (!base._gat || !base._gat._getTracker)) {
            var gaJsHost = (("https:" == base.document.location.protocol) ? "https://ssl." : "http://www.");
            loadxhr(gaJsHost + "google-analytics.com/ga.js");
        }

        WaitForScripts(function() {
            linker.jQuery = jQuery.noConflict();

            if (base.GOOGLE_ANALYTICS && base._gat) {
                linker.pageTracker = base._gat._getTracker("UA-8954573-1");

                if (linker.pageTracker)
                    linker.pageTracker._trackPageview();
            }

            var commonScriptName = "bin/js/common";
            if (_STATUS !== "undefined" && _STATUS !== "") commonScriptName += "_" + _STATUS;
            if (_REVISION !== "undefined" && _REVISION !== "") commonScriptName += "_" + _REVISION;
            commonScriptName += ".js";

            loadxhr(BUTTONAPPLICATION + commonScriptName);

            if (DEBUG)
                loadxhr(BUTTONAPPLICATION + "log4javascript.js");

            WaitForScripts(function() {
                if (DEBUG) {
                    var log = log4javascript.getLogger();
                    popUpAppender = new log4javascript.PopUpAppender();
                    popUpAppender.setFocusPopUp(true);
                    popUpAppender.setNewestMessageAtTop(false);
                    log.addAppender(popUpAppender);

                    linker.utils.fireLinkerEvent("linkerLogInit", [log]);
                }

                linker.indexing.queryLength = Math.min(linker.indexing.queryLength, (linker.browser.is_ie6 || linker.browser.is_ie7) ? 1800 : 3072);

                if ('undefined' !== typeof base.setupWikify)
                    base.setupWikify(linker.state);

                loadxhr(BUTTONAPPLICATION + "wikifier_transport_xhr.js");

                WaitForScripts(function() {
                    scripts_loaded = true;
                    button_process = false;

                    if (button_parse)
                        button_enrich();
                });
            });
        });
    }

    function WikiProfClick() {
        loadJavascript(true);
    }


    // enrich functions

    function button_enrich(){
        HOST = BUTTONAPPLICATION.replace(/\/$/, "");
        linker.base_url = HOST + "/default.py?url=";

        if (!linker.utils.getData(base, "initialized")) {
            linker.initpage(base, "button_" + _REVISION, APPLICATION);

            if (linker.state.options.topbar.show)
                insertTopBar();

            linker.parsing.SiteSpecificHandling(PAGE);
            linker.utils.addEvent(button_obj, "mouseenter", function() {
                linker.utils.fireLinkerEvent("linkerButtonOver");
            });
            linker.utils.addEvent(button_obj, "mouseleave", function() {
                linker.utils.fireLinkerEvent("linkerButtonOut");
            });
            linker.ui.caller = "CWButton";

            if (false !== base.SHOW_BUTTON) {
                if (base.hideWikifyButton) {
                    hideWikifyButton(button_obj);
                } else {
                    hideDefaultWikifyButton(button_obj);
                }
            }

            linker.utils.createCookie("wikibutton" + APPLICATION, "true");
        } else {
            if (linker.state.is_visible) {
                if (false !== base.SHOW_BUTTON) {
                    if (base.showWikifyButton)
                        showWikifyButton(button_obj);
                    else
                        showDefaultWikifyButton(button_obj);
                }

                linker.utils.createCookie("wikibutton" + APPLICATION, "false");
            } else {
                if (false !== base.SHOW_BUTTON) {
                    if (base.hideWikifyButton) {
                        hideWikifyButton(button_obj);
                    } else {
                        hideDefaultWikifyButton(button_obj);
                    }
                }

                linker.utils.createCookie("wikibutton" + APPLICATION, "true");
            }

            linker.utils.fireLinkerEvent("linkerVisibilityChanged", [!linker.state.is_visible]);
        }

        return 0;
    }


    // default site functions

    function insertDefaultWikifyButton(place) {
        var img = base.document.getElementById("wikifier-conceptweblinker-button");
        if (null !== img)
            return img; // already exists

        if ("undefined" === typeof place) {
            place = base.document.getElementById("wikifier-conceptweblinker-button-place");
            if (null === place) {
                return false; // can't find place and have no WriteDebugLine at this stage
            }
        }

        img = base.document.createElement("img");
        if (!APPLICATION) {
            img.src = BUTTONAPPLICATION + "img/anywikibutton.png";
        } else {
            img.src = BUTTONAPPLICATION + "img/wikibutton.png";
        }
        img.id = "wikifier-conceptweblinker-button";
        img.title = "Knewco's ConceptWeb Linker Button";
        img.style.cursor = "pointer";

        if (BUTTONPRELOAD)
            linker.utils.addEvent(img, "load", button_load);

        place.appendChild(img);

        IEPNGFix.process(img, 1);

        return img;
    }

    function showDefaultWikifyButton(button) {
        if ("undefined" === typeof button) {
            button = base.document.getElementById("wikifier-conceptweblinker-button");
            if (null === button) {
                if ("undefined" !== typeof base.WriteDebugLine)
                    WriteDebugLine("Can't find wikify button");
                return false;
            }
        }

        if (button.tagName.toLowerCase() === "img") {
            if (!APPLICATION) {
                button.src = BUTTONAPPLICATION + "img/anywikibutton.png";
            } else {
                button.src = BUTTONAPPLICATION + "img/wikibutton.png";
            }
            return true;
        }

        if (button.tagName.toLowerCase() === "a") {
            button.innerHTML = ShowLabel;
            return true;
        }

        return false;
    }

    function hideDefaultWikifyButton(button) {
        if ("undefined" === typeof button) {
            button = base.document.getElementById("wikifier-conceptweblinker-button");
            if (null === button) {
                if ("undefined" !== typeof base.WriteDebugLine)
                    WriteDebugLine("Can't find wikify button");
                return false;
            }
        }

        if (button.tagName.toLowerCase() === "img") {
            if (!APPLICATION) {
                button.src = BUTTONAPPLICATION + "img/anywikibutton_hide.png";
            } else {
                button.src = BUTTONAPPLICATION + "img/wikibutton_hide.png";
            }
            return true;
        }

        if (button.tagName.toLowerCase() === "a") {
            button.innerHTML = HideLabel;
            return true;
        }

        return false;
    }


    // preload functions
    if (BUTTONPRELOAD) {
        function button_load() {
            button_loaded = true;

            if (button_loaded)
                loadJavascript();
        }

        function page_load() {
            page_loaded = true;

            if (button_loaded)
                loadJavascript();
        }

        linker.utils.addEvent(base, "load", page_load);
    }


    base.document.write('<span id="wikifier-conceptweblinker-button-place"></span>');


    var loaderScriptName = "bin/js/loader_" + (APPLICATION || 'Default');
    if (_STATUS !== "undefined" && _STATUS !== "") loaderScriptName += "_" + _STATUS;
    if (_REVISION !== "undefined" && _REVISION !== "") loaderScriptName += "_" + _REVISION;
    loaderScriptName += ".js";

    loadxhr(BUTTONAPPLICATION + loaderScriptName);

    WaitForScripts(function() {
        if ('undefined' !== base.BUTTON_PRELOAD)
            BUTTONPRELOAD = base.BUTTON_PRELOAD;

        if ('undefined' !== base.BUTTON_AUTOSTART)
            BUTTONAUTOSTART = base.BUTTON_AUTOSTART;

        if (false === base.SHOW_BUTTON) {
            button_obj = null;

            if (BUTTONPRELOAD)
                button_load();
        } else {
            var place = base.document.getElementById("wikifier-conceptweblinker-button-place");
            if ('undefined' !== typeof base.insertWikifyButton) {
                var obj = insertWikifyButton(place);
                if (obj)
                    button_obj = obj;
                else
                    button_obj = base.document.getElementById("wikifier-conceptweblinker-button") || place;

                if (BUTTONPRELOAD) {
                    if ('img' === button_obj.tagName.toLowerCase())
                        linker.utils.addEvent(button_obj, "load", button_load);
                    else
                        button_load();
                }
            } else {
                button_obj = insertDefaultWikifyButton(place);
            }

            linker.utils.addEvent(button_obj, "click", WikiProfClick);
        }

        if (BUTTONAUTOSTART || ("on" === BUTTONSTATUS) || ("true" === linker.utils.readCookie("wikibutton" + APPLICATION)))
            WikiProfClick();
    });
})(window);
