(function() {
    var jsm = { };
    if (typeof XPCOMUtils == "undefined") {
        Cu.import("resource://gre/modules/XPCOMUtils.jsm");
    }
    XPCOMUtils.defineLazyGetter(jsm, "utils", function() {
        let obj = { };
        Cu["import"]("resource://livemargins/utils.jsm", obj);
        return obj.utils;
    });
    XPCOMUtils.defineLazyGetter(jsm, "SnapshotStorage", function() {
        let obj = { };
        Cu["import"]("resource://livemargins/apps/snapshot.js", obj);
        return obj.SnapshotStorage;
    });
    XPCOMUtils.defineLazyGetter(jsm, "Tracker", function() {
        let obj = { };
        Cu["import"]("resource://livemargins/track.jsm", obj);
        return obj.Tracker;
    });

    var ns = MOA.ns('LM4.Snapshot');
    var _logger = jsm.utils.logger('LM4.snapshot');
    var _strings = null;

    ns.init = function (evt) {
        _strings = document.getElementById("livemarginsStrings");
    };

    ns.getDefaultAction = function() {
        return jsm.utils.getPref("postSnapshotDefaultAction", "local");
    };

    ns.getSnapshot = function(part) {
        jsm.Tracker.track(jsm.Tracker.snapshot.type, jsm.Tracker.snapshot.actions.SNAP, part);
        var contentWindow = window.content;
        var document = contentWindow.document;
        var width, height, x, y;
        switch (part) {
            case 'visible':
                x = document.documentElement.scrollLeft;
                y = document.documentElement.scrollTop;
                width = document.documentElement.clientWidth;
                height = document.documentElement.clientHeight;
                break;
            case 'entire':
                x = y = 0;
                width = Math.max(document.documentElement.scrollWidth, document.body.scrollWidth);
                height = Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
                break;
            default:
                _logger.trace('unknown part argument')
        }

        var scale = 1;
        // Unfortunately there is a limit:
        if (height > 8192) {
            scale = 8192 / height;
        }

        var canvas = document.createElementNS("http://www.w3.org/1999/xhtml", "html:canvas");
        var ctx = canvas.getContext("2d");

        canvas.height = height * scale;
        canvas.width = width * scale;
        ctx.clearRect(0, 0, canvas.width, canvas.height);
        ctx.scale(scale, scale);
        ctx.save();
        ctx.drawWindow(contentWindow, x, y, width, height, "rgb(255,255,255)");

        sendSnapshot(canvas, ctx);
    };

    var sendSnapshot = function(canvas, ctx) {
        var defaultAction = ns.getDefaultAction();
        jsm.Tracker.track(jsm.Tracker.snapshot.type, jsm.Tracker.snapshot.actions.POST, defaultAction);

        switch(defaultAction) {
            case "local":
                saveDataToDisk(canvas.toDataURL("image/png", ""));
                break;
            case "editor":
                jsm.SnapshotStorage.push(ctx.getImageData(0, 0, canvas.width, canvas.height));
                window.open('chrome://livemargins/content/editor.xhtml', 'AppcenterSnapshotEditor', 'menubar=no,toolbar=no,location=no,personalbar=no,status=no,scrollbars=yes,resizable');
                break;
            case "xiuxiu":
                _logger.trace('xiuxiu, not implemented')
        }
    }

    var saveDataToDisk = function(data) {
        var fp = Cc['@mozilla.org/filepicker;1'].createInstance(Ci.nsIFilePicker);
        fp.init(window.parent, _strings.getString('saveImageTo'), Ci.nsIFilePicker.modeSave);
        fp.defaultString = _strings.getString('AppcenterSnap') + '_' + (new Date()).toISOString() + '.png';
        fp.appendFilter(_strings.getString('pngImage'), '*.png');

        if (fp.show() != Ci.nsIFilePicker.returnCancel) {
            var file = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsILocalFile);
            var path = fp.file.path;
            file.initWithPath(path + (/\.png$/.test(path) ? '' : '.png'));

            var ios = Cc['@mozilla.org/network/io-service;1'].getService(Ci.nsIIOService);
            var source = ios.newURI(data, 'utf8', null);
            var target = ios.newFileURI(file);

            var persist = Cc['@mozilla.org/embedding/browser/nsWebBrowserPersist;1'].createInstance(Ci.nsIWebBrowserPersist);
            persist.persistFlags = Ci.nsIWebBrowserPersist.PERSIST_FLAGS_AUTODETECT_APPLY_CONVERSION;

            var transfer = Cc['@mozilla.org/transfer;1'].createInstance(Ci.nsITransfer);
            transfer.init(source, target, '', null, null, null, persist);
            persist.progressListener = transfer;

            persist.saveURI(source, null, null, null, null, file);
        }
    }

    ns.openSnapshotFeedback = function() {
        gBrowser.selectedTab = gBrowser.addTab('http://mozilla.com.cn/addon/107/?src=snapshotmenu');
    }

    window.addEventListener("load", function() {
        window.setTimeout(function() {
            ns.init();
        }, 1000);
        window.removeEventListener("load", arguments.callee, false);
    }, false);
})();
