//
// BEGIN FLOCK GPL
// 
// Copyright Flock Inc. 2005-2006
// http://flock.com
// 
// This file may be used under the terms of of the
// GNU General Public License Version 2 or later (the "GPL"),
// http://www.gnu.org/licenses/gpl.html
// 
// Software distributed under the License is distributed on an "AS IS" basis,
// WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
// for the specific language governing rights and limitations under the
// License.
// 
// END FLOCK GPL
//

const DEBUG = true; /* set to false to suppress debug messages */

const FLOCK_FEED_UTILITY_CONTRACTID = '@flock.com/feed-utility;1';
const FLOCK_FEED_UTILITY_CID        = Components.ID('1b25dd36-912d-4a3b-bb64-cadaa71a39b7}');
const flockIFeedUtility             = Components.interfaces.flockIFeedUtility;

const nsISupports                   = Components.interfaces.nsISupports;
const nsIClassInfo                  = Components.interfaces.nsIClassInfo;

const flockIFeedService             = Components.interfaces.flockIFeedService;

const FEED_SERVICE_CONTRACTID       = '@flock.com/feed-service;1';

const RATE_LIMIT_NUM                = 10;
const RATE_LIMIT_EXPIRE             = 10 * 1000;

// Service implementation
function flockFeedUtility()
{
    debug("Constructed");

    this.feedsvc = Components.classes[FEED_SERVICE_CONTRACTID]
        .getService(flockIFeedService);

    this.subscribeInvokeNum = 0;
    this.subscribeLastRan = 0;

    this.blogInvokeNum = 0;
    this.blogLastRan = 0;
}

flockFeedUtility.prototype.markRead =
function (url, id)
{
    this.feedsvc.markRead(url, id);
}

flockFeedUtility.prototype.markUnread =
function (url, id)
{
    this.feedsvc.markUnread(url, id);
}

flockFeedUtility.prototype.markAllRead =
function (urn)
{
    this.feedsvc.markAllRead(urn);
}

flockFeedUtility.prototype.markAllUnread =
function (urn)
{
    this.feedsvc.markAllUnread(urn);
}

flockFeedUtility.prototype.flagPost =
function (url, id)
{
    this.feedsvc.flagPost(url, id);
}

flockFeedUtility.prototype.blogThis =
function (url, title, content, alwaysRaised)
{
    var now = Date.now();
    if (now - this.blogLastRan > RATE_LIMIT_EXPIRE) {
        this.blogInvokeNum = 0;
        this.blogLastRan = now;
    }
    this.blogInvokeNum++;
    if (this.blogInvokeNum > RATE_LIMIT_NUM)
        throw "Invoking blog editor too often";

	var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService(Components.interfaces.nsIWindowMediator);
	var window = wm.getMostRecentWindow("navigator:browser");
	var aParams = {file: 0, title: title, content: "<a href=\"" + url + "\">" + title + "</a><p>" + content + "</p>"};
	if (alwaysRaised) {
		window.openDialog("chrome://browser/content/flock/blog/editor.xul", "_blank", "chrome,close,titlebar,resizable=yes,toolbar=no,dialog=no,scrollbars=yes,alwaysRaised=1,centerscreen", aParams);
	} else {
		window.openDialog("chrome://browser/content/flock/blog/editor.xul", "_blank", "chrome,close,titlebar,resizable=yes,toolbar=no,dialog=no,scrollbars=yes,centerscreen", aParams);
	}
}

flockFeedUtility.prototype.unflagPost =
function (url, id)
{
    this.feedsvc.unflagPost(url, id);
}

flockFeedUtility.prototype.subscribeFeed =
function (url)
{
    var now = Date.now();
    if (now - this.subscribeLastRan > RATE_LIMIT_EXPIRE) {
        this.subscribeInvokeNum = 0;
        this.subscribeLastRan = now;
    }
    this.subscribeInvokeNum++;
    if (this.subscribeInvokeNum > RATE_LIMIT_NUM)
        throw "Subscribing too often";
    this.feedsvc.subscribeFeed(url, null, 0, false);
}

flockFeedUtility.prototype.setDefaultStyle =
function (urn, style)
{
    this.feedsvc.setDefaultStyle(urn, style);
}

flockFeedUtility.prototype.setDefaultColumns =
function (columns)
{
    this.feedsvc.setDefaultColumns(columns);
}

