//
// BEGIN FLOCK GPL
//
// Copyright Flock Inc. 2005-2008
// 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;

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

const MODULE_NAME = "Flock People Utils";

// People Utils
const FLOCK_PEOPLE_UTILS_CLASS_NAME = "Flock People Utils";
const FLOCK_PEOPLE_UTILS_CLASS_ID =
        Components.ID("{242d79d2-41d6-4a11-8949-7e4017ff7ef7}");
const FLOCK_PEOPLE_UTILS_CONTRACT_ID = "@flock.com/people-utils;1";

// Person
const FLOCK_PERSON_CLASS_NAME = "Flock Person";
const FLOCK_PERSON_CLASS_ID =
        Components.ID("{8c7b2681-b315-4c1b-b8dc-4d3d0fba003a}");
const FLOCK_PERSON_CONTRACT_ID = "@flock.com/person;1";


/**************************************************************************
 * Component: Flock People Utils
 **************************************************************************/

// Constructor.
function flockPeopleUtils() {
  this._coop = CC["@flock.com/singleton;1"]
               .getService(CI.flockISingleton)
               .getSingleton("chrome://flock/content/common/load-faves-coop.js")
               .wrappedJSObject;
  this._logger = CC["@flock.com/logger;1"]
                 .createInstance(CI.flockILogger);
  this._logger.init("peopleutils");
}

/**************************************************************************
 * Flock People Utils: XPCOM Component Creation
 **************************************************************************/

flockPeopleUtils.prototype = new FlockXPCOMUtils.genericComponent(
  FLOCK_PEOPLE_UTILS_CLASS_NAME,
  FLOCK_PEOPLE_UTILS_CLASS_ID,
  FLOCK_PEOPLE_UTILS_CONTRACT_ID,
  flockPeopleUtils,
  CI.nsIClassInfo.SINGLETON,
  [
    CI.flockIPeopleUtils,
  ]
);

/**************************************************************************
 * Flock People Utils: Private Data and Functions
 **************************************************************************/

flockPeopleUtils.prototype._getIdentityUrn =
function flockPeopleUtils__getIdentityUrn(aCoopAccount, aPersonId) {
  var coopService = aCoopAccount.service;
  var result = "urn:flock:identity:"
             + coopService.name.toLowerCase() + ":"
             + aCoopAccount.accountId + ":"
             + aPersonId;

  return result;
}

/**************************************************************************
 * Flock People Utils: flockIPeopleUtils Implementation
 **************************************************************************/

flockPeopleUtils.prototype.addPerson =
function flockFacebookService_addPerson(aAccount, aPerson) {
  var person = aPerson;

  var coopAccount = this._coop.get(aAccount.urn);
  var coopService = coopAccount.service;

  // We include the current accountId in the identity urn to prevent friend
  // collisions if multiple accounts on the same service have the same friend.
  var identityUrn = this._getIdentityUrn(coopAccount, aPerson.accountId);
  var updating = this._coop.Identity.exists(identityUrn);
  var identity;

  if (updating) {
    // update data of the identity coop obj here
    identity = this._coop.get(identityUrn);
    if (person.lastUpdate > identity.lastUpdate) {
      identity.lastUpdate = person.lastUpdate;
      identity.lastUpdateType = person.lastUpdateType;
      identity.name = person.name;
      identity.avatar = person.avatar;
      identity.statusMessage = person.statusMessage;
      identity.URL = person.profileURL;
      identity.screenName = person.screenName;
    }
  } else {
    identity = new this._coop.Identity(
      identityUrn,
      {
        name: person.name,
        serviceId: coopService.serviceId,
        accountId: person.accountId,
        avatar: person.avatar,
        statusMessage: person.statusMessage,
        lastUpdate: person.lastUpdate,
        lastUpdateType: person.lastUpdateType,
        URL: person.profileURL,
        screenName: person.screenName
      }
    );
    if (!coopAccount.friendsList) {
      this.createFriendsList(aAccount.urn);
    }
    coopAccount.friendsList.children.add(identity);
  }

  return identityUrn;
}

