/* -*- 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 "nsIAbCollection.idl"
#include "nsIAbCard.idl"

interface nsISimpleEnumerator;
interface nsIArray;
interface nsIMutableArray;

/* moz-abdirectory:// is the URI to access nsAbBSDirectory,
 * which is the root directory for all types of address books
 * this is used to get all address book directories. */

%{C++
#define kAllDirectoryRoot          "moz-abdirectory://"

#define kPersonalAddressbook       "abook.mab"
#define kPersonalAddressbookUri    "moz-abmdbdirectory://abook.mab"
#define kCollectedAddressbook      "history.mab"
#define kCollectedAddressbookUri   "moz-abmdbdirectory://history.mab"

#define kABFileName_PreviousSuffix ".na2" /* final v2 address book format */
#define kABFileName_PreviousSuffixLen 4
#define kABFileName_CurrentSuffix ".mab"  /* v3 address book extension */
%}

/**
 * A top-level address book directory.
 *
 * Please note that in order to be properly instantiated by nsIAbManager, every
 * type of nsIAbDirectory must have a contract ID of the form:
 *
 * @mozilla.org/addressbook/directory;1?type=<AB URI Scheme>
 *
 * Where AB URI Scheme does not include the ://.  For example, for the Mork-based
 * address book, the scheme is "moz-abmdbdirectory", so the contract ID for
 * the Mork-based address book type is:
 *
 * @mozilla.org/addressbook/directory;1?type=moz-abmdbdirectory
 *
 * The UUID of an nsIAbDirectory is its preference ID and its name, concatenated
 * together.
 */
[scriptable, uuid(72dc868b-db5b-4daa-b6c6-071be4a05d02)]
interface nsIAbDirectory : nsIAbCollection {

  /**
   * The chrome URI to use for bringing up a dialog to edit this directory.
   * When opening the dialog, use a JS argument of
   * {selectedDirectory: thisdir} where thisdir is this directory that you just
   * got the chrome URI from.
   */
  readonly attribute ACString propertiesChromeURI;

  /**
   * The description of the directory. If this directory is not a mailing list,
   * then setting this attribute will send round a "DirName" update via
   * nsIAddrBookSession.
   */
  attribute AString dirName;

  // XXX This should really be replaced by a QI or something better
  readonly attribute long dirType;

  // eliminated a bit more.

  // The filename for address books within this directory.
  readonly attribute ACString fileName;

  // The URI of the address book
  readonly attribute ACString URI;

  // The position of the directory on the display.
  readonly attribute long position;

  // will be used for LDAP replication
  attribute unsigned long lastModifiedDate;

  // Defines whether this directory is a mail
  // list or not
  attribute boolean isMailList;

  // Get the children directories
  readonly attribute nsISimpleEnumerator childNodes;

  /**
   * Get the cards associated with the directory. This will return the cards
   * associated with the mailing lists too.
   */
  readonly attribute nsISimpleEnumerator childCards;

  /**
   * Returns true if this directory represents a query - i.e. the rdf resource
   * was something like moz-abmdbdirectory://abook.mab?....
   */
  readonly attribute boolean isQuery;

  /**
   * Initializes a directory, pointing to a particular
   * URI
   */
  void init(in string aURI);

  // Deletes either a mailing list or a top
  // level directory, which also updates the
  // preferences
  void deleteDirectory(in nsIAbDirectory directory);

  // Check if directory contains card
  // If the implementation is asynchronous the card
  // may not yet have arrived. If it is in the process
  // of obtaining cards the method will throw an
  // NS_ERROR_NOT_AVAILABLE exception if the card
  // cannot be found.
  boolean hasCard(in nsIAbCard cards);

  // Check if directory contains directory
  boolean hasDirectory(in nsIAbDirectory dir);

  /**
   * Adds a card to the database.
   *
   * This card does not need to be of the same type as the database, e.g., one
   * can add an nsIAbLDAPCard to an nsIAbMDBDirectory.
   *
   * @return "Real" card (eg nsIAbLDAPCard) that can be used for some
   *         extra functions.
   */
  nsIAbCard addCard(in nsIAbCard card);

  /**
   * Modifies a card in the database to match that supplied.
   */
  void modifyCard(in nsIAbCard modifiedCard);

  /**
   * Deletes the array of cards from the database.
   *
   * @param  aCards  The cards to delete from the database.
   */
  void deleteCards(in nsIArray aCards);

  void dropCard(in nsIAbCard card, in boolean needToCopyCard);

