/* 
 Copyright 2010 Xmarks Inc.

 foxmarks-discover.js: Classes related to SERP and sim sites

 */

(function() {
var xm = Xmarks;

Components.utils.import('resource://xmarks/reviews.jsm', Xmarks);

xm.SimSites = {
    DRIFTSITE: "/site/?cid=xmfx&url=",
    SIMSITE: "/internal/visitsite?cid=xmfx&id=",
    TOPICSITE: "/topic/",
    WRITEREVIEW: "/review/edit/?cid=xmfx&url=",
    _iconLoaded: false,
    observe: function(subject, topic, data) {
        var shouldShow;
        if (topic == "foxmarks-settingschange") {
            shouldShow = this.settings.simsiteEnabled && 
                !this.settings.privateBrowsing;
        } else if (topic == "private-browsing") {
            if (data == "enter") {
                shouldShow = false;
            } else if (data == "exit") {
                shouldShow = this.settings.simsiteEnabled;
            }
        }
        if (shouldShow && !this._iconLoaded) {
            this.addIcon();
        } else if (!shouldShow && this._iconLoaded) {
            this.removeIcon();
        }
    },
    addIcon: function(){
        var staricon = this.doc.getElementById("star-button");
        if(staricon && !this._iconLoaded){
            var img = this.doc.createElement('image');
            img.setAttribute('id', "foxmarks-ss-button");
            img.setAttribute('tooltiptext',
                    xm.Bundle().GetStringFromName("similarsite.getsiteinfo"));
            img.setAttribute('src', 
                    xm.gSettings.httpProtocol + xm.gSettings.staticHost +
                    xm.gSettings.bibBug);
            img.addEventListener(
                "mousedown",
                function(e){
                    xm.SimSites.showSimSites();
                },
                true
            );

            staricon.parentNode.appendChild(img);
            this._iconLoaded = true;
        }
    },
    removeIcon: function() {
        var image = this.doc.getElementById("foxmarks-ss-button");
        image.parentNode.removeChild(image);
        this._iconLoaded = false;
    },
    openLink: function(link, addTab){
        var callback= {
            notify: function(){
                if(addTab){
                    gBrowser.selectedTab = gBrowser.addTab(link);
                } else {
                    gBrowser.selectedBrowser.contentDocument.location.href =
                        link;
                }
            }
        };
        var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
        timer.initWithCallback(callback, 100,
            Ci.nsITimer.TYPE_ONE_SHOT);
    },
    init: function(){
        this.settings = xm.gSettings;
        this.doc = document;
        if(this.settings.simsiteEnabled && !this.settings.privateBrowsing){
            this.addIcon();
        }
        var os = Cc["@mozilla.org/observer-service;1"].
            getService(Ci.nsIObserverService);
        os.addObserver(this, "foxmarks-settingschange", false);
        os.addObserver(this, "private-browsing", false);
        /*
         * FYI this doesn't work so well in linux so using our own 
         * messaging system
        var prefs = Components.classes["@mozilla.org/preferences-service;1"]
                .getService(Components.interfaces.nsIPrefBranch2);
        prefs.addObserver("extensions.xmarks.", this, false);
        */
        var iframe = document.getElementById("foxmarks-bib");
        var self = this;
        var unloadFunc = function(event){
            iframe.removeEventListener(
                "unload",
                unloadFunc,
                true
            );
            var doc = event.target;
            var biblink = doc.getElementById("biblink");
            var link = biblink ? biblink.getAttribute("value") : null;

            if(link){
                var panel = document.getElementById("foxmarks-similarsites");
                if(panel){
                    panel.hidePopup();
                }
                var bibkeys = doc.getElementById("bibkeys");
                var keys = bibkeys.getAttribute("value");
                if(keys.indexOf("M") != -1 || keys.indexOf("C") != -1){
                    self.openLink(link, true);
                } else {
                    self.openLink(link, false);
                }
            }
        };
        iframe.addEventListener(
            "DOMContentLoaded", 
            function(event){
                if(event.target.location.href != "about:blank"){
                    self.handleBibLoad(event.target);
                    iframe.addEventListener(
                        "unload",
                        unloadFunc,
                        true
                    );
                }

            }, 
            true
        );
    },
    handleBibLoad: function(doc){
       var iframe = this.doc.getElementById("foxmarks-bib");
       var win = doc.defaultView;
       var pageHeight = win.innerHeight + win.scrollMaxY
       iframe.setAttribute("height",pageHeight);
       iframe.style.overflow = "hidden";
       this.doc.getElementById("foxmarks-ss-body").
            setAttribute("height", pageHeight);
       //iframe.style.height = "500px;";

    },
    clearPanel: function(){
        this.doc.getElementById("foxmarks-ss-progtitle").
            setAttribute("hidden", "true");
        this.doc.getElementById("foxmarks-ss-progress").
            setAttribute("hidden", "false");
        this.doc.getElementById("foxmarks-ss-body").
            setAttribute("hidden", "true");
       var iframe = this.doc.getElementById("foxmarks-bib");
        iframe.setAttribute("src", "about:blank");
       iframe.setAttribute("height","32");
       iframe.style.overflow = "hidden";
       this.doc.getElementById("foxmarks-ss-body").
            setAttribute("height", "32");
    },
    onPopupHiding: function(){
        if(this._inflight){
            this._inflight = false;
            Xmarks.SimilarSitesCancel();
        }
        xm.SimSites.detachKeyListener();
        return true;
    },
    _handleKeyListener: function(e){
        // static member; this is undefined
        if(e.metaKey){
           return;
        }
        var panel = this.doc.getElementById("foxmarks-similarsites");
        if(panel){
            panel.hidePopup();
        }
    },
    detachKeyListener: function(){
        var urlbar = this.doc.getElementById("urlbar");
        if(!urlbar){
            return;
        }
        urlbar.removeEventListener("keydown", this._handleKeyListener, true);
    },
    attachKeyListener: function(){
        var urlbar = this.doc.getElementById("urlbar");
        if(!urlbar){
            return;
        }
        urlbar.addEventListener("keydown", this._handleKeyListener, true);
    },
    showSimSites: function(){
        if (this.settings.privateBrowsing) {
            return;
        }
        var panel = this.doc.getElementById("foxmarks-similarsites");
        if(panel){

            //BUGFIX for Windows  where popup would close randomly
            var content = this.doc.getElementById("content");
            content.focus();

            this.attachKeyListener();
            panel.openPopup(
                this.doc.getElementById("urlbar"),
                "after_end",
                0,
                0,
                false,
                false
            );
            var url = gBrowser.selectedBrowser.contentDocument.location.href;
            this.clearPanel();
            this._inflight = true;

            var self = this;
            Xmarks.FetchSimilarSites(
                url, 
                this.doc.getElementById("foxmarks-ss-progtitle"), 
                this.doc.getElementById("foxmarks-ss-throbber"), 
                function(data){
                    self._inflight = false;
                    xm.SimSites.loadData(data);
                }
            );
        }
    },
    loadData: function(data){

        if(data && data.status == 0){
            var iframe = this.doc.getElementById("foxmarks-bib");
            iframe.setAttribute("src", "data:text/html," + encodeURI(data.txt));
            this.doc.getElementById("foxmarks-ss-progress").
                setAttribute("hidden", "true");
            this.doc.getElementById("foxmarks-ss-body").
                setAttribute("hidden", "false");
        } else {
            var errbox = this.doc.getElementById("foxmarks-ss-progtitle");

            errbox.setAttribute("value",
                xm.Bundle().GetStringFromName(
                    data.status == 0 || data.status == 400 ?
                    "similarsite.nositeinfo" :
                    "similarsite.busy"
                )
            );
 
            errbox.setAttribute("hidden", "false");
        }
    }

};

xm.SERP = {
    DEBUGSCRIPTURL: "/SERP/gink.js",
    SCRIPTURL: "/SERP/",
    init: function(){
        var domain = xm.Bundle().GetStringFromName("serp.googleintl");
        this.gSettings = xm.gSettings;
        this.topdoc = document;
        this.INTL_PATTERN =
            new RegExp("http:\/\/" + domain + "\/.*[?&]q=([^&]+)");
        var appcontent = document.getElementById("appcontent");
        if(appcontent){
            appcontent.addEventListener(
                "DOMContentLoaded", 
                function(e){ 
                    if(e.originalTarget.nodeName == "#document"){
                        xm.SERP.onPageLoad(e);
                    }
                },
                true
            );
        }
    },
    buildScriptURL: function(prefix){
        var lang = xm.gSettings.lang;
        if(!lang){
            return this.SCRIPTURL + prefix + ".js";
        }
        var langshort = lang.split('-')[0];
        
        if(langshort == "en"){
            return this.SCRIPTURL + prefix + ".js";
        }
        var langs = {
            bn: 1, cs: 1, da: 1, de: 1, el: 1, eu: 1, es: 1, fi: 1, fr: 1,
            fy: 1, hu: 1, bg: 1, it: 1, ja: 1, ko: 1, nb: 1, nl: 1, pl: 1,
            ro: 1, ru: 1, sk: 1, sv: 1, tr: 1, uk: 1, vi: 1
        };

        if(langshort in langs){
            return "/SERP/" + prefix + "." + langshort + ".js";
        }

        switch(lang){
            case "pt-BR":
            case "pt-PT":
            case "zh-CN":
            case "zh-TW":
                return "/SERP/" + prefix + "." + lang + ".js";
        }

        return this.SCRIPTURL + prefix + ".js";
    },
    onPageLoad: function(e){
        // Don't decorate if we're in private browsing mode.
        if (this.gSettings.privateBrowsing) {
            return;
        }
        var doc = e.originalTarget;
        if(!doc ||
           !doc.location ||
           !doc.location.href){
            return;
        }
        var settings = this.gSettings;
        this.doc = doc;
        var rx = new RegExp(settings.serpRegex);
        if(settings.serpEnabled && 
           rx.test(doc.location.href)
        ){
            doc = doc.defaultView.top.document;
            this.doc = doc;
            this.injectScript(settings.serpPrefix, doc);
        }

        if(settings.iframeregex){
            var rx = new RegExp(settings.iframeregex);
            if(rx.test(doc.location.href)){
                this.doc = doc;
                this.injectScript(settings.iframePrefix, doc);
            }
        }
    },
    injectScript: function(prefix, doc){
        var bodytags = doc.getElementsByTagName('body');
        if(bodytags && bodytags.length == 1){
            var field = doc.createElement('input');
            field.setAttribute('type', 'hidden');
            field.setAttribute('id', 'foxmarks.prefs');
            var prefs = [];
            prefs.push("MACHINEID=" + this.gSettings.machineId);
            prefs.push("NUM_TO_SHOW=" + this.gSettings.serpMaxItems);
            prefs.push("APIHOST=" + this.gSettings.apiHost);
            prefs.push("DRIFTHOST=" + this.gSettings.driftHost);
            prefs.push("STATICHOST=" + this.gSettings.staticHost);
            prefs.push("SERPPREFS=" + encodeURIComponent(this.gSettings.serpPrefs));
            prefs.push("TRHOST=" + this.gSettings.trHost);
            if(this.gSettings.getDebugOption("serp")){
                prefs.
                    push("DEBUG=" + this.gSettings.getDebugOption("serp"));
            }
            field.setAttribute('value', prefs.join(";"));
            bodytags[0].appendChild(field);
        }
        var headtags = doc.getElementsByTagName('head');
        if(headtags && headtags.length == 1){
            var script = doc.createElement('script');
            script.setAttribute('src', 
                "http://"+ this.gSettings.staticHost + 
                this.buildScriptURL(prefix)
            );
            headtags[0].appendChild(script);
        }
        if(doc.body){
            var self = this;
            doc.body.addEventListener(
                "xmarksload",
                function(e){
                    var obj = doc.defaultView.wrappedJSObject.XmarksData;
                    Xmarks.Review.AddFromSERP(obj);
                },
                false
            );
            doc.body.addEventListener(
                "xmarks_saveprefs",
                function(e){
                    self.gSettings.serpPrefs = doc.defaultView.wrappedJSObject.XmarksPrefs;
                },
                false
            );
        }
    },
    handleOpenSettings: function(e, doc){
       if(e.target && e.target.id == "foxmarks.opensettings"){
            var os = Cc["@mozilla.org/observer-service;1"].
                getService(Ci.nsIObserverService);
            os.notifyObservers(null, 
                "foxmarks-showsettingpane", 
                "foxmarks-discoverypane"
            );
            e.stopPropagation();
       }
    }
};
})();
