/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 *
 * 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 Netscape are
 * Copyright (C) 1998 Netscape Communications Corporation. All
 * Rights Reserved.
 *
 * Contributor(s): 
 */
 
#include "nsISupports.idl"
#include "domstubs.idl"
#include "nsIFileSpec.idl"
#include "nsISupportsArray.idl"
#include "nsIDocumentStateListener.idl"
#include "nsISelectionController.idl"

%{C++

class nsIDOMWindow;
class nsIDOMDocument;
class nsIDOMSelection;
class nsIDOMElement;
class nsIDOMNode;

%}

interface nsIFileSpec;
interface nsIEditor;

[scriptable, uuid(9afff72b-ca9a-11d2-96c9-0060b0fb9956)]
interface nsIEditorShell : nsISupports
{
  readonly attribute nsIDOMDocument    editorDocument;
  readonly attribute nsIDOMSelection   editorSelection;
  readonly attribute nsISelectionController   selectionController;
  
  [noscript] readonly attribute nsIEditor         editor;
  
%{C++

  enum {
    eDocumentStatusUnmodified,
    eDocumentStatusModified
  };

  enum {
    eDisplayModeEdit,
    eDisplayModeBrowserPreview
  };

  enum {
    eTable,
    eTableRow,
    eTableColumn,
    eTableCell,
    eTableCaption
  };
%}
  readonly attribute boolean              documentModified;
  readonly attribute boolean              documentIsEmpty;
  readonly attribute long                 documentLength;
  attribute long                          wrapColumn;
   
  /* Setup */
  void SetEditorType(in wstring editorType);

  void SetToolbarWindow(in nsIDOMWindow win);
  void SetContentWindow(in nsIDOMWindow win);
  void SetWebShellWindow(in nsIDOMWindow win);
  void LoadUrl(in wstring url);

  /* Set the value of the <title> tag in the <head> of a document
   * Also uses this to set the editing window caption
   */
  void    SetDocumentTitle(in wstring title);
  /* Get value of the <title> tag */
  wstring GetDocumentTitle();
  
  /** Register a doc state listener. This gets added to a list of listeners
     which are registered with the editor when that gets instantiated.
     If the LoadUrl fails, this listener will not receive any notifcations.
     If you call this after the editor has been instantiated, it calls through
     to editor::AddDocumentStateListener().
  */
  void RegisterDocumentStateListener(in nsIDocumentStateListener docListener);
  /** Unregister a listener.
     If you call this after the editor has been instantiated, it calls through
     to editor::RemoveDocumentStateListener().
  */
  void UnregisterDocumentStateListener(in nsIDocumentStateListener docListener);
  
  void Init();
  
  /* check a particular window's URL to see if it matches the given URL */
  boolean checkOpenWindowForURLMatch( in wstring inFileURL, in nsIDOMWindow inCheckWindow); 

  /* Commands */
  /** 
   *  @param saveAs false to try to save to existing file
   *          If document is not already saved, it is treated as true
   *          so filename is prompted.
   *  @param saveCopy       
   *          true if we are saving off a copy of the document
   *          without changing the disk file associated with the doc.
   *          This would correspond to a 'Save Copy As' menu command
   *          (currently not in our UI)
   *  return value
   *          true if file was really saved.
   *          false if there is some problem with saving or user
   *          executed "Cancel" when prompted for a filename to save
   */  
  boolean saveDocument(in boolean saveAs, in boolean saveCopy);
  
  /** Check if current document has changes and prompt to save if it does.
   *  return value:
   *         false ONLY if user executed "Cancel" in the SaveAs dialog
   *         true if no changes in doc, or file was saved successfully
   *  @param reasonToSave 
   *         A string to append after "Save changes to <URL>"
   *         If null, just the question mark will be appended
   */
  boolean  CheckAndSaveDocument(in wstring reasonToSave);

  boolean CloseWindow();
  void Print();
  
  void Undo();
  void Redo();
  
  void Cut();
  void Copy();
  void Paste();
  void PasteAsQuotation();
  void PasteAsCitedQuotation(in wstring cite);
  
  void InsertAsQuotation(in wstring quotedText, out nsIDOMNode nodeInserted);
  void InsertAsCitedQuotation(in wstring quotedText, in wstring cite,
                              in wstring charset,
                              out nsIDOMNode nodeInserted);
  
  void SelectAll();
  void DeleteSelection(in PRInt32 action);
  
  void Find();
  void FindNext();

  /* General Utilities */

  /* UI updating */
  void UpdateInterfaceState();

  /* Get string from the Editor's localized string bundle */
  wstring GetString(in wstring name);

  /* Charset Menu */
  wstring GetDocumentCharacterSet();
  void SetDocumentCharacterSet(in wstring characterSet);
  
