// 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.mediaGalleries</code> API to access media files (audio,
// images, video) from the user's local disks (with the user's consent).
namespace mediaGalleries {

  [inline_doc] enum GalleryChangeType {
    // The contents of the gallery have changed.
    contents_changed,
    // The watch has been dropped because the device has been detached,
    // the gallery permission has been removed, or any other reason.
    watch_dropped
  };

  [inline_doc] enum GetMediaFileSystemsInteractivity {
    // Do not act interactively.
    no,
    // Ask the user to manage permitted media galleries.
    yes,
    // Ask the user to manage permitted galleries only if the return set would
    // otherwise be empty.
    if_needed
  };

  [inline_doc] enum GetMetadataType {
    // Retrieve the mime type, metadata tags, and attached images.
    all,
    // Retrieve only the mime type and the metadata tags.
    mimeTypeAndTags,
    // Retrieve only the mime type.
    mimeTypeOnly
  };

  [nodefine, inline_doc] enum ScanProgressType {
    // The scan started.
    start,
    // The scan was cancelled.
    cancel,
    // The scan finished but none of the result have been added,
    // addScanResults() has to be called to ask the user for permission.
    finish,
    // The scan encountered an error and could not proceed.
    error
  };

  [inline_doc] dictionary GalleryChangeDetails {
    // Type of change event.
    GalleryChangeType type;

    // Identifies the modified gallery.
    DOMString galleryId;
  };

  [inline_doc] dictionary MediaFileSystemsDetails {
    // Whether to prompt the user for permission to additional media galleries
    // before returning the permitted set. Default is silent.  If the value
    // 'yes' is passed, or if the application has not been granted access to
    // any media galleries and the value 'if_needed' is passed, then the
    // media gallery configuration dialog will be displayed.
    GetMediaFileSystemsInteractivity? interactive;
  };

  [inline_doc] dictionary MediaMetadataOptions {
    // Specifies which subset of the metadata to retrieve. Defaults to 'all'
    // if the option is omitted.
    GetMetadataType? metadataType;
  };

  callback MediaFileSystemsCallback =
      void ([instanceOf=DOMFileSystem] object[] mediaFileSystems);

  callback AddUserFolderCallback =
      void ([instanceOf=DOMFileSystem] object[] mediaFileSystems,
            DOMString selectedFileSystemName);

  [nodefine] callback DropPermissionForMediaFileSystemCallback = void ();

  [inline_doc] dictionary MediaFileSystemMetadata {
    // The name of the file system.
    DOMString name;

    // A unique and persistent id for the media gallery.
    DOMString galleryId;

    // If the media gallery is on a removable device, a unique id for the
    // device while the device is online.
    DOMString? deviceId;

    // True if the media gallery is on a removable device.
    boolean isRemovable;

    // True if the device the media gallery is on was detected as a media
    // device.  i.e. a PTP or MTP device, or a DCIM directory is present.
    boolean isMediaDevice;

    // True if the device is currently available.
    boolean isAvailable;
  };

  [nodefine, inline_doc] dictionary ScanProgressDetails {
    // The type of progress event, i.e. start, finish, etc.
    ScanProgressType type;

    // The number of Galleries found.
    long? galleryCount;

    // Appoximate number of media files found; some file types can be either
    // audio or video and are included in both counts.
    long? audioCount;
    long? imageCount;
    long? videoCount;
  };

  callback MediaFileSystemsMetadataCallback =
      void (MediaFileSystemMetadata[] metadata);

  dictionary StreamInfo {
    // Describes format of container or codec of stream, i.e. "mp3", "h264".
    DOMString type;

    // An unfiltered string->string dictionary of tags for the stream.
    object tags;
  };

  dictionary MediaMetadata {
    // The browser sniffed mime type.
    DOMString mimeType;

    // Defined for video. In pixels.
    long? height;
    long? width;

    // Defined for audio and video. In seconds.
    double? duration;

    // Defined for video. In degrees.
    long? rotation;

    // Defined for audio and video.
    DOMString? album;
    DOMString? artist;
    DOMString? comment;
    DOMString? copyright;
    long? disc;
    DOMString? genre;
    DOMString? language;
    DOMString? title;
    long? track;

    // All the metadata in the media file. For formats with multiple streams,
    // stream order will be preserved. Container metadata is the first element.
    StreamInfo[] rawTags;

    // The images embedded in the media file's metadata. This is most often
    // used for album art or video thumbnails.
    [instanceOf=Blob] object[] attachedImages;
  };

