/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "nsIAbItem.idl"

interface nsISimpleEnumerator;
interface nsIVariant;

[scriptable, uuid(97448252-F189-11d4-A422-001083003D0C)]
interface nsIAbPreferMailFormat {
    const unsigned long unknown   = 0;
    const unsigned long plaintext = 1;
    const unsigned long html      = 2;
};

/**
 * An interface representing an address book card.
 *
 * The UUID of a card is a composition of a directory ID and a per-directory ID.
 * The per-directory ID is reflected in the localId property. If either of these
 * properties change, the UUID will change correspondingly.
 *
 * None of these IDs will be reflected in the property collection. Neither
 * nsIAbCard::properties, nsIAbCard::deleteProperty, nor any of the property
 * getters and setters are able to interact with these properties.
 *
 * Fundamentally, a card is a collection of properties. Modifying a property in
 * some way on a card does not change the backend used to store the card; the
 * directory is required to do make the changes here.
 *
 * The following are the core properties that are used:
 * - Names:
 *   - FirstName, LastName
 *   - PhoneticFirstName, PhoneticLastName
 *   - DisplayName, NickName
 *   - SpouseName, FamilyName
 * - PrimaryEmail, SecondEmail
 * - Home Contact:
 *   - HomeAddress, HomeAddress2, HomeCity, HomeState, HomeZipCode, HomeCountry
 *   - HomePhone, HomePhoneType
 * - Work contact. Same as home, but with `Work' instead of `Home'
 * - Other Contact:
 *   - FaxNumber, FaxNumberType
 *   - PagerNumber, PagerNumberType
 *   - CellularNumber, CellularNumberType
 * - JobTitle, Department, Company
 * - _AimScreenName
 * - Dates:
 *   - AnniversaryYear, AnniversaryMonth, AnniversaryDay
 *   - BirthYear, BirthMonth, BirthDay
 * - WebPage1 (work), WebPage2 (home)
 * - Custom1, Custom2, Custom3, Custom4
 * - Notes
 * - Integral properties:
 *   - LastModifiedDate
 *   - PopularityIndex
 *   - PreferMailFormat (see nsIAbPreferMailFormat)
 * - Photo properties:
 *   - PhotoName
 *   - PhotoType
 *   - PhotoURI
 *
 * The contract id for the standard implementation is
 * <tt>\@mozilla.org/addressbook/cardproperty;1</tt>.
 */
[scriptable, uuid(9bddf024-5178-4097-894e-d84b4ddde101)]
interface nsIAbCard : nsIAbItem {
  /**
   * The UUID for the nsIAbDirectory containing this card.
   *
   * The directory considered to contain this card is the directory which
   * produced this card (e.g., through nsIAbDirectory::getCardForProperty) or
   * the last directory to modify this card, if another directory did so. If the
   * last directory to modify this card deleted it, then this card is considered
   * unassociated.
   *
   * If this card is not associated with a directory, this string will be empty.
   *
   * There is no standardized way to associate a card with multiple directories.
   *
   * Consumers of this interface outside of directory implementations SHOULD
   * NOT, in general, modify this property.
   */
  attribute AUTF8String directoryId;

  /**
   * The per-directory ID of this card.
   *
   * This property is the second part of the tuple logically representing a card
   * UUID. It shares many requirements with that of nsIAbItem::uuid. In
   * particular:
   * - It MUST be unique (within the scope of its directory).
   * - The empty string MUST only be used to indicate that it has not yet been
   *   assigned a localId.
   * - It is STRONGLY RECOMMENDED that this id is consistent across sessions and
   *   that, should the card be deleted, its ids will not be reused.
   * - The format of localId is left undefined.
   *
   * As long as directoryId is not changed, this property SHOULD NOT be changed.
   * If directoryId is changed, the new directory MAY choose to reuse the same
   * localId if reasonable. However, consumers MUST NOT assume that two cards
   * with different directoryIds but the same localId are logically the same
   * card.
   *
   * Similar to directoryId, consumers of cards outside of directory
   * implementations SHOULD NOT, in general, modify this property.
   */
  attribute AUTF8String localId;

  /**
   * A list of all the properties that this card has as an enumerator, whose
   * members are all nsIProperty objects.
   */
  readonly attribute nsISimpleEnumerator properties;