  /* Structure change */
       /* TypedText actionToTake param is an enum - values in nsIHTMLEditor.h */
  void TypedText(in wstring textToInsert, in PRInt32 actionToTake);
  void InsertText(in wstring textToInsert);
  void InsertSource(in wstring textToInsert);
  void InsertSourceWithCharset(in wstring textToInsert, in wstring charset);
  void InsertBreak();
  
  void MakeOrChangeList(in wstring listType);
  void RemoveList(in wstring listType);
  void Indent(in wstring indent);
  void Align(in wstring align);
  
  /** Element insert and property editing */

  /** Return an element only if it is the only node selected,
    *    such as an image, horizontal rule, etc.
    * The exception is a link, which is more like a text attribute:
    *    The Anchor tag is returned if the selection is within the textnode(s)
    *    that are children of the "A" node.
    *    This could be a collapsed selection, i.e., a caret within the link text.
    *
    * tagName:  The HTML tagname or and empty string 
    *       to get any element (but only if it is the only element selected)
    *    Special input values for Links and Named anchors:
    *    Use "href" to get a link node
    *      (an "A" tag with the "href" attribute set)
    *    Use "anchor" or "namedanchor" to get a named anchor node
    *      (an "A" tag with the "name" attribute set)
    */
  nsIDOMElement GetSelectedElement(in wstring tagName);

  /** Return the input node or a parent matching the given aTagName,
    *   starting the search at the supplied node.
    * An example of use is for testing if a node is in a table cell
    *   given a selection anchor node.
    *
    * tagName:  The HTML tagname
    *    Special input values:
    *    Use "href" to get a link node 
    *      (an "A" tag with the "href" attribute set)
    *    Use "anchor" or "namedanchor" to get a named anchor node
    *      (an "A" tag with the "name" attribute set)
    *    Use "list" to get an OL, UL, or DL list node
    *    Use "td" to get either a TD or TH cell node
    *
    * node:    The node in the document to start the search
    *     If it is null, the anchor node of the current selection is used
    */
  nsIDOMElement GetElementOrParentByTagName(in wstring tagName, in nsIDOMNode node);

  /** Return a new element with default attribute values
    * 
    * This does not rely on the selection, and is not sensitive to context.
    * 
    * Used primarily to supply new element for various insert element dialogs
    *  (Image, Link, NamedAnchor, Table, and HorizontalRule 
    *   are the only returned elements as of 7/25/99)
    *
    * tagName:  The HTML tagname
    *    Special input values for Links and Named anchors:
    *    Use "href" to get a link node
    *      (an "A" tag with the "href" attribute set)
    *    Use "anchor" or "namedanchor" to get a named anchor node
    *      (an "A" tag with the "name" attribute set)
    */
  nsIDOMElement CreateElementWithDefaults(in wstring tagName);

  /** Insert an element, which may have child nodes, at the selection
    * Used primarily to insert a new element for various insert element dialogs,
    *   but it enforces the HTML 4.0 DTD "CanContain" rules, so it should
    *   be useful for other elements.
    *
    * element:           The element to insert
    * deleteSelection:   Delete the selection before inserting
    *     If deleteSelection is PR_FALSE, then the element is inserted 
    *     after the end of the selection for all element except
    *     Named Anchors, which insert before the selection
    */  
  void InsertElementAtSelection(in nsIDOMElement element, in boolean deleteSelection);

  /** Insert an link element as the parent of the current selection
    *
    * element   An "A" element with a non-empty "href" attribute
    */
  void InsertLinkAroundSelection(in nsIDOMElement anchorElement);

  /** 
   * Insert an element under parent at position.
   * No checking is done to verify the legality of the insertion.
   *  That is the responsibility of the caller.
   * element:   The DOM element to insert.
   * parent:    The element to insert the new object under
   * position:  The place in parent to insert the new element
   *                  0=first child, 1=second child, etc.
   *                  any number > number of current children = last child
   */
  void InsertElement(in nsIDOMElement element, in nsIDOMElement parent, in PRInt32 position);

  /** 
    * DeleteNode removes element from the document
    */
  void DeleteElement(in nsIDOMElement element);

  /** 
    * Deletion methods which need to be accessible to JS:
    */
  void DeleteCharForward();
  void DeleteCharBackward();
  void DeleteWordForward();
  void DeleteWordBackward();
  void DeleteToBeginningOfLine();
  void DeleteToEndOfLine();

  void SelectElement(in nsIDOMElement element);
  void SetSelectionAfterElement(in nsIDOMElement element);
  