  callback MediaMetadataCallback = void (MediaMetadata metadata);

  // A dictionary that describes the add gallery watch request results.
  dictionary AddGalleryWatchResult {
    DOMString galleryId;
    boolean success;
  };

  callback AddGalleryWatchCallback = void (AddGalleryWatchResult result);
  [nodefine] callback GetAllGalleryWatchCallback =
      void (DOMString[] galleryIds);

  interface Functions {
    // Get the media galleries configured in this user agent. If none are
    // configured or available, the callback will receive an empty array.
    static void getMediaFileSystems(optional MediaFileSystemsDetails details,
                                    MediaFileSystemsCallback callback);

    // Present a directory picker to the user and add the selected directory
    // as a gallery. If the user cancels the picker, selectedFileSystemName
    // will be empty.
    // A user gesture is required for the dialog to display. Without a user
    // gesture, the callback will run as though the user canceled.
    static void addUserSelectedFolder(AddUserFolderCallback callback);

    // Give up access to a given media gallery.
    [nodefine, deprecated="The user can manually drop access to galleries
    via the permissions dialog."]
    static void dropPermissionForMediaFileSystem(
        DOMString galleryId,
        optional DropPermissionForMediaFileSystemCallback callback);

    // Start a scan of the user's hard disks for directories containing media.
    // The scan may take a long time so progress and completion is communicated
    // by events. No permission is granted as a result of the scan, see
    // addScanResults.
    [nodefine, deprecated="The mediaGalleries API no longer supports scanning."]
    static void startMediaScan();

    // Cancel any pending media scan.  Well behaved apps should provide a way
    // for the user to cancel scans they start.
    [nodefine, deprecated="The mediaGalleries API no longer supports scanning."]
    static void cancelMediaScan();

    // Show the user the scan results and let them add any or all of them as
    // galleries. This should be used after the 'finish' onScanProgress()
    // event has happened. All galleries the app has access to are returned, not
    // just the newly added galleries.
    [nodefine, deprecated="The mediaGalleries API no longer supports scanning."]
    static void addScanResults(MediaFileSystemsCallback callback);

    // Get metadata about a specific media file system.
    [nocompile] static MediaFileSystemMetadata getMediaFileSystemMetadata(
        [instanceOf=DOMFileSystem] object mediaFileSystem);

    // Get metadata for all available media galleries.
    [nodefine, deprecated="Use getMediaFileSystemMetadata instead."]
    static void getAllMediaFileSystemMetadata(
        MediaFileSystemsMetadataCallback callback);

    // Gets the media-specific metadata for a media file. This should work
    // for files in media galleries as well as other DOM filesystems.
    static void getMetadata([instanceOf=Blob] object mediaFile,
                            optional MediaMetadataOptions options,
                            MediaMetadataCallback callback);

    // Adds a gallery watch for the gallery with the specified gallery ID.
    // The given callback is then fired with a success or failure result.
    static void addGalleryWatch(DOMString galleryId,
                                AddGalleryWatchCallback callback);

    // Removes a gallery watch for the gallery with the specified gallery ID.
    static void removeGalleryWatch(DOMString galleryId);

    // Notifies which galleries are being watched via the given callback.
    [nodefine, deprecated="Applications should store their own gallery watches
    as they are added."]
    static void getAllGalleryWatch(GetAllGalleryWatchCallback callback);

    // Removes all gallery watches.
    [nodefine, deprecated="Use removeGalleryWatch instead."]
    static void removeAllGalleryWatch();
  };

  interface Events {
    // Fired when a media gallery is changed or a gallery watch is dropped.
    static void onGalleryChanged(GalleryChangeDetails details);

    // The pending media scan has changed state. See details for more
    // information.
    [nodefine, deprecated="The mediaGalleries API no longer supports scanning."]
    static void onScanProgress(ScanProgressDetails details);
  };
};
