if (!("CueCard" in window)) {
    (function() {
        var acreAppUrl = "http://cuecard.dfhuynh.user.dev.freebaseapps.com/";
        
        window.CueCard = {
            loaded:                 false,
            loadingScriptsCount:    0,
            error:                  null,
            helper: acreAppUrl,
            apiProxy: {
                base : acreAppUrl,
                read:  "mqlread?",
                write: "mqlwrite?"
            },
            freebaseServiceUrl:     "http://www.freebase.com/",
            params:                 { bundle: true, externals: true }
        };
        
        var getHead = function(doc) {
            return doc.getElementsByTagName("head")[0];
        };
        CueCard.findScript = function(doc, substring) {
            var heads = doc.documentElement.getElementsByTagName("head");
            for (var h = 0; h < heads.length; h++) {
                var node = heads[h].firstChild;
                while (node != null) {
                    if (node.nodeType == 1 && node.tagName.toLowerCase() == "script") {
                        var url = node.src;
                        var i = url.indexOf(substring);
                        if (i >= 0) {
                            return url;
                        }
                    }
                    node = node.nextSibling;
                }
            }
            return null;
        };
        CueCard.includeJavascriptFile = function(doc, url, onerror, charset) {
            onerror = onerror || "";
            if (doc.body == null) {
                try {
                    var q = "'" + onerror.replace( /'/g, '&apos' ) + "'"; // "
                    doc.write("<script src='" + url + "' onerror="+ q +
                              (charset ? " charset='"+ charset +"'" : "") +
                              " type='text/javascript'>"+ onerror + "</script>");
                    return;
                } catch (e) {
                    // fall through
                }
            }

            var script = doc.createElement("script");
            if (onerror) {
                try { script.innerHTML = onerror; } catch(e) {}
                script.setAttribute("onerror", onerror);
            }
            if (charset) {
                script.setAttribute("charset", charset);
            }
            script.type = "text/javascript";
            script.language = "JavaScript";
            script.src = url;
            return getHead(doc).appendChild(script);
        };
        CueCard.includeJavascriptFiles = function(doc, urlPrefix, filenames) {
            for (var i = 0; i < filenames.length; i++) {
                CueCard.includeJavascriptFile(doc, urlPrefix + filenames[i]);
            }
            CueCard.loadingScriptsCount += filenames.length;
            //CueCard.includeJavascriptFile(doc, CueCard.urlPrefix + "scripts/signal.js?" + filenames.length);
        };
        CueCard.includeCssFile = function(doc, url) {
            if (doc.body == null) {
                try {
                    doc.write("<link rel='stylesheet' href='" + url + "' type='text/css'/>");
                    return;
                } catch (e) {
                    // fall through
                }
            }
            
            var link = doc.createElement("link");
            link.setAttribute("rel", "stylesheet");
            link.setAttribute("type", "text/css");
            link.setAttribute("href", url);
            getHead(doc).appendChild(link);
        };
        CueCard.includeCssFiles = function(doc, urlPrefix, filenames) {
            for (var i = 0; i < filenames.length; i++) {
                CueCard.includeCssFile(doc, urlPrefix + filenames[i]);
            }
        };
        CueCard.parseURLParameters = function(url, to, types) {
            to = to || {};
            types = types || {};
            
            if (typeof url == "undefined") {
                url = location.href;
            }
            var q = url.indexOf("?");
            if (q < 0) {
                return to;
            }
            url = (url+"#").slice(q+1, url.indexOf("#")); // toss the URL fragment
            
            var params = url.split("&"), param, parsed = {};
            var decode = window.decodeURIComponent || unescape;
            for (var i = 0; param = params[i]; i++) {
                var eq = param.indexOf("=");
                var name = decode(param.slice(0,eq).replace(/\+/g, ' '));
                var old = parsed[name];
                if (typeof old == "undefined") {
                    old = [];
                } else if (!(old instanceof Array)) {
                    old = [old];
                }
                parsed[name] = old.concat(decode(param.slice(eq+1).replace(/\+/g, ' ')));
            }
            for (var i in parsed) {
                if (!parsed.hasOwnProperty(i)) continue;
                var type = types[i] || String;
                var data = parsed[i];
                if (!(data instanceof Array)) {
                    data = [data];
                }
                if (type === Boolean && data[0] == "false") {
                    to[i] = false; // because Boolean("false") === true
                } else {
                    to[i] = type.apply(this, data);
                }
            }
            return to;
        };
        
        if (typeof CueCard_urlPrefix == "string") {
            CueCard.urlPrefix = CueCard_urlPrefix;
        } else {
            var url = CueCard.findScript(document, "cuecard-api.js");
            if (url == null) {
                CueCard.error = new Error("Failed to derive URL prefix for CueCard API code files");
                return;
            }

            CueCard.urlPrefix = url.substr(0, url.indexOf("cuecard-api.js"));
        }

        CueCard.parseURLParameters(url, CueCard.params, {bundle:Boolean, externals:Boolean});
        CueCard.externalPrefix = CueCard.urlPrefix + "external/";
        CueCard.codemirrorPrefix = CueCard.externalPrefix + "CodeMirror/";
        CueCard.jqueryuiPrefix = CueCard.externalPrefix + "jquery-ui/";
        
        if (!(window.__cuecard_suppress_loading)) {
            var externalJavascriptFiles = [
                "http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js",
                CueCard.jqueryuiPrefix + "jquery-ui-1.7.1.custom.min.js",
                CueCard.codemirrorPrefix + "js/codemirror.js",
                CueCard.externalPrefix + "json2.js",
                CueCard.externalPrefix + "jquery.cookie.js"
            ];
            var javascriptFiles = [
                "cuecard.js",
                "mql-syntax.js",
                "indent-writer.js",
                "jsonize.js",
                "queue.js",
                "query-parser.js",
                "query-model.js",
                "ui.js",
                "popup.js",
                "topic-suggestors.js",
                "static-choices-suggestor.js",
                "property-suggestor.js",
                "type-suggestor.js",
                "suggestion-controller.js",
                "query-editor.js",
                "output-pane.js",
                "control-pane.js",
                "code-generation.js",
                "example-dialog.js",
                "examples.js",
                "languages.js",
                "x-metaweb-costs.js"
            ];
            var externalCssFiles = [
                CueCard.jqueryuiPrefix + "theme/jquery-ui-1.7.1.custom.css"
            ];
            var cssFiles = [
                "cuecard.css",
                "query-editor.css",
                "popup.css",
                "suggestion.css",
                "output-pane.css",
                "control-pane.css",
                "example-dialog.css"
            ];
            
            if (CueCard.params.externals) {
                CueCard.includeJavascriptFiles(document, "", externalJavascriptFiles);
                CueCard.includeCssFiles(document, "", externalCssFiles);
            }
            
            if (CueCard.params.bundle) {
                CueCard.includeJavascriptFiles(document, CueCard.urlPrefix, [ "cuecard-bundle.js" ]);
                CueCard.includeCssFiles(document, CueCard.urlPrefix, [ "cuecard-bundle.css" ]);
            } else {
                CueCard.includeJavascriptFiles(document, CueCard.urlPrefix + "scripts/", javascriptFiles);
                CueCard.includeCssFiles(document, CueCard.urlPrefix + "styles/", cssFiles);
            }
        }
        
        CueCard.loaded = true;
    })();
}