// BEGIN FLOCK GPL
//
// Copyright Flock Inc. 2005-2009
// http://flock.com
//
// This file may be used under the terms 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 CC = Components.classes;
const CI = Components.interfaces;
const CR = Components.results;
const CU = Components.utils;

CU.import("resource:///modules/FlockXPCOMUtils.jsm");
FlockXPCOMUtils.debug = false;

const CLASS_NAME = "wordpress";
const CLASS_ID = Components.ID("{8bf9b147-5dc1-49d9-a26b-bfb00ef537fa}");
const CONTRACT_ID = "@flock.com/blog/service/wordpress;1";
const DESCRIPTION = "Wordpress";
const MODULE_NAME = "Wordpress API";

function loadLibraryFromSpec(aSpec) {
  var loader = CC["@mozilla.org/moz/jssubscript-loader;1"]
    .getService(CI.mozIJSSubScriptLoader);

  loader.loadSubScript(aSpec);
}


/**************************************************************************
 * Component: Wordpress API
 **************************************************************************/

function WordpressBlogAPI() {

  loadLibraryFromSpec("chrome://flock/content/blog/blogBackendLib.js");
  loadLibraryFromSpec("chrome://flock/content/xmlrpc/xmlrpchelper.js");

  // set attributes
  this.name = "Wordpress";
  this.shortName = "wordpress";
  this.description = "The Wordpress API"
  this.supportsCategories = CI.flockIBlogWebService.CATEGORIES_MULTIPLE;
  this.supportsPostReplace = true;
  this._setup();
}

/**************************************************************************
 * Wordpress API: XPCOM Component Creation
 **************************************************************************/

WordpressBlogAPI.prototype = new FlockXPCOMUtils.genericComponent(
  CLASS_NAME,
  CLASS_ID,
  CONTRACT_ID,
  WordpressBlogAPI,
  CI.nsIClassInfo.SINGLETON,
  [
    CI.flockICustomBlogWebService,
    CI.flockIBlogWebService,
    CI.flockIWebService
  ]
);

// FlockXPCOMUtils.genericModule() categories
WordpressBlogAPI.prototype._xpcom_categories = [
  { category: "app-startup" },
  {
    category: "flockICustomBlogWebService",
    entry: CLASS_NAME,
    value: CONTRACT_ID
  }
];

/**************************************************************************
 * Wordpress API: Private Data and Functions
 **************************************************************************/

WordpressBlogAPI.prototype._setup =
function wordpressapi__setup() {
  this._logger = CC["@flock.com/logger;1"].createInstance(CI.flockILogger);
  this._logger.init("wordpressapi");

  this._mtService = CC["@flock.com/blog/service/movabletype;1"]
                   .getService(CI.flockIBlogWebService);
}

/**************************************************************************
 * Wordpress API: flockICustomBlogWebService implementation
 **************************************************************************/

WordpressBlogAPI.prototype.detectAccount =
function WordpressBlogAPI_detectAccount(aUrl, aLinkList) {
  return { wrappedJSObject: null };
}

/**************************************************************************
 * Wordpress API: flockIBlogWebService implementation
 **************************************************************************/

WordpressBlogAPI.prototype.newPost =
function wordpressApi_newPost(aPublishListener,
                              aBlogId,
                              aPost,
                              aPublish,
                              aNotifications)
{
  var svc = this;

  var gBlogService = CC["@flock.com/flock-blog;1"]
                     .getService(CI.flockIBlogService);
  var account = gBlogService.getAccount(aBlogId).wrappedJSObject;

  var notifsArray = [];
  var tags = [];
  var html = aPost.description;
  if (aPost.tags) {
    while (aPost.tags.hasMore()) {
      tags.push(aPost.tags.getNext());
    }
  }
  if (aNotifications) {
    while (aNotifications.hasMore()) {
      notifsArray.push(aNotifications.getNext());
    }
  }

  var listener = {
    onResult: function newPost_listener_onResult(aResult) {
      svc.setPostCategories(aPublishListener, aBlogId, aResult, aPost.categories);
    },
    onError: function newPost_listener_onError(aFlockError) {
      svc._logger.error("ERROR " + aFlockError.serviceErrorString);
      aPublishListener.onError(aFlockError);
    },
    onFault: function newPost_listener_onFault(aFlockError) {
      svc.logger.error("FAULT " + aFlockError.serviceErrorCode
                       + " " + aFlockError.serviceErrorString);
      switch (aFlockError.serviceErrorCode) {
        case 0: // Invalid login/pass
          aFlockError.errorCode = CI.flockIError.BLOG_INVALID_AUTH;
          break;
        default: // Unknown error code
          aFlockError.errorCode = CI.flockIError.BLOG_UNKNOWN_ERROR;
      }
      aPublishListener.onFault(aFlockError);
    }
  };

  var xmlrpcServer = new flockXmlRpcServer(account.apiLink);
  var args = [account.blogid,
              account.username,
              account.password,
              {
                title: aPost.title,
                description: html,
                mt_keywords: tags,
                mt_convert_breaks: "1",
                mt_tb_ping_urls: notifsArray
              },
              aPublish];
  xmlrpcServer.call("metaWeblog.newPost", args, listener);
}

