/* -*- Mode: IDL; 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 Places.
 *
 * The Initial Developer of the Original Code is
 * Google Inc.
 * Portions created by the Initial Developer are Copyright (C) 2005
 * the Initial Developer. All Rights Reserved.
 *
 * Contributor(s):
 *   Brian Ryner <bryner@brianryner.com> (original author)
 *
 * 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 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 "nsISupports.idl"

interface nsIURI;

/**
 * Observer for bookmark changes.
 */

[scriptable, uuid(c4159523-bedb-4e3f-a163-087e6d89e8a6)]
interface nsINavBookmarkObserver : nsISupports
{
  /**
   * Notify this observer that a batch transaction has started.
   * Other notifications will be sent during the batch change,
   * but the observer is guaranteed that onEndUpdateBatch() will be called
   * at the completion of changes.
   */
  void onBeginUpdateBatch();

  /**
   * Notify this observer that a batch transaction has ended.
   */
  void onEndUpdateBatch();

  /**
   * Notify this observer that the bookmark was added.
   * Called after the actual add took place.
   * If other bookmarks in the folder shift due to the item being added, 
   * no additional onItemMoved notifications are sent.
   *
   * @param bookmark   The bookmark item that was added.
   * @param folder     The folder that the item was added to.
   * @param index      The item's index in the folder.
   */
  void onItemAdded(in nsIURI bookmark, in PRInt64 folder, in PRInt32 index);

  /**
   * Notify this observer that the bookmark was removed.
   * Called after the actual remove took place.
   * If other bookmarks in the folder shift due to the item being removed, 
   * no additional onItemMoved notifications are sent.
   *
   * @param bookmark   The bookmark item will be removed.
   * @param folder     The folder that the item was removed from.
   * @param index      The bookmark's index in the folder.
   */
  void onItemRemoved(in nsIURI bookmark, in PRInt64 folder, in PRInt32 index);

  /**
   * Notify this observer that an item has changed position in a folder.
   * Note that items can exist in more than one folder, but may only occur once
   * within a given folder.
   * If other bookmarks in the folder shift due to the item being moved, 
   * no additional onItemMoved notifications are sent.
   * 
   * @param bookmark   The bookmark item that changed position.
   * @param folder     The folder where the item changed position.
   * @param oldIndex   The old index of the item in the folder.
   * @param newIndex   The new index of the item in the folder.
   */
  void onItemMoved(in nsIURI bookmark, in PRInt64 folder,
                   in PRInt32 oldIndex, in PRInt32 newIndex);

  /**
   * Notify this observer that a bookmark's information has changed.  This
   * will be called whenever any attributes like "title" are changed.
   *
   * @param bookmark The bookmark which changed.
   * @param property The property which changed.
   *
   * property = "cleartime" (history was deleted, there is no last visit date):
   *                        value = none
   * property = "title": value = new title
   * property = "favicon": value = new "moz-anno" URL of favicon image
   */
  void onItemChanged(in nsIURI bookmark, in ACString property,
                     in AString value);

  /**
   * Notify that the item was visited. Normally in bookmarks we use the last
   * visit date, and normally the time will be a new visit that will be more
   * recent, but this is not guaranteed. You should check to see if it's
   * actually more recent before using this new time.
   *
   * @see onItemChanged properth = "cleartime" for when all visit dates are
   * deleted for the URI.
   */
  void onItemVisited(in nsIURI bookmark, in PRInt64 aVisitID, in PRTime time);

  /**
   * Notify this observer that a bookmark has been replaced.
   *
   * @param folder   The folder in which the bookmark was replaced
   * @param item     The item which was replaced
   * @param newItem  The new item which replaced item
   */
  void onItemReplaced(in PRInt64 folder, in nsIURI item, in nsIURI newItem);

  /**
   * Notify this observer that a bookmark folder has been added.
   *  @param folder     The id of the folder that was added.
   *  @param parent     The id of the folder's parent.
   *  @param index      The folder's index inside its parent.
   */
  void onFolderAdded(in PRInt64 folder, in PRInt64 parent, in PRInt32 index);

  /**
   * Notify this observer that a bookmark folder has been removed.
   *  @param folder     The id of the folder that was removed.
   *  @param parent     The id of the folder's old parent.
   *  @param index      The folder's old index in its parent.
   */
  void onFolderRemoved(in PRInt64 folder, in PRInt64 parent, in PRInt32 index);

  /**
   * Notify this observer that a bookmark folder has been moved.
   *  @param folder     The id of the folder that was moved.
   *  @param oldParent  The id of the folder's old parent.
   *  @param oldIndex   The folder's old index inside oldParent.
   *  @param newParent  The id of the folder's new parent.
   *  @param newIndex   The folder's index inside newParent.
   */
  void onFolderMoved(in PRInt64 folder,
                     in PRInt64 oldParent, in PRInt32 oldIndex,
                     in PRInt64 newParent, in PRInt32 newIndex);

