/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * 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.
 *
 * The Original Code is mozilla.org code.
 *
 * The Initial Developer of the Original Code is
 * Netscape Communications Corporation.
 * Portions created by the Initial Developer are Copyright (C) 1998
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Seth Spitzer <sspitzer@netscape.com>
 *   Mark Banner <mark@standard8.demon.co.uk>
 *   Joshua Cranmer <Pidgeot18@gmail.com>
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either of the GNU General Public License Version 2 or later (the "GPL"),
 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */
 
#include "nsIAbCollection.idl"
#include "nsIAbCard.idl"

interface nsISimpleEnumerator;
interface nsIArray;
interface nsIMutableArray;

%{C++
/* RDF root for all types of address books */
/* use this to get all directories, create new directory*/
#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.
 *
 * The UUID of an nsIAbDirectory is its preference ID and its name, concatenated
 * together.
 */
[scriptable, uuid(1f11f37e-7009-4a51-bbb1-041e9f75120a)]
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 RDF resource 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 PRBool 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;

  // 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.
   */
  void 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);
  //@}

  /**
   * @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);
  //@}
};