flockPeopleUtils.prototype.removePerson =
function flockPeopleUtils_removePerson(aAccount, aPerson) {
  var coopAccount = this._coop.get(aAccount.urn);
  var identityUrn = this._getIdentityUrn(coopAccount, aPerson.accountId);

  if (this._coop.Identity.exists(identityUrn)) {
    var coopIdentity = this._coop.get(identityUrn);
    coopIdentity.destroy();
  } else {
    this._logger.error("Can't remove "
                       + identityUrn
                       + ": it doesn't exist!");
  }
}

flockPeopleUtils.prototype.getPerson =
function flockPeopleUtils_getPerson(aPersonUrn) {
   this._logger.info("getPerson('"+ aPersonUrn + "')");
   
  var person = null;
  if (this._coop.Identity.exists(aPersonUrn)) {
    var coopPerson = this._coop.get(aPersonUrn);
    person = CC["@flock.com/person;1"]
               .createInstance(CI.flockIPerson);
    person.accountId = coopPerson.accountId;
    person.lastUpdate = coopPerson.lastUpdate;
    person.lastUpdateType = coopPerson.lastUpdateType;
    person.name = coopPerson.name;
    person.avatar = coopPerson.avatar;
    person.statusMessage = coopPerson.statusMessage;
    person.profileURL = coopPerson.URL;
    person.screenName = coopPerson.screenName;
  }
  return person;
}

flockPeopleUtils.prototype.incrementMedia =
function flockPeopleUtils_incrementMedia(aAccount,
                                         aPersonId,
                                         aCount,
                                         aLatest)
{
  // Update the count on the identity...
  aCoopAccount = this._coop.get(aAccount.urn);
  var identityUrn = this._getIdentityUrn(aCoopAccount, aPersonId);
  var coopIdentity = this._coop.get(identityUrn);
  coopIdentity.unseenMedia += aCount;

  // + 10 explanation: when the friend uploads a new photo, Facebook
  // updates the profile update time a few seconds after the photo upload.
  // We want that to show as a "media" update, not as a "profile" update
  if ((aLatest + 10) >= coopIdentity.lastUpdate) {
    coopIdentity.lastUpdate = new Date(aLatest);
    coopIdentity.lastUpdateType = "media";
  }
}

flockPeopleUtils.prototype.lightPeopleIcon =
function flockPeopleUtils_lightPeopleIcon() {
  this._logger.debug(".lightPeopleIcon()");

  var obs = CC["@mozilla.org/observer-service;1"]
            .getService(CI.nsIObserverService);
  obs.notifyObservers(null, "new-people-notification", null);
}


/**************************************************************************
 * END Flock People Utils
 **************************************************************************/


/**************************************************************************
 * BEGIN Flock Person
 **************************************************************************/

// Constructor.
function flockPerson() {
}

/**************************************************************************
 * Flock Person: XPCOM Component Creation
 **************************************************************************/

flockPerson.prototype = new FlockXPCOMUtils.genericComponent(
  FLOCK_PERSON_CLASS_NAME,
  FLOCK_PERSON_CLASS_ID,
  FLOCK_PERSON_CONTRACT_ID,
  flockPerson,
  CI.nsIClassInfo.SINGLETON,
  [
    CI.flockIPerson,
  ]
);

flockPerson.prototype.urn = "";
flockPerson.prototype.serviceId = "";
flockPerson.prototype.accountId = "";
flockPerson.prototype.avatar = "";
flockPerson.prototype.name = "";
flockPerson.prototype.statusMessage = "";
flockPerson.prototype.lastUpdate = 0;
flockPerson.prototype.lastUpdateType = "";
flockPerson.prototype.unseenMedia = 0;
flockPerson.prototype.lastUploadedMedia = 0;
flockPerson.prototype.profileURL = "";
flockPerson.prototype.screenName = "";

/**************************************************************************
 * END Flock Person
 **************************************************************************/


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

// Create array of components.
var gComponentsArray = [flockPeopleUtils, flockPerson];

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

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