// The hierarchy of koIPart interfaces. A koIPart instance is the base
// piece for inclusion in Komodo's project system.

#include "nsISupports.idl"
#include "nsIObserver.idl"
#include "koIPrefs.idl"
#include "nsIDOMDocument.idl"
#include "ISciMoz.idl"

interface koIDocument;
interface koIView;
interface koIFile;
interface koIFileEx;

interface koIPart;
interface koITool;

[scriptable, uuid(a77656db-b2e5-4f9c-83ca-e78351ae8993)]
interface koIPart_Common: nsIObserver {
    attribute wstring id;
    attribute wstring type; // the programmer-oriented type, e.g. "folder"
    attribute wstring prettytype;  // A user-intended version of the type: e.g. "Group"
    attribute wstring iconurl;
    attribute wstring url;
    attribute wstring yaml_url;
    attribute wstring logic_url;
    attribute wstring uri; // This is for finding errors
    attribute wstring name;
    koIFileEx getFile();
    
    wstring get_keybinding_description();
    
    // Content for serialization in the CDATA section. 
    // (Not used for all part types.)
    attribute wstring value;
    // A reference to the containing project.
    // (Currently needed to notify on URL addition.)
    attribute koIPart project;

    // koIParts maintain a dictionary of attributes, corresponding to
    // attributes on the serialized koIPart's XML tag.
    boolean hasAttribute(in wstring name);

    nsISupports getAttribute(in wstring name);
    void setAttribute(in wstring name, in nsISupports value);

    void removeAttribute(in wstring name);

    wstring getStringAttribute(in wstring name);
    void setStringAttribute(in wstring name, in wstring value);

    long getLongAttribute(in wstring name);
    void setLongAttribute(in wstring name, in long value);

    boolean getBooleanAttribute(in wstring name);
    void setBooleanAttribute(in wstring name, in boolean value);

    // koIPart data may also be serialized in its 'prefset'. This
    // prefset is inserted into Komodo's preference inheritance stack
    // when appropriate. Data that is appropriate for that stack should
    // be set here.  The prefset will always exist, but empty prefsets
    // may not be serialized.
    attribute koIPreferenceSet prefset;
    void dump(in long indent);
    // This can raise an exception, in which case an appropriate error is
    // set on the last error service.
        /**
         * serialize method is private
         * @deprecated since Komodo 7.0.0
         */
    [deprecated] void serialize(in koIFile stream);

    wstring getDragData(); 
    wstring getDragDataByFlavor(in wstring flavor); 
    void getDragFlavors([array, size_is(count)] out wstring flavors,
                     out unsigned long count);
};

[scriptable, uuid(8EAA9B6D-1D59-43f6-8D0E-F992429ECFE2)]
interface koIPart: koIPart_Common {
    //koIPart-specific items:
    
    koIPart clone();

    // A reference to the part's parents.  If none, then it is a reference to the same part
    // (i.e. top-level parts have self.parent = self
    attribute koIPart parent;

    /* is the part my ancestor? */
    boolean isAncestor(in koIPart part);
};

/* koIContainerBase is a base interface for all container types.
  Types that want to have a hierarchy should inherit this interface.
  Parts (ie a folder or project) that want to contain any other part should
  inherit koIContainer, and not koIContainerBase.
*/
[scriptable, uuid(649FBD6D-BA35-46a9-946B-91DA766BC691)]
interface koIContainerBase: koIPart {
    void getChildren([array, size_is(count)] out koIPart child,
                     out unsigned long count);

    koIPart getChildById(in wstring id);
    /* hasChild does not recurse */
    boolean hasChild(in koIPart child);
    boolean isEmpty();
    void getChildrenByType(in wstring type,
                           in boolean recurse,
                           [array, size_is(count)] out koIPart child,
                           out unsigned long count);
    koIPart getChildWithTypeAndStringAttribute(in wstring type,
                                               in wstring attribname,
                                               in wstring attribvalue,
                                               in boolean recurse);
    koIPart getChildByAttributeValue(in wstring attribname,
                                     in wstring attribvalue,
                                     in boolean recurse);
    void addChild(in koIPart child);
    void removeChild(in koIPart child);

};

/* koIContainer is a base interface for all container types that
  may contain any other type of part. Most actions, such as
  add file or add folder, are attached to koIContainer.  */
[scriptable, uuid(72FFD301-1CFF-4418-98DF-30A70E0C21B5)]
interface koIContainer: koIContainerBase {
};