  /**
   * Notify this observer that a bookmark folder's information has changed.
   * This will be called whenever any attributes like "title" are changed.
   *  @param folder     The id of the folder that was changed.
   *  @param property   The property that was changed.
   */
  void onFolderChanged(in PRInt64 folder, in ACString property);

  /**
   * Notify this observer that a separator has been added.
   *  @param parent     The id of the separator's parent.
   *  @param index      The separator's index inside its parent.
   */
  void onSeparatorAdded(in PRInt64 parent, in PRInt32 index);

  /**
   * Notify this observer that a separator has been removed.
   *  @param parent     The id of the separator's parent.
   *  @param index      The separator's old index in its parent.
   */
  void onSeparatorRemoved(in PRInt64 parent, in PRInt32 index);
};

/**
 * The BookmarksService interface provides methods for managing bookmarked
 * history items.  Bookmarks consist of a set of user-customizable
 * folders.  A URI in history can be contained in one or more such folders.
 */

[scriptable, uuid(5feca204-b735-40e8-921f-8b057eedffe2)]
interface nsINavBookmarksService : nsISupports
{
  /**
   * The folder ID of the Places root.
   */
  readonly attribute PRInt64 placesRoot;

  /**
   * The folder ID of the bookmarks root.
   */
  readonly attribute PRInt64 bookmarksRoot;

  /**
   * The folder ID of the personal toolbar root.
   */
  readonly attribute PRInt64 toolbarRoot;

  /**
   * Inserts a child item into the given folder. If this item already exists in
   * the given folder, it will be moved to the new position.
   *  @param folder     The id of the parent folder
   *  @param item       The URI to insert
   *  @param index      The index to insert at, or -1 to append
   */
  void insertItem(in PRInt64 folder, in nsIURI item, in PRInt32 index);

  /**
   * Removes a child item from the given folder.
   *  @param folder     The folder to remove the child from
   *  @param item       The child item to remove
   */
  void removeItem(in PRInt64 folder, in nsIURI child);

  /**
   * Replace an item with a different item.
   *  @param folder     The folder which contains the item to replace
   *  @param item       The item which should be replaced
   *  @param newItem    The new item
   */
  void replaceItem(in PRInt64 folder, in nsIURI item, in nsIURI newItem);

  /**
   * Creates a new child folder and inserts it under the given parent.
   *  @param parent     The id of the parent folder
   *  @param name       The name of the new folder
   *  @param index      The index to insert at, or -1 to append
   *  @returns the ID of the newly-inserted folder
   */
  PRInt64 createFolder(in PRInt64 parent, in AString name, in PRInt32 index);

  /**
   * Wrapper for container services.  Creates a folder under the given
   * parent and sets the container type.
   *  @param parent     The id of the parent folder
   *  @param name       The name of the new folder
   *  @param index      The index to insert at, or -1 to append
   *  @param type       The type of container to insert
   *  @returns the ID of the newly-inserted folder
   */
  PRInt64 createContainer(in PRInt64 parent, in AString name,
                          in PRInt32 index, in AString type);

  /**
   * Removes a folder from the bookmarks tree.
   *  @param folder     The id of the folder to remove.
   */
  void removeFolder(in PRInt64 folder);

  /**
   * Convenience function for container services.  Removes
   * all children of the given folder.
   *  @param folder     The id of the folder to remove children from.
   */
  void removeFolderChildren(in PRInt64 folder);

  /**
   * Moves a folder to a different container, preserving its contents.
   *  @param folder      The folder to move
   *  @param newParent   The id of the folder's new parent
   *  @param index       The folder's index under newParent, or -1 to append
   */
  void moveFolder(in PRInt64 folder, in PRInt64 newParent, in PRInt32 index);

  /**
   * Returns the ID of a child folder with the given name. This does not
   * recurse, you have to give it an immediate sibling of the given folder.
   * If the given subfolder doesn't exist, it will return 0.
   *  @param folder    Parent folder whose children we will search
   *  @param subFolder Name of the folder to search for in folder
   */
  PRInt64 getChildFolder(in PRInt64 folder, in AString subFolder);

  /**
   * Inserts a bookmark separator into the given folder at the given index.
   * The separator can be removed using removeChildAt().
   *  @param folder    Parent folder of the separator
   *  @param index     The separator's index under folder, or -1 to append
   */
  void insertSeparator(in PRInt64 folder, in PRInt32 index);

  /**
   * Removes any type of child (item, folder, or separator) at the given index.
   *  @param folder    The folder to remove a child from
   *  @param index     The index of the child to remove
   */
  void removeChildAt(in PRInt64 folder, in PRInt32 index);

  /**
   * Set the history/bookmark title for a URI.  The new title will be used
   * anywhere the URI is shown in bookmarks or history.
   *  @param uri   The URI whose name should be set
   *  @param title The new title for the URI
   */
  void setItemTitle(in nsIURI uri, in AString title);

  /**
   * Get the history/bookmark title for the URI.
   *  @param uri   The URI whose title should be retrieved
   *  @returns     The title for the URI.
   */
  AString getItemTitle(in nsIURI uri);