WordpressBlogAPI.prototype.editPost =
function wordpressApi_editPost(aPublishListener,
                               aBlogId,
                               aPost,
                               aPublish,
                               aNotifications)
{
  var svc = this;

  var gBlogService = CC["@flock.com/flock-blog;1"]
                     .getService(CI.flockIBlogService);
  var account = gBlogService.getAccount(aBlogId).wrappedJSObject;

  var listener = {
    onResult: function editPost_listener_onResult(aResult) {
      aPublishListener.onResult(aResult);
    },
    onError: function editPost_listener_onError(aFlockError) {
      svc._logger.error("ERROR " + aFlockError.serviceErrorString);
      aPublishListener.onError(aFlockError);
    },
    onFault: function editPost_listener_onFault(aFlockError) {
      svc.logger.error("FAULT " + aFlockError.serviceErrorCode
                       + " " + aFlockError.serviceErrorString);
      switch (aFlockError.serviceErrorCode) {
        case 0: // Invalid login/pass
          aFlockError.errorCode = CI.flockIError.BLOG_INVALID_AUTH;
          break;
        default: // Unknown error code
          aFlockError.errorCode = CI.flockIError.BLOG_UNKNOWN_ERROR;
      }
      aPublishListener.onFault(aFlockError);
    }
  };

  var notifsArray = [];
  while (aNotifications.hasMore()) {
    notifsArray.push(aNotifications.getNext());
  }

  var catArray = [];
  while (aPost.categories.hasMoreElements()) {
    var category = aPost.categories.getNext();
    category.QueryInterface(CI.flockIBlogCategory);
    catArray.push(category.label);
  }
  var tags = [];
  if (aPost.tags) {
    while (aPost.tags.hasMore()) {
      tags.push(aPost.tags.getNext());
    }
  }

  var xmlrpcServer = new flockXmlRpcServer (account.apiLink);
  var struct = {
    title: aPost.title,
    description: aPost.description,
    mt_keyworkds: tags,
    mt_convert_breaks: "1",
    mt_tb_ping_urls: notifsArray,
    categories: catArray
  };
  if (aPost.issued) {
    struct.dateCreated = new Date(parseInt(aPost.issued));
  }
  var args = [parseInt(aPost.postid),
              account.username,
              account.password,
              struct,
              aPublish];
  xmlrpcServer.call("metaWeblog.editPost", args, listener);}

WordpressBlogAPI.prototype.deletePost =
function WordpressBlogAPI_deletePost(aListener, aAccount, aPostid) {
  throw CR.NS_ERROR_NOT_IMPLEMENTED;
}

WordpressBlogAPI.prototype.setPostCategories =
function wordpressApi_setPostCategories(aPublishListener,
                                        aBlogId,
                                        aPostid,
                                        aCategories)
{
  this._mtService.setPostCategories(aPublishListener, aBlogId,
                                    aPostid, aCategories);
}

WordpressBlogAPI.prototype.getUsersBlogs =
function WordpressBlogAPI_getUsersBlogs(aBlogListener, aAPILink, aUsername, aPassword) {
  this._mtService.getUsersBlogs(aBlogListener, aAPILink, aUsername, aPassword);
}

WordpressBlogAPI.prototype.getRecentPosts =
function WordpressBlogAPI_getRecentPosts(aBlogListener, aBlogId, aNumber) {
  this._mtService.getRecentPosts(aBlogListener, aBlogId, aNumber);
}

WordpressBlogAPI.prototype.getCategoryList =
function WordpressBlogAPI_getCategoryList(aBlogListener, aBlogId) {
  this._mtService.getCategoryList(aBlogListener, aBlogId);
}

WordpressBlogAPI.prototype.removeAccount =
function WordpressBlogAPI_removeAccount(aId) {
  this._mtService.removeAccount(aId);
}

WordpressBlogAPI.prototype.getAccount =
function WordpressBlogAPI_getAccount(aId) {
  return this._mtService.getAccount(aId);
}


/**************************************************************************
 * XPCOM Support - Module Construction
 **************************************************************************/

// Create array of components.
var gComponentsArray = [WordpressBlogAPI];

// Generate a module for XPCOM to find.
var NSGetModule = FlockXPCOMUtils.generateNSGetModule(MODULE_NAME,
                                                      gComponentsArray);

/**************************************************************************
 * END XPCOM Support
 **************************************************************************/