  /** Table insert and delete methods.  Done relative to selected cell or
   * cell containing the selection anchor.
   */
  void InsertTableCell(in PRInt32 number, in boolean after);
  void InsertTableRow(in PRInt32 number, in boolean after);
  void InsertTableColumn(in PRInt32 number, in boolean after);
  void DeleteTable();
  void DeleteTableCell(in PRInt32 number);
  void DeleteTableCellContents();
  void DeleteTableRow(in PRInt32 number);
  void DeleteTableColumn(in PRInt32 number);
  void JoinTableCells();

  /** Scan through all rows and add cells as needed so 
    *   all locations in the cellmap are occupied.
    *   Used after inserting single cells or pasting
    *   a collection of cells that extend past the
    *   previous size of the table
    * If aTable is null, it uses table enclosing the selection anchor
    */
  void NormalizeTable(in nsIDOMElement tableElement);

  /** Get the indexes from layout's cellmap */
  PRInt32 GetRowIndex(in nsIDOMElement cellElement);
  PRInt32 GetColumnIndex(in nsIDOMElement cellElement);

  /** Get the number of rows in a table from the layout's cellmap 
    * If tableElement is null, it will try to find enclosing table of selection anchor
    */
  PRInt32 GetTableRowCount(in nsIDOMElement tableElement);

  /* Get the number of columns in a table from the layout's cellmap
    * If tableElement is null, it will try to find enclosing table of selection anchor
    */
  PRInt32 GetTableColumnCount(in nsIDOMElement tableElement);

  /* Get cell at a location in the layout's cellmap
     returns null when past last cell in a row or column */
  /* Get a cell and associated data from the layout frame  based on cell map coordinates (0 index) */
  nsIDOMElement GetCellAt(in nsIDOMElement tableElement, in PRInt32 rowIndex, in PRInt32 colIndex);
  /* Get cell at a location in the layout's cellmap with associated data 
     returns null when past last cell in a row or column */
  nsIDOMElement GetCellDataAt(in nsIDOMElement tableElement, in PRInt32 rowIndex, in PRInt32 colIndex,
                              out PRInt32 startRowIndex, out PRInt32 startColIndex,
                              out PRInt32 rowSpan, out PRInt32 colSpan, out boolean isSelected);
  
  /**** end of table editing *****/

  /* Get list of embedded objects, e.g. for mail compose */
  nsISupportsArray GetEmbeddedObjects();

  /* Formatting */
  void SetAttribute(in nsIDOMElement element, in wstring attr, in wstring value);
  void RemoveAttribute(in nsIDOMElement element, in wstring attr);
  void SetTextProperty(in wstring prop, in wstring attr, in wstring value);
  void RemoveTextProperty(in wstring prop, in wstring attr);
  void GetTextProperty(in wstring prop, in wstring attr, in wstring value, out boolean firstHas, out boolean anyHas, out boolean allHas);
  void IncreaseFontSize();
  void DecreaseFontSize();
  void SetParagraphFormat(in wstring paragraphFormat); 
  void SetBodyAttribute(in wstring attr, in wstring value);
  void SetBackgroundColor(in wstring color);

  void ApplyStyleSheet(in wstring url);

  /** Set the display mode for editing
    * @param displayMode
    *       0 (eDisplayModeEdit) Use extra CSS style 
    *           (from override styles in EditorContent.css) 
    *           to show named anchors, table borders, etc for editing
    *       1 (eDisplayModeBrowserPreview) "WYSIWIG" or Preview mode
    *           that looks exactly like the browser display except
    *           for certain behaviors like cursor style over links, etc.
    */
  void  SetDisplayMode(in PRInt32 displayMode);
    
  /* Output.
   * format is mime type, e.g. text/html;
   * See nsIEditor.h for legal flag values.
   */
  /* Get the contents, for output or other uses */
  wstring GetContentsAs(in wstring format, in PRUint32 flags);

  /* Debugging: dump content tree to stdout */
  void DumpContentTree();

  /* Utility */
  wstring GetLocalFileURL(in nsIDOMWindow parent, in wstring filterType);

  /**
   * Tests if a node is a BLOCK element according the the HTML 4.0 DTD
   *   This does NOT consider CSS effect on display type
   */
  boolean NodeIsBlock(in nsIDOMNode node);

  /**
   * This is similar to nsIDOMNode::cloneNode(),
   *   it assures the attribute nodes of the destination are identical with the source node
   *   by copying all existing attributes from the source and deleting those not in the source.
   *   This is used when the destination node (element) already exists
   *
   * The supplied nodes MUST BE ELEMENTS (most callers are working with nodes)
   * destNode     the destination element to operate on
   * sourceNode   the source element to copy attributes from
   */
  void CloneAttributes(in nsIDOMNode destNode, in nsIDOMNode sourceNode);

  void BeginBatchChanges();
  void EndBatchChanges();
  void RunUnitTests();

  void StartLogging(in nsIFileSpec logFile);
  void StopLogging();
};
