/* ***** 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 Komodo code.
 * 
 * The Initial Developer of the Original Code is ActiveState Software Inc.
 * Portions created by ActiveState Software Inc are Copyright (C) 2000-2007
 * ActiveState Software Inc. All Rights Reserved.
 * 
 * Contributor(s):
 *   ActiveState Software Inc
 * 
 * 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"

#include "koIFileEx.idl"
#include "koIEncoding.idl"
#include "koIPrefs.idl"
#include "koILanguage.idl"
#include "ISciMoz.idl"
#include "nsIObserverService.idl"

interface koIDocumentSettingsManager;
interface koICodeIntelBuffer;
interface koITabstopInsertionNode;

interface koILexerLanguageService;

/* A koIDocument instance represents the contents of a file in Komodo,
 * whether saved or unsaved.
 */
[scriptable, uuid(BE0B2F5D-DB83-427B-9C41-FA8E890F81AF)]
interface koIDocument : nsISupports
{
    void initWithFile(in koIFileEx file, in boolean untitled);
    void initUntitled(in wstring name, in wstring encoding);

    // Basic operations.
    //
    // Each of load(), save() and revert() can raise an exception if
    // the operation fails. If so the error is set on the
    // koILastErrorService.
    void loadFromURI(in wstring uri);
    void load();
    void save(in boolean forceSave); 
    void revert(); 

    // Manual reference counting.
    void addReference();
    void releaseReference();

    // The baseName and displayPath for untitled documents is just its
    // name.
    attribute wstring baseName;
    readonly attribute wstring displayPath;

    // The file that this document corresponds to, or NULL if untitled
    // document.
    readonly attribute koIFileEx file;

    attribute koICodeIntelBuffer ciBuf;

    attribute AString buffer; // The contents of the document
    readonly attribute long bufferLength;

    attribute boolean isDirty; // There are unsaved changes to the document.
    attribute boolean isUntitled;
    
    // Returns true if the contents of the file on disk have changed from
    // the last save/load/revert or call to differentOnDisk.  It DOES NOT
    // compare against the current contents of the buffer in memory.
    boolean differentOnDisk();

    // --- EOLs (end-of-line characters)
    // The EOL_* constants must remain in sync with the ones in eollib.py
    const long EOL_LF = 0;
    const long EOL_CR = 1;
    const long EOL_CRLF = 2;
    // EOL to use for new lines
    // - Must be one of the above three EOL_* constants.
    attribute long new_line_endings;
    const long EOL_MIXED = 3;
    const long EOL_NOEOL = 4;
    // Getting/setting this involves reading/changing the document.
    // - Can be any of the above five EOL_* constants.
    //XXX Might want to add a get_dominant_line_ending() method to know
    //    what to use when existing_line_endings returns EOL_MIXED.
    attribute long existing_line_endings;
    void cleanLineEndings();

    attribute wstring language;  // what language is this document in?
    attribute koILanguage languageObj;  // what language object corresponds to language?
    // subLanguage returns the language for the current position in the
    // document. the document must be using a UDL buffer, otherwise it is the
    // same as language above 
    readonly attribute wstring subLanguage; 
    // Return the language (or sub-language in the UDL case) for the given pos.
    string languageForPosition(in long position);

    //---- Encoding support
    // Komodo always uses code page 65001, i.e. put scintilla in
    // Unicode/UTF-8 mode. Setting `codePage` is DEPRECATED in
    // Komodo 6.0.0b1 -- the set value is ignored.
    attribute long codePage;
    attribute koIEncoding encoding;
    readonly attribute boolean isEncodable; // true if the file can be encoded using it's current encoding settings
    void setEncodingFromEncodingName(in string encoding_name);
    void forceEncodingFromEncodingName(in string encoding_name);
    // encodedText must be an 8bit string as it is the byte representation of a file
    // that is only used for saving a buffer (see autoSave)
    readonly attribute ACString encodedText;
    readonly attribute ACString utf8Text;
    void removeUnencodeable();  

    void setBufferAndEncoding(in AString buffer, in string encoding_name);

    // document prefset
    readonly attribute koIPreferenceSet prefs;
    // see if this document is in the current project, if so, use those
    // prefs, if not, find it in any open project and use those prefs.
    // if the document is not in a project, the return is the prefs above
    koIPreferenceSet getEffectivePrefs();
    
    void saveState(in koIScintillaView scintilla);
    
    // Maintain a list of editor views that are using this document.
    // XXX we will want to revisit this and make it less scintilla-specific
    void addView(in koIScintillaView scintilla);
    void releaseView(in koIScintillaView scintilla);
    koIScintillaView getView(); // return first view
    readonly attribute long numScintillas; // the number of scintillas for this view.
    
    // Users can observe changes of a number of document attributes.
    readonly attribute nsIObserverService observerService;

    // The indentation parameters are derived from prefs if they exist
    // in prefs, or guessed from analysis of the document if not.
    attribute long tabWidth;    // number of spaces that a tab character uses in display
    attribute boolean useTabs;  // true if tabs are used for indentation
    attribute long indentWidth; // number of spaces for an indent (typically 4 or 8)
    AString getUnsavedChanges();

