// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Use the <code>chrome.fileSystem</code> API to create, read, navigate,
// and write to a sandboxed section of the user's local file system. With this
// API, Chrome Apps can read and write to a user-selected location. For
// example, a text editor app can use the API to read and write local documents.
// All failures are notified via chrome.runtime.lastError.
namespace fileSystem {
  dictionary AcceptOption {
    // This is the optional text description for this option. If not present,
    // a description will be automatically generated; typically containing an
    // expanded list of valid extensions (e.g. "text/html" may expand to
    // "*.html, *.htm").
    DOMString? description;

    // Mime-types to accept, e.g. "image/jpeg" or "audio/*". One of mimeTypes or
    // extensions must contain at least one valid element.
    DOMString[]? mimeTypes;

    // Extensions to accept, e.g. "jpg", "gif", "crx".
    DOMString[]? extensions;
  };

  enum ChooseEntryType {

    // Prompts the user to open an existing file and returns a FileEntry on
    // success. From Chrome 31 onwards, the FileEntry will be writable if the
    // application has the 'write' permission under 'fileSystem'; otherwise, the
    // FileEntry will be read-only.
    openFile,

    // Prompts the user to open an existing file and returns a writable
    // FileEntry on success. Calls using this type will fail with a runtime
    // error if the application doesn't have the 'write' permission under
    // 'fileSystem'.
    openWritableFile,

    // Prompts the user to open an existing file or a new file and returns a
    // writable FileEntry on success. Calls using this type will fail with a
    // runtime error if the application doesn't have the 'write' permission
    // under 'fileSystem'.
    saveFile,

    // Prompts the user to open a directory and returns a DirectoryEntry on
    // success. Calls using this type will fail with a runtime error if the
    // application doesn't have the 'directory' permission under 'fileSystem'.
    // If the application has the 'write' permission under 'fileSystem', the
    // returned DirectoryEntry will be writable; otherwise it will be read-only.
    // New in Chrome 31.
    openDirectory
  };

  dictionary ChooseEntryOptions {
    // Type of the prompt to show. The default is 'openFile'. From Chrome 31
    // onwards, 'openWritableFile' is deprecated and 'openFile' will return a
    // writable file entry for apps with the 'write' permission under
    // 'fileSystem'. 'openDirectory' is new in Chrome 31 and will fail with a
    // runtime error if the application doesn't have the 'directory' permission
    // under 'fileSystem'.
    ChooseEntryType? type;

    // The suggested file name that will be presented to the user as the
    // default name to read or write. This is optional.
    DOMString? suggestedName;

    // The optional list of accept options for this file opener. Each option
    // will be presented as a unique group to the end-user.
    AcceptOption[]? accepts;

    // Whether to accept all file types, in addition to the options specified
    // in the accepts argument. The default is true. If the accepts field is
    // unset or contains no valid entries, this will always be reset to true.
    boolean? acceptsAllTypes;

    // Whether to accept multiple files. This is only supported for openFile and
    // openWritableFile. The callback to chooseEntry will be called with a list
    // of entries if this is set to true. Otherwise it will be called with a
    // single Entry.
    boolean? acceptsMultiple;
  };
  callback GetDisplayPathCallback = void (DOMString displayPath);
  callback EntryCallback = void ([instanceOf=Entry] object entry);
  callback EntriesCallback = void (
      [instanceOf=Entry] optional object entry,
      [instanceOf=FileEntry] optional object[] fileEntries);
  callback IsWritableCallback = void (boolean isWritable);
  callback IsRestorableCallback = void (boolean isRestorable);

  interface Functions {
    // Get the display path of an Entry object. The display path is based on
    // the full path of the file or directory on the local file system, but may
    // be made more readable for display purposes.
    static void getDisplayPath([instanceOf=Entry] object entry,
                               GetDisplayPathCallback callback);

    // Get a writable Entry from another Entry. This call will fail with a
    // runtime error if the application does not have the 'write' permission
    // under 'fileSystem'. If entry is a DirectoryEntry, this call will fail if
    // the application does not have the 'directory' permission under
    // 'fileSystem'.
    static void getWritableEntry([instanceOf=Entry] object entry,
                                 EntryCallback callback);

    // Gets whether this Entry is writable or not.
    static void isWritableEntry([instanceOf=Entry] object entry,
                                IsWritableCallback callback);

    // Ask the user to choose a file or directory.
    static void chooseEntry(optional ChooseEntryOptions options,
                            EntriesCallback callback);

    // Returns the file entry with the given id if it can be restored. This call
    // will fail with a runtime error otherwise. This method is new in Chrome
    // 31.
    static void restoreEntry(DOMString id, EntryCallback callback);

    // Returns whether the app has permission to restore the entry with the
    // given id. This method is new in Chrome 31.
    static void isRestorable(DOMString id, IsRestorableCallback callback);

    // Returns an id that can be passed to restoreEntry to regain access to a
    // given file entry. Only the 500 most recently used entries are retained,
    // where calls to retainEntry and restoreEntry count as use. If the app has
    // the 'retainEntries' permission under 'fileSystem', entries are retained
    // indefinitely. Otherwise, entries are retained only while the app is
    // running and across restarts. This method is new in Chrome 31.
    static DOMString retainEntry([instanceOf=Entry] object entry);
  };
};