  /**
   * Whether or not the directory should be searched when doing autocomplete,
   * (currently by using GetChildCards); LDAP does not support this in online
   * mode, so that should return false; additionally any other directory types
   * that also do not support GetChildCards should return false.
   *
   * @param aIdentity  An optional parameter detailing the identity key (see
   *                   nsIMsgAccountManager) that this autocomplete is being
   *                   run against.
   * @return           True if this directory should/can be used during
   *                   local autocomplete.
   */
  boolean useForAutocomplete(in ACString aIdentityKey);

  /** 
   * Does this directory support mailing lists? Note that in the case
   * this directory is a mailing list and nested mailing lists are not
   * supported, this will return false rather than true which the parent
   * directory might.
   */
  readonly attribute boolean supportsMailingLists;

  /**
   * This attribute serves two purposes
   *  1. If this directory is not a mail list, directories are stored here
   *  2. If it is a mail list card entries are stored here
   *
   * @note This is a *live* array and not a static copy
   */
  attribute nsIMutableArray addressLists;

  // Specific to a directory which stores mail lists

  /**
   * Creates a new mailing list in the directory. Currently only supported 
   * for top-level directories.
   *
   * @param  list  The new mailing list to add.
   * @return The mailing list directory added, which may have been modified.
   */
  nsIAbDirectory addMailList(in nsIAbDirectory list);

  /**
   * Nick Name of the mailing list. This attribute is only really used when
   * the nsIAbDirectory represents a mailing list.
   */
  attribute AString listNickName;

  /**
   * Description of the mailing list. This attribute is only really used when
   * the nsIAbDirectory represents a mailing list.
   */
  attribute AString description;

  /**
   * Edits an existing mailing list (specified as listCard) into its parent
   * directory. You should call this function on the resource with the same
   * uri as the listCard.
   *
   * @param  listCard  A nsIAbCard version of the mailing list with the new
   *                   values.
   */
  void editMailListToDatabase(in nsIAbCard listCard);

  // Copies mail list properties from the srcList
  void copyMailList(in nsIAbDirectory srcList);

  /**
   * Only creates a top level address book
   * which is stored in the preferences
   *
   * Need to change to factory based approach
   * to create new address books
   *
   * This method should become redundant or 
   * be only associated with card folders
   *
   * The parameters are the same as for
   * nsIAbManager::newAddressBook
   */
  ACString createNewDirectory(in AString aDirName, in ACString aURI,
                              in unsigned long aType, in ACString aPrefName);

  /* create a directory by passing the display name and address book uri */
  void createDirectoryByURI(in AString displayName, in ACString aURI);

  /**
   * The id of the directory used in prefs e.g. "ldap_2.servers.pab"
   * Setting this will cause directoryPrefs to be updated.
   */
  attribute ACString dirPrefId;

  /**
   * @name  getXXXValue
   *
   * Helper functions to get different types of pref, but return a default
   * value if a pref value was not obtained.
   *
   * @param aName         The name of the pref within the branch dirPrefId to
   *                      get a value from.
   *
   * @param aDefaultValue The default value to return if getting the pref fails
   *                      or the pref is not present.
   *
   * @return              The value of the pref or the default value.
   *
   * @exception           NS_ERROR_NOT_INITIALIZED if the pref branch couldn't
   *                      be obtained (e.g. dirPrefId isn't set).
   */
  //@{
  long getIntValue(in string aName, in long aDefaultValue);
  boolean getBoolValue(in string aName, in boolean aDefaultValue);
  ACString getStringValue(in string aName, in ACString aDefaultValue);
  AUTF8String getLocalizedStringValue(in string aName, in AUTF8String aDefaultValue);
  //@}

  /**
   * The following attributes are read from an nsIAbDirectory via the above methods:
   *
   * HidesRecipients (Boolean)
   *    If true, and this nsIAbDirectory is a mailing list, then when sending mail to
   *    this list, recipients addresses will be hidden from one another by sending
   *    via BCC.
   */

  /**
   * @name  setXXXValue
   *
   * Helper functions to set different types of pref values.
   *
   * @param aName         The name of the pref within the branch dirPrefId to
   *                      get a value from.
   *
   * @param aValue        The value to set the pref to.
   *
   * @exception           NS_ERROR_NOT_INITIALIZED if the pref branch couldn't
   *                      be obtained (e.g. dirPrefId isn't set).
   */
  //@{
  void setIntValue(in string aName, in long aValue);
  void setBoolValue(in string aName, in boolean aValue);
  void setStringValue(in string aName, in ACString aValue);
  void setLocalizedStringValue(in string aName, in AUTF8String aValue);
  //@}

};