  /**
   * Returns a property for the given name.
   *
   * @param name             The case-sensitive name of the property to get.
   * @param defaultValue     The value to return if the property does not exist.
   * @exception NS_ERROR_NOT_AVAILABLE if the named property does not exist.
   * @exception NS_ERROR_CANNOT_CONVERT_DATA if the property cannot be converted
   *                                         to the desired type.
   */
  nsIVariant getProperty(in AUTF8String name, in nsIVariant defaultValue);
  /**
   * @{
   * Returns a property for the given name.  Javascript callers should NOT use these,
   * but use getProperty instead. XPConnect will do the type conversion automagically.
   *
   * These functions convert values in the same manner as the default
   * implementation of nsIVariant. Of particular note is that boolean variables
   * are converted to integers as in C/C++ (true is a non-zero value), so that
   * false will be converted to a string of "0" and not "false."
   *
   *
   * @param name             The case-sensitive name of the property to get.
   * @exception NS_ERROR_NOT_AVAILABLE if the named property does not exist.
   * @exception NS_ERROR_CANNOT_CONVERT_DATA if the property cannot be converted
   *                                         to the desired type.
   */
  AString getPropertyAsAString(in string name);
  AUTF8String getPropertyAsAUTF8String(in string name);
  unsigned long getPropertyAsUint32(in string name);
  boolean getPropertyAsBool(in string name);

  /** @} */

  /**
   * Assigns the given to value to the property of the given name.
   *
   * Should the property exist, its value will be overwritten. An
   * implementation may impose additional semantic constraints for certain
   * properties. However, such constraints might not be checked by this method.
   *
   * @warning A value MUST be convertible to a string; if this convention is not
   * followed, consumers of cards may fail unpredictably or return incorrect
   * results.
   *
   * @param name             The case-sensitive name of the property to set.
   * @param value            The new value of the property.
   */
  void setProperty(in AUTF8String name, in nsIVariant value);

  /**
   * @{
   * Sets a property for the given name.  Javascript callers should NOT use these,
   * but use setProperty instead. XPConnect will do the type conversion automagically.
   *
   * These functions convert values in the same manner as the default
   * implementation of nsIVariant.
   */
  void setPropertyAsAString(in string name, in AString value);
  void setPropertyAsAUTF8String(in string name, in AUTF8String value);
  void setPropertyAsUint32(in string name, in unsigned long value);
  void setPropertyAsBool(in string name, in boolean value);

  /** @} */

  /**
   * Deletes the property with the given name.
   *
   * Some properties may not be deleted. However, the implementation will not
   * check this constraint at this method. If such a property is deleted, an
   * error may be thrown when the card is modified at the database level.
   *
   * @param name             The case-sensitive name of the property to set.
   */
  void deleteProperty(in AUTF8String name);
 
  /**
   * @{
   * These properties are shorthand for getProperty and setProperty.
   */
  attribute AString firstName;
  attribute AString lastName;
  attribute AString displayName;
  attribute AString primaryEmail;
  /** @} */

  /**
   * Determines whether or not a card has the supplied email address in either
   * of its PrimaryEmail or SecondEmail attributes.
   *
   * Note: This function is likely to be temporary whilst we work out proper
   * APIs for multi-valued attributes in bug 118665.
   *
   * @param  aEmailAddress The email address to attempt to match against.
   * @return               True if aEmailAddress matches any of the email
   *                       addresses stored in the card.
   */
  boolean hasEmailAddress(in AUTF8String aEmailAddress);

  /**
   * Translates a card into a specific format.
   * The following types are supported:
   * - base64xml
   * - xml
   * - vcard
   *
   * @param  aType          The type of item to translate the card into.
   * @return                A string containing the translated card.
   * @exception NS_ERROR_ILLEGAL_VALUE if we do not recognize the type.
   */
  AUTF8String translateTo(in AUTF8String aType);

  /**
   * Translates a card from the specified format
   */
  //void translateFrom(in AUTF8String aType, in AUTF8String aData);

  /** 
   * Generate a phonetic name from the card, using the firstName and lastName
   * values.
   *
   * @param  aLastNameFirst  Set to True to put the last name before the first.
   * @return                 A string containing the generated phonetic name.
   */
  AString generatePhoneticName(in boolean aLastNameFirst);

  /**
   * Generate a chat name from the card, containing the value of the
   * first non-empty chat field.
   *
   * @return                 A string containing the generated chat name.
   */
  AString generateChatName();