[scriptable, uuid(0B2531D9-E75E-4428-A5E9-F4F97D21D89C)]
interface koIPart_folder: koIContainer {
    koIPart_folder getLanguageFolder(in wstring language);
    koIPart_folder getDirFolder(in wstring basedir, in wstring targetdir);
};

// our command system depends on the idl inheritence, so we make a livefolder
// subclass a container, rather than subclassing the folder above.
[scriptable, uuid(8D1C1A69-DFB7-11DA-85CA-000D935D3368)]
interface koIPart_livefolder: koIContainer {
    readonly attribute wstring liveDirectory;
};

[scriptable, uuid(D571C805-F554-4de9-AD6E-0D0D8F198705)]
interface koIFileImportingService : nsISupports { 
    // Import files from disk and add them under this folder.
    // XXX We need to move this to a service, since it does not modify the part.
    void findCandidateFiles(in koIPart_folder folder,
                            in wstring dirname, in wstring include,
                            in wstring exclude, in boolean recursive,
                            [array, size_is(count)] out wstring filenames,
                            out unsigned long count);
    void findCandidateFilesRemotely(in koIPart_folder folder,
                            in wstring dirname, in wstring include,
                            in wstring exclude, in boolean recursive,
                            [array, size_is(count)] out wstring filenames,
                            out unsigned long count);
    void addSelectedFiles(in koIPart_folder folder, in wstring importType,
                          in wstring basedir,
                          [array, size_is(count)] in wstring filenames,
                          in unsigned long count);
};

[scriptable, uuid(9D67C0BC-D8D7-4158-9065-28E26466859F)]
interface koIProject: koIPart_livefolder { 
    // Note: Renaming is done by modifying either the URL or the name.
    attribute boolean isDirty;
    readonly attribute boolean isPrefDirty;
    
    // Import directory is the base folder that the project imports (i.e. the
    // folder that will be shown in Places).
    // The LocalPath variant returns null for remote URIs
    readonly attribute wstring importDirectoryLocalPath;
    readonly attribute wstring importDirectoryURI;
    
    void create();
    void activate(); // called when project is made active
    void deactivate(); // called when another project is made active
    
    void load(in wstring url);  // raises an exception on error
                                // and uses the lastErrorService to return error information
    void loadQuiet(in wstring url);  // same as load, but prevents notifications
                                    // when reading toolbars/menu's
    void loadFromFileSystem(in wstring url);

    // Check if the project kpf file has changed on disk since it was last
    // loaded/saved. This uses a md5 check to ensure the contents on disk
    // match what the toolbox originally loaded/saved.
    boolean haveContentsChangedOnDisk();

    void revert();
    // This can raise an exception, in which case an appropriate error is
    // set on the last error service.
    void save();
    void close();

    // Return a reference to any contained koIPart with the given URL.
    // Return NULL if the project contains no such child.
    koIPart getChildByURL(in wstring url);

    // This method is the usual replacement for getChildByURL, where we only
    // care if a particular file is associated with a specific project,
    // but not if it's linked in or just lives in the project's base
    // directory.
    boolean belongsToProject(in wstring url);

    // A registry of contained url-addressable koIParts(where
    // "contained" is of arbitrary depth) is maintained in a koIProject
    // for convenient (and efficient) use of getChildByURL().
    void registerChildByURL(in koIPart child);
    void forgetChildByURL(in koIPart child);

    void getAllContainedURLs([array, size_is(count)] out wstring url,
                             out unsigned long count);
    
    koIPart createPartFromType(in wstring type);

    // look in all live parts and see if this path would be dynamically
    // included in the project.
    boolean containsLiveURL(in wstring url);

    // When doing a save-as, all UUIDs in the project need to be updated.
    void reassignUUIDs();
};

[scriptable, uuid(717c94cf-e454-446e-8836-7df65f86e44c)]
interface koIUnopenedProject: koIProject {
    // This type is used only in the single-project view in the project panel.
    // It represents an unopened project in the projects MRU.
    // It inherits from koIProject so it can work with the KPF trees,
    // but it certainly doesn't support all the same items.
};

[scriptable, uuid(2F84B17E-FCEB-4cd0-8579-6C0F4E95CCA0)]
interface koIPart_file: koIPart {
};


[scriptable, uuid(9D5E81D3-9AA1-4ad3-8D1D-A2CBFD65B55D)]
interface koIPart_SCC_file {
};

