/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Netscape 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/NPL/
 *
 * 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) 1999
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either 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 NPL, 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 NPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#include "nsISupports.idl"
#include "MailNewsTypes2.idl"
#include "nsIDBChangeAnnouncer.idl"
#include "nsIMsgDBView.idl"

%{C++
#include "nsMsgKeyArray.h"
%}

interface nsIFileSpec;
interface nsIDBChangeListener;
interface nsIMsgDBHdr;
interface nsISimpleEnumerator;
interface nsIMsgThread;
interface nsIDBFolderInfo;
interface nsIMsgOfflineImapOperation;
interface nsIMsgFolder;
interface nsIOFileStream;

[ptr] native octetPtr(PRUint8);

typedef unsigned long nsMsgRetainByPreference;


[scriptable, uuid(063bd2ac-de85-11d4-a5b6-0060b0fc04b7)]

interface nsIMsgRetentionSettings : nsISupports
{
	const unsigned long nsMsgRetainAll = 1;
	const unsigned long nsMsgRetainByAge = 2;
	const unsigned long nsMsgRetainByNumHeaders = 3;

  attribute boolean useServerDefaults;
  attribute nsMsgRetainByPreference retainByPreference;
  attribute unsigned long daysToKeepHdrs;
  attribute unsigned long numHeadersToKeep; 

  // this is orthogonal to retaining by age or num headers, i.e., if
  // it's set, we'll only keep NNN unread messages only, or unread
  // messages less than NNN days old.
  attribute boolean keepUnreadMessagesOnly;
  // this is for keeping offline bodies.
  attribute boolean cleanupBodiesByDays;
  attribute unsigned long daysToKeepBodies;
}; 

[scriptable, uuid(86a9da90-14f1-11d5-a5c0-0060b0fc04b7)]
interface nsIMsgDownloadSettings : nsISupports
{
  attribute boolean useServerDefaults;
  attribute boolean downloadByDate;
	attribute boolean downloadUnreadOnly;
	attribute unsigned long ageLimitOfMsgsToDownload;
};

typedef long nsMsgDBCommit;

[scriptable, uuid(aa4d45d0-3956-11d3-8d76-00805f8a6617)]

interface nsMsgDBCommitType 
{
  const long kSmallCommit = 0;
  const long kLargeCommit = 1;
  const long kSessionCommit = 2;
  const long kCompressCommit = 3;
};

[ref] native nsMsgKeyArrayRef(nsMsgKeyArray);
[ptr] native nsMsgKeyArrayPtr(nsMsgKeyArray);

[scriptable, uuid(9188bc83-f92e-11d2-81ef-0060083a0bcf)]

interface  nsIMsgDatabase : nsIDBChangeAnnouncer {
  nsIMsgDatabase Open(in nsIFileSpec folderName, in boolean create, in boolean upgrading);
  nsIMsgDatabase OpenFolderDB(in nsIMsgFolder folder, in boolean create, in boolean upgrading);
  void Close(in boolean forceCommit);

  void Commit(in nsMsgDBCommit commitType);
  // Force closed is evil, and we should see if we can do without it.
  // In 4.x, it was mainly used to remove corrupted databases.
  void ForceClosed();
  void clearCachedHdrs();
  void resetHdrCacheSize(in unsigned long size);

  readonly attribute nsIDBFolderInfo  dBFolderInfo;

  // get a message header for the given key. Caller must release()!

  nsIMsgDBHdr GetMsgHdrForKey(in nsMsgKey key);
  //Returns whether or not this database contains the given key
  boolean ContainsKey(in nsMsgKey key);

   // Must call AddNewHdrToDB after creating. The idea is that you create
  // a new header, fill in its properties, and then call AddNewHdrToDB.
  // AddNewHdrToDB will send notifications to any listeners.
  nsIMsgDBHdr CreateNewHdr(in nsMsgKey key);

  void AddNewHdrToDB(in nsIMsgDBHdr newHdr, in boolean notify);

  nsIMsgDBHdr CopyHdrFromExistingHdr(in nsMsgKey key, in nsIMsgDBHdr existingHdr, in boolean addHdrToDB);

  [noscript] void ListAllKeys(in nsMsgKeyArrayRef outputKeys);

  nsISimpleEnumerator EnumerateMessages();
  nsISimpleEnumerator EnumerateThreads();
  boolean hasThreads();

  nsIMsgThread GetThreadContainingMsgHdr(in nsIMsgDBHdr msgHdr) ;

  // helpers for user command functions like delete, mark read, etc.

  void MarkHdrRead(in nsIMsgDBHdr msgHdr, in boolean bRead,
                         in nsIDBChangeListener instigator);

  void MarkHdrReplied(in nsIMsgDBHdr msgHdr, in boolean bReplied,
                         in nsIDBChangeListener instigator);

  void MarkHdrMarked(in nsIMsgDBHdr msgHdr, in boolean mark,
                         in nsIDBChangeListener instigator);

  // MDN support
  void MarkMDNNeeded(in nsMsgKey key, in boolean bNeeded,
                           in nsIDBChangeListener instigator);

  // MarkMDNneeded only used when mail server is a POP3 server
  // or when the IMAP server does not support user defined
  // PERMANENTFLAGS
  boolean IsMDNNeeded(in nsMsgKey key);

  void MarkMDNSent(in nsMsgKey key, in boolean bNeeded,
                         in nsIDBChangeListener instigator);
  boolean IsMDNSent(in nsMsgKey key);

// methods to get and set docsets for ids.
  void MarkRead(in nsMsgKey key, in boolean bRead, 
                      in nsIDBChangeListener instigator);