  /**
   * This function will copy all values from one card to another.
   *
   * @param  srcCard         The source card to copy values from.
   */
  void copy(in nsIAbCard aSrcCard);

  /**
   * Returns true if this card is equal to the other card.
   *
   * The default implementation defines equal as this card pointing to the
   * same object as @arg aCard; another implementation defines it as equality of
   * properties and values.
   *
   * @warning The exact nature of equality is still undefined, and actual
   *          results may not match theoretical results. Most notably, the code
   *          <tt>a.equals(b) == b.equals(a)</tt> might not return true. In
   *          particular, calling equals on cards from different address books
   *          may return inaccurate results.
   *          
   *
   * @return                 Equality, as defined above.
   * @param  aCard           The card to compare against.
   */
  boolean equals(in nsIAbCard aCard);

  // PROPERTIES TO BE DELETED AS PART OF REWRITE

  attribute boolean isMailList;
  /**
   * If isMailList is true then mailListURI
   * will contain the URI of the associated
   * mail list
   */
  attribute string mailListURI;
};

%{C++
// A nice list of properties for the benefit of C++ clients
#define kFirstNameProperty          "FirstName"
#define kLastNameProperty           "LastName"
#define kDisplayNameProperty        "DisplayName"
#define kNicknameProperty           "NickName"
#define kPriEmailProperty           "PrimaryEmail"
#define kPreferMailFormatProperty   "PreferMailFormat"
#define kLastModifiedDateProperty   "LastModifiedDate"
#define kPopularityIndexProperty    "PopularityIndex"

#define kPhoneticFirstNameProperty  "PhoneticFirstName"
#define kPhoneticLastNameProperty   "PhoneticLastName"
#define kSpouseNameProperty         "SpouseName"
#define kFamilyNameProperty         "FamilyName"
#define k2ndEmailProperty           "SecondEmail"

#define kHomeAddressProperty        "HomeAddress"
#define kHomeAddress2Property       "HomeAddress2"
#define kHomeCityProperty           "HomeCity"
#define kHomeStateProperty          "HomeState"
#define kHomeZipCodeProperty        "HomeZipCode"
#define kHomeCountryProperty        "HomeCountry"
#define kHomeWebPageProperty        "WebPage2"

#define kWorkAddressProperty        "WorkAddress"
#define kWorkAddress2Property       "WorkAddress2"
#define kWorkCityProperty           "WorkCity"
#define kWorkStateProperty          "WorkState"
#define kWorkZipCodeProperty        "WorkZipCode"
#define kWorkCountryProperty        "WorkCountry"
#define kWorkWebPageProperty        "WebPage1"

#define kHomePhoneProperty          "HomePhone"
#define kHomePhoneTypeProperty      "HomePhoneType"
#define kWorkPhoneProperty          "WorkPhone"
#define kWorkPhoneTypeProperty      "WorkPhoneType"
#define kFaxProperty                "FaxNumber"
#define kFaxTypeProperty            "FaxNumberType"
#define kPagerTypeProperty          "PagerNumberType"
#define kPagerProperty              "PagerNumber"
#define kCellularProperty           "CellularNumber"
#define kCellularTypeProperty       "CellularNumberType"

#define kJobTitleProperty           "JobTitle"
#define kDepartmentProperty         "Department"
#define kCompanyProperty            "Company"
#define kScreenNameProperty         "_AimScreenName"
#define kCustom1Property            "Custom1"
#define kCustom2Property            "Custom2"
#define kCustom3Property            "Custom3"
#define kCustom4Property            "Custom4"
#define kNotesProperty              "Notes"

#define kGtalkProperty              "_GoogleTalk"
#define kAIMProperty                "_AimScreenName"
#define kYahooProperty              "_Yahoo"
#define kSkypeProperty              "_Skype"
#define kQQProperty                 "_QQ"
#define kMSNProperty                "_MSN"
#define kICQProperty                "_ICQ"
#define kXMPPProperty               "_JabberId"
#define kIRCProperty                "_IRC"

#define kAnniversaryYearProperty    "AnniversaryYear"
#define kAnniversaryMonthProperty   "AnniversaryMonth"
#define kAnniversaryDayProperty     "AnniversaryDay"
#define kBirthYearProperty          "BirthYear"
#define kBirthMonthProperty         "BirthMonth"
#define kBirthDayProperty           "BirthDay"
%}