[scriptable, uuid(D1B9328D-5D67-4aac-A93A-703E74F1C37F)]
interface koIPart_SCC_collection {
};

[scriptable, uuid(09EB26F0-D9EB-4773-B46A-185D793C1968)]
interface koIPart_SCC_directory {
};



[scriptable, uuid(0A6C17E8-B7A2-4424-8200-9D1A08C6EC75)]
interface koIPartService: nsISupports
{
    // Return a reference to the koIPart with the given id.
    // Return NULL if such a part does not exist.
    koIPart getPartById(in wstring id);

    koIProject getProjectForURL(in wstring url);

    // return prefs for a uri, look in the current project first,
    // then look in all other projects
    koIPreferenceSet getEffectivePrefsForURL(in wstring url);
    
    void addProject(in koIProject project);
    void removeProject(in koIProject project);
    void getProjects([array, size_is(count)] out koIProject project,
                             out unsigned long count);

    attribute koITool toolbox;
    attribute koITool sharedToolbox;
    attribute koIProject currentProject;

    /**
     * Searches the specified koIProjects (e.g. a project, a toolbox)
     * for a part.
     *
     * Note: Not finding what you are looking for? Try to newer and
     * slightly more generate getPart().
     *
     * @param type {string} A part type, e.g. "folder", "snippet",
     *      "command", etc.
     * @param name {string} The part name.
     * @param where {string} Is one of the following:
     *      "container"         the given `part`s project
     *      "toolbox"           the toolbox
     *      "shared toolbox"    the shared toolbox
     *      "toolboxes"         the toolbox, then the shared toolbox
     *      "*"                 contain, toolbox, shared toolbox
     * @param part {Components.interfaces.koIPart} Optional. A koIPart
     *      whose owning project is search for where=="container". Note
     *      that a project belongs to itself, so you can pass in a project
     *      to search the project.
     */
    koIPart findPart(in wstring type,
                     in wstring name,
                     in wstring where,
                     in koIPart part);

    /**
     * Search the specified koIProjects (e.g. a project, a toolbox)
     * for a matching koIPart (or list of matching koIParts).
     *
     * @param type {string} A part type, e.g. "folder", "snippet",
     *      "command", etc.
     * @param attrname {string} The name of string attribute to which
     *      to compare.
     * @param attrvalue {string} The attribute's value.
     * @param where {string} Is one of the following:
     *      "container"         the given `container`
     *      "current project"   the current project
     *      "projects"          all open projects
     *      "toolbox"           the toolbox
     *      "shared toolbox"    the shared toolbox
     *      "toolboxes"         the toolbox, then the shared toolbox
     *      "*"                 container, toolbox, shared toolbox
     * @param container {Components.interfaces.koIContainer} Optional.
     *      A container in which to search, for where=="container".
     *
     * Example:
     * - Search for all folders named "Abbreviations" on the current
     *   project:
     *      findParts("folder", "name", "Abbreviations", "container",
     *                <curr-project>);
     */    
    koIPart getPart(
        in wstring type,
        in wstring attrname,
        in wstring attrvalue,
        in wstring where,
        in koIContainer container);
    void getParts(
        in wstring type,
        in wstring attrname,
        in wstring attrvalue,
        in wstring where,
        in koIContainer container,
        out unsigned long count,
        [retval, array, size_is(count)] out koIPart parts);

    /* DEPRECATED, USE, koIToolbox2Service.runningMacro instead */
    attribute koITool runningMacro;

    void renameProject(in wstring oldPath, in wstring newPath);
};

[scriptable, uuid(bad42fbe-e309-4404-abf7-ff83d4d4c564)]
interface koIProjectPackageService: nsISupports {
    // takes a name and a project, calls packageParts with the projects children
    void packageProject(in wstring packageName, in koIProject project, in boolean overwrite);

    // takes a name and a list of parts, creates a zip file
    void packageParts(in wstring packageName,
                      in unsigned long count,
                      [array, size_is(count)] in koIPart child,
                      in boolean overwrite);
    
    // extracts the package at packagePath to the destination directory
    void extractPackage(in wstring packagePath, in wstring destinationPath);

    // extracts the package at packagePath to the destination directory, then adds
    // the parts in the package project to the provided part
    void importPackage(in wstring packagePath, in wstring destinationPath,
                       in koIPart part);
    
    koIProject newProjectFromPackage(in wstring packagePath, in wstring destinationPath);
};