    // Auto-save API.    
    boolean haveAutoSave();
    void doAutoSave();
    void restoreAutoSave();
    // `removeAutoSaveFile` should only called from the viewManager
    // canClose handler.  Other uses are internal to koDocument.  The
    // auto save file is removed by revert and save.
    void removeAutoSaveFile();

    readonly attribute koIDocumentSettingsManager docSettingsMgr;

    // The TabstopInsertionTable maintains the state of tabstop
    // insertions from snippets or templates on the current
    // document.  It needs to be on the document object, so all
    // views see the same state of tabstop processing.
    void getTabstopInsertionTable(out PRUint32 count,
                                  [array, size_is(count), retval] out koITabstopInsertionNode value);
    void clearTabstopInsertionTable();
    readonly attribute boolean hasTabstopInsertionTable;
    void setTabstopInsertionTable(in PRUint32 count,
                                  [array, size_is(count)] in koITabstopInsertionNode insertionNodes);
    void removeTabstopInsertionNodeAt(in PRUint32 idx);

    readonly attribute boolean isLargeDocument; // Based on time to load
    attribute koILexerLanguageService lexer;
};

[scriptable, uuid(826C0192-5D6C-4DDB-B135-1412649BF3CC)]
interface koITabstopInsertionNode : nsISupports
{
    attribute long indicator;
    attribute boolean isBackref;
    attribute long backrefNumber;
    attribute boolean isBackrefAnchor;
    void describe(); // for debugging
};

/*
 * The koIDocumentService knows all of the open documents.
 */
[scriptable, uuid(CA0A2B77-781B-49E9-B394-B6F8DD56700E)]
interface koIDocumentService: nsISupports
{
    // Creates a new document for this uri.
    koIDocument createNewDocumentFromURI(in wstring uri);
    // Like createNewDocumentFromURI, though first checks to see if a doc with
    // this uri already exists, and if it does it returns the existing one.
    koIDocument createDocumentFromURI(in wstring uri);
    // In Komodo's view system "untitled" == "unsaved and unnamed".
    koIDocument createUntitledDocument(in string language);
    
    // These create methods are currently only used for creating a new
    // file from a template.
    koIDocument createDocumentFromTemplateURI(in wstring uri,
                                           in wstring name,
                                           in wstring ext);
    koIDocument createFileFromTemplateURI(in wstring templateURI,
                                           in wstring uri,
                                           in boolean savenow);
    
    void getAllDocuments([array, size_is(count)] out koIDocument documents,
                     out PRUint32 count);
    koIDocument findDocumentByURI(in wstring URI);
    
    //TODO: Move this to a more suitable IDL. This has nothing to do with managing koIDocuments. 
    // This should indicate that it is intended to be an error line with
    // a parseable filepath and line number.
    void parseHotspotLine(in AString line,
                          in wstring cwd,
                          out PRUint32 count,
                          [array, size_is(count)] out wstring results);
};

/* The koIDocumentSettingsManager manages the transfer of data between
 * document prefs and scintilla views.  There is one per document.
 */
[scriptable, uuid(F42C1036-6AAA-4B9A-8623-B398983095E3)]
interface koIDocumentSettingsManager : nsISupports {
    void register(in koIDocument koDoc, in koIScintillaView scintilla);
    void unregister(in koIScintillaView scintilla);
    void applyViewSettingsToDocument(in koIScintillaView scintilla);
    void applyDocumentSettingsToView(in koIScintillaView scintilla);
};


// koIDiff usage:
// 1. Initialize with one of the init*() methods
// 2. Use the data or extra methods for info.
[scriptable, uuid(0c70afc1-a195-4578-8c5e-f82cd0aba531)]
interface koIDiff : nsISupports
{
    void initByDiffingFiles(in wstring fname1, in wstring fname2);
    void initByDiffingDocuments(in koIDocument doc1, in koIDocument doc2);
    void initWithDiffContent(in AString diff);


    readonly attribute AString diff;    // the diff content
    readonly attribute AString warning; // a possible warning about the diff
    // These two are not available if initialized via initWithDiffContent().
    readonly attribute koIDocument doc1;
    readonly attribute koIDocument doc2;
    
    // Find the file and file position corresponding to the given position
    // in the diff.
    //
    // All line and column numbers are 0-based.
    //
    // Raises an exception if it could not be determined. The reason is set
    // on koILastErrorService. Note also that 'filePath' could be relative.
    void filePosFromDiffPos(in PRUint32 line,
                            in PRUint32 column,
                            out wstring filePath,
                            out PRUint32 fileLine,
                            out PRUint32 fileColumn);

    // Infer, if possible, an appropriate 'cwd' and 'strip' (i.e.
    // `patch -p <val>`) given different paths in the diff and actual on disk.
    //
    // Raises an exception if it could not infer these.
    void inferCwdAndStripFromPath(in wstring pathInDiff,
                                  in wstring actualPath,
                                  out wstring cwd,
                                  out PRUint32 strip);
};