  /**
   * Set the title for a bookmark folder.
   *  @param folder     The folder whose title should be set
   *  @param title      The new title for the folder
   */
  void setFolderTitle(in PRInt64 folder, in AString title);

  /**
   * Get the title for a bookmark folder.
   *  @param folder     The folder whose title should be retrieved
   *  @returns          The title for the folder
   */
  AString getFolderTitle(in PRInt64 folder);

  /**
   * Get the place: url for a bookmark folder. You can use this value to
   * get/set the icon for a folder or to associate other data with it using
   * the annotation service. Its important that you use this function instead
   * of just serializing the query/options for a given folder because you
   * may have different options or query parameters. This function will give
   * the canonical value.
   * @param folder      The folder whose URI should be retrieved
   * @returns           The URI for the folder
   */
  nsIURI getFolderURI(in PRInt64 folder);

  /**
   * Checks whether a folder has read-only children.  This property is
   * defined by the nsIBookmarsContainer for the folder, if one exists.
   * If this is set to true, UI should not allow the user to add, remove,
   * or reorder children in this folder.  The default for all folders is false.
   */
  boolean getFolderReadonly(in PRInt64 folder);

  /**
   * Returns true if the given URI is in any bookmark folder. If you want the
   * results to be redirect-aware, use getBookmarkedURIFor()
   */
  boolean isBookmarked(in nsIURI uri);

  /**
   * Used to see if the given URI is bookmarked, or any page that redirected to
   * it is bookmarked. For example, if I bookmark "mozilla.org" by manually
   * typing it in, and follow the bookmark, I will get redirected to
   * "www.mozilla.org". Logically, this new page is also bookmarked. This
   * function, if given "www.mozilla.org", will return the URI of the bookmark,
   * in this case "mozilla.org".
   *
   * If there is no bookmarked page found, it will return NULL.
   */
  nsIURI getBookmarkedURIFor(in nsIURI uri);

  /**
   * Returns the list of folder ids that contain the given URI.
   */
  void getBookmarkFolders(in nsIURI uri, out PRUint32 count,
                          [array, retval, size_is(count)] out PRInt64 folders);

  /**
   * Returns the index of the given item in the given folder.
   * Returns -1 if the item is not present in the folder.
   */
  PRInt32 indexOfItem(in PRInt64 folder, in nsIURI uri);

  /**
   * Returns the index of the given subfolder in its parent.
   * Returns -1 if the subfolder is not present in the parent folder.
   */
  PRInt32 indexOfFolder(in PRInt64 parent, in PRInt64 folder);

  /**
   * Associates the given keyword with the given URI.
   *
   * Use an empty keyword to clear the keyword associated with the URI. Use an
   * empty URI to clear the URI associated with that keyword. In both of these
   * cases, succeeds but does nothing if the URL/keyword is not found.
   *
   * When setting a keyword (both URI and keyword are specified), the URI must
   * be bookmarked for the keyword to be persistent.
   */
  void setKeywordForURI(in nsIURI uri, in AString keyword);

  /**
   * Retrieves the keyword for the given URI. Will be empty if no such
   * keyword is found.
   */
  AString getKeywordForURI(in nsIURI uri);

  /**
   * Returns the URI associated with the given keyword. Empty if no such
   * keyword is found.
   */
  nsIURI getURIForKeyword(in AString keyword);

  /**
   * Adds a bookmark observer. If ownsWeak is false, the bookmark service will
   * keep an owning reference to the observer.  If ownsWeak is true, then
   * aObserver must implement nsISupportsWeakReference, and the bookmark
   * service will keep a weak reference to the observer.
   */
  void addObserver(in nsINavBookmarkObserver observer, in boolean ownsWeak);

  /**
   * Removes a bookmark observer.
   */
  void removeObserver(in nsINavBookmarkObserver observer);

  /**
   * Causes observers to be notified of a beginUpdateBatch when a lot of things
   * are about to change. Calls can be nested, observers will only be
   * notified when all batches begin/end.
   *
   * It is EXTREMELY IMPORTANT that you call EndUpdateBatch for each call to
   * beginUpdateBatch. If you don't do this, certain parts of the UI will not
   * get updated and any changes to bookmarks will not get written to disk.
   * From C++ code inside the places component, use nsBookmarksUpdateBatcher
   * defined in nsNavBookmarks.h to scope batches. For JS or from other
   * components, just please be very careful to close the batch, especially
   * when encountering an error and returning early.
   */
  void beginUpdateBatch();

  /**
   * Causes observers to be notified of an endUpdateBatch when a batch is
   * done changing. Should match beginUpdateBatch or bad things will happen.
   */
  void endUpdateBatch();


  /**
   * Loads the given bookmarks.html file and merges it with the current
   * bookmarks hierarchy.
   */
  void importBookmarksHTML(in nsIURI url);


  /**
   * Loads the given bookmarks.html file and puts it in the given folder
   */
  void importBookmarksHTMLToFolder(in nsIURI url, in PRInt64 folder);


  /**
   * Saves the current bookmarks hierarchy to a bookmarks.html file.
   */
  void exportBookmarksHTML(in nsIURI url);
};