flockFeedUtility.prototype.setShowUnread =
function (show)
{
    this.feedsvc.setShowUnread(show);
}

flockFeedUtility.prototype.setShowRead =
function (show)
{
    this.feedsvc.setShowRead(show);
}

flockFeedUtility.prototype.setShowFlagged =
function (show)
{
    this.feedsvc.setShowFlagged(show);
}

flockFeedUtility.prototype.handleContentMessage =
function (obj)
{
    try {
        var doc = obj.window.document;
        var url = doc.location.href;
        if (url.indexOf('feed:') != 0 && url.indexOf('feeds:') != 0 &&
            url.indexOf('opml:') != 0)
            return;
    } catch (e) {
        return;
    }

    debug("handling " + obj.method);

    switch (obj.method) {
        case 'markRead':
            this.markRead(obj.url, obj.id);
            break;

        case 'markUnread':
            this.markUnread(obj.url, obj.id);
            break;

        case 'markAllRead':
            this.markAllRead(obj.urn);
            break;

        case 'markAllUnread':
            this.markAllUnread(obj.urn);
            break;

        case 'flagPost':
            this.flagPost(obj.url, obj.id);
            break;

        case 'unflagPost':
            this.unflagPost(obj.url, obj.id);
            break;

        case 'blogThis':
            this.blogThis(obj.url, obj.title, obj.content, obj.alwaysRaised);
            break;

        case 'subscribeFeed':
            this.subscribeFeed(url);
            break;

        case 'setDefaultStyle':
            this.setDefaultStyle(obj.urn, obj.style);
            break;

        case 'setDefaultColumns':
            this.setDefaultColumns(obj.columns);
            break;

        case 'setShowUnread':
            this.setShowUnread(obj.show);
            break;

        case 'setShowRead':
            this.setShowRead(obj.show);
            break;

        case 'setShowFlagged':
            this.setShowFlagged(obj.show);
            break;
    }
}

// the nsIClassInfo implementation
flockFeedUtility.prototype.flags = nsIClassInfo.SINGLETON;
flockFeedUtility.prototype.classDescription = "Flock Feed Utility";
flockFeedUtility.prototype.getInterfaces =
function (count)
{
    var interfaceList = [flockIFeedUtility, nsIClassInfo];
    count.value = interfaceList.length;
    return interfaceList;
}

flockFeedUtility.prototype.getHelperForLanguage =
function (language)
{
    return null;
}

// the nsISupports implementation
flockFeedUtility.prototype.QueryInterface =
function (iid)
{
    if (!iid.equals(flockIFeedUtility) &&
        !iid.equals(nsIClassInfo) &&
        !iid.equals(nsISupports))
        throw Components.results.NS_ERROR_NO_INTERFACE;
    return this;
}

// Module implementation
var utilityModule = new Object();

utilityModule.registerSelf =
function (compMgr, fileSpec, location, type)
{
    compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);

    compMgr.registerFactoryLocation(FLOCK_FEED_UTILITY_CID,
                                    "Flock Feed Utility JS Component",
                                     FLOCK_FEED_UTILITY_CONTRACTID,
                                     fileSpec,
                                     location,
                                     type);
}

utilityModule.getClassObject =
function (compMgr, cid, iid)
{
    if (!cid.equals(FLOCK_FEED_UTILITY_CID))
        return Components.results.NS_ERROR_NO_INTERFACE;

    if (!iid.equals(Components.interfaces.nsIFactory))
        throw Components.results.NS_ERROR_NOT_IMPLEMENTED;

    return feedUtilityFactory;
}

utilityModule.canUnload =
function(compMgr)
{
    debug("Unloading feed utility component.");
    return true;
}

/* entrypoint */
function NSGetModule(compMgr, fileSpec)
{
    return utilityModule;
}

var feedUtilityFactory = new Object();

feedUtilityFactory.createInstance =
function (outer, iid)
{
    debug("CI: " + iid);

    if (outer != null)
        throw Components.results.NS_ERROR_NO_AGGREGATION;

    return (new flockFeedUtility()).QueryInterface(iid)
}

if (DEBUG) {
    var builtin_debug = debug;
    var debug = function (s) {
        builtin_debug("-*- flockFeedUtility: " + s + "\n");
    }
} else {
    var debug = function (s) {}
}