  void MarkReplied(in nsMsgKey key, in boolean bReplied, 
                         in nsIDBChangeListener instigator);

  void MarkForwarded(in nsMsgKey key, in boolean bForwarded, 
                           in nsIDBChangeListener instigator);

  void MarkHasAttachments(in nsMsgKey key, in boolean bHasAttachments, 
                                in nsIDBChangeListener instigator);

  [noscript] void MarkThreadRead(in nsIMsgThread thread, 
					in nsIDBChangeListener instigator, in nsMsgKeyArrayPtr thoseMarked);

  void MarkThreadIgnored(in nsIMsgThread thread, in nsMsgKey threadKey, in boolean bIgnored,
                               in nsIDBChangeListener instigator);
  void MarkThreadWatched(in nsIMsgThread thread, in nsMsgKey threadKey, in boolean bWatched,
                               in nsIDBChangeListener instigator);

  boolean IsRead(in nsMsgKey key);
  boolean IsIgnored(in nsMsgKey key);
  boolean IsMarked(in nsMsgKey key);
  boolean HasAttachments(in nsMsgKey key);

  [noscript] void MarkAllRead(in nsMsgKeyArrayPtr thoseMarked);

  [noscript] void MarkReadByDate (in PRTime startDate, in PRTime endDate, in nsMsgKeyArrayPtr markedIds);

  [noscript] void DeleteMessages(in nsMsgKeyArrayPtr nsMsgKeys, in nsIDBChangeListener instigator);
  void DeleteMessage(in nsMsgKey key, 
                           in nsIDBChangeListener instigator,
                           in boolean commit);
  void DeleteHeader(in nsIMsgDBHdr msgHdr, in nsIDBChangeListener instigator,
                          in boolean commit, in boolean notify);

  // lower level routine that doesn't remove hdr from thread or adjust counts
  void RemoveHeaderMdbRow(in nsIMsgDBHdr msgHdr);

  void UndoDelete(in nsIMsgDBHdr msgHdr);

  void MarkLater(in nsMsgKey key, in PRTime until);
  void MarkMarked(in nsMsgKey key, in boolean mark,
                        in nsIDBChangeListener instigator);
  void MarkOffline(in nsMsgKey key, in boolean offline,
                         in nsIDBChangeListener instigator);
  void SetLabel(in nsMsgKey key, in nsMsgLabelValue label);

  [noscript] void AllMsgKeysImapDeleted(in nsMsgKeyArrayPtr keys, out boolean allDeleted);

  void MarkImapDeleted(in nsMsgKey key, in boolean deleted,
                             in nsIDBChangeListener instigator);

  readonly attribute nsMsgKey FirstNew;

  attribute nsIMsgRetentionSettings msgRetentionSettings;
  // purge unwanted message headers and/or bodies
  void ApplyRetentionSettings(in nsIMsgRetentionSettings msgRetentionSettings);

  attribute nsIMsgDownloadSettings msgDownloadSettings;

  boolean HasNew();  
  void ClearNewList(in boolean notify);
  void AddToNewList(in nsMsgKey key);

  // used mainly to force the timestamp of a local mail folder db to
  // match the time stamp of the corresponding berkeley mail folder,
  // but also useful to tell the summary to mark itself invalid
  // Also, if a local folder is being reparsed, summary will be invalid
  // until the reparsing is done.
  attribute boolean summaryValid;

  // batching - can be used to cache file stream for local mail,
  // and perhaps to use the mdb batching mechanism as well.
  void StartBatch();
  void EndBatch();
  // offline operations - we could move these into an offline operation interface
  // but it would have to be in nsMailDatabase, since local folders can be move destinations
  nsIMsgOfflineImapOperation GetOfflineOpForKey(in nsMsgKey messageKey, in boolean create);
  void  RemoveOfflineOp(in nsIMsgOfflineImapOperation op);
  nsISimpleEnumerator EnumerateOfflineOps();
  [noscript] void ListAllOfflineOpIds(in nsMsgKeyArrayPtr offlineOpIds);
  [noscript] void ListAllOfflineDeletes(in nsMsgKeyArrayPtr offlineDeletes);
  [noscript] void ListAllOfflineMsgs(in nsMsgKeyArrayPtr offlineMsgs);

  readonly attribute nsMsgKey lowWaterArticleNum;
  readonly attribute nsMsgKey highWaterArticleNum;
  attribute nsMsgKey nextPseudoMsgKey;   //for undo-redo of move pop->imap
  readonly attribute nsMsgKey nextFakeOfflineMsgKey; // for saving "fake" offline msg hdrs
  // for sorting
  [noscript] void createCollationKey(in wstring sourceString, out octetPtr key, out unsigned long len);
  [noscript] long compareCollationKeys(out octet key1, in unsigned long len1, out octet key2, in unsigned long len2);

  // when creating a view, the default sort order and view flags 
  // use these for the default.  (this allows news to override, so that
  // news can be threaded by default)
  readonly attribute nsMsgViewFlagsTypeValue defaultViewFlags;
  readonly attribute nsMsgViewSortTypeValue  defaultSortType;

  // for msg hdr hash table allocation. controllable by caller to improve folder loading preformance.
  attribute unsigned long msgHdrCacheSize;

  void setFolderStream(in nsIOFileStream aFileStream);
};

