/*
 * Copyright (C) 2007, 2008 Apple Inc.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1.  Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 * 2.  Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/**
 * @unrestricted
 */
export class ImageView extends UI.SimpleView {
  /**
   * @param {string} mimeType
   * @param {!Common.ContentProvider} contentProvider
   */
  constructor(mimeType, contentProvider) {
    super(Common.UIString('Image'));
    this.registerRequiredCSS('source_frame/imageView.css');
    this.element.tabIndex = 0;
    this.element.classList.add('image-view');
    this._url = contentProvider.contentURL();
    this._parsedURL = new Common.ParsedURL(this._url);
    this._mimeType = mimeType;
    this._contentProvider = contentProvider;
    this._uiSourceCode = contentProvider instanceof Workspace.UISourceCode ?
        /** @type {!Workspace.UISourceCode} */ (contentProvider) :
        null;
    if (this._uiSourceCode) {
      this._uiSourceCode.addEventListener(
          Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
      new UI.DropTarget(
          this.element, [UI.DropTarget.Type.ImageFile, UI.DropTarget.Type.URI], Common.UIString('Drop image file here'),
          this._handleDrop.bind(this));
    }
    this._sizeLabel = new UI.ToolbarText();
    this._dimensionsLabel = new UI.ToolbarText();
    this._mimeTypeLabel = new UI.ToolbarText(mimeType);
    this._container = this.element.createChild('div', 'image');
    this._imagePreviewElement = this._container.createChild('img', 'resource-image-view');
    this._imagePreviewElement.addEventListener('contextmenu', this._contextMenu.bind(this), true);
    this._imagePreviewElement.alt = ls`Image from ${this._url}`;
  }

  /**
   * @override
   * @return {!Array<!UI.ToolbarItem>}
   */
  syncToolbarItems() {
    return [
      this._sizeLabel, new UI.ToolbarSeparator(), this._dimensionsLabel, new UI.ToolbarSeparator(), this._mimeTypeLabel
    ];
  }

  /**
   * @override
   */
  wasShown() {
    this._updateContentIfNeeded();
  }

  /**
   * @override
   */
  disposeView() {
    if (this._uiSourceCode) {
      this._uiSourceCode.removeEventListener(
          Workspace.UISourceCode.Events.WorkingCopyCommitted, this._workingCopyCommitted, this);
    }
  }

  _workingCopyCommitted() {
    this._updateContentIfNeeded();
  }

  async _updateContentIfNeeded() {
    const {content} = await this._contentProvider.requestContent();
    if (this._cachedContent === content) {
      return;
    }

    const contentEncoded = await this._contentProvider.contentEncoded();
    this._cachedContent = content;
    let imageSrc = Common.ContentProvider.contentAsDataURL(content, this._mimeType, contentEncoded);
    if (content === null) {
      imageSrc = this._url;
    }
    const loadPromise = new Promise(x => this._imagePreviewElement.onload = x);
    this._imagePreviewElement.src = imageSrc;
    const size = content && !contentEncoded ? content.length : base64ToSize(content);
    this._sizeLabel.setText(Number.bytesToString(size));
    await loadPromise;
    this._dimensionsLabel.setText(
        Common.UIString('%d × %d', this._imagePreviewElement.naturalWidth, this._imagePreviewElement.naturalHeight));
  }

  _contextMenu(event) {
    const contextMenu = new UI.ContextMenu(event);
    if (!this._parsedURL.isDataURL()) {
      contextMenu.clipboardSection().appendItem(Common.UIString('Copy image URL'), this._copyImageURL.bind(this));
    }
    if (this._imagePreviewElement.src) {
      contextMenu.clipboardSection().appendItem(
          Common.UIString('Copy image as data URI'), this._copyImageAsDataURL.bind(this));
    }

    contextMenu.clipboardSection().appendItem(Common.UIString('Open image in new tab'), this._openInNewTab.bind(this));
    contextMenu.clipboardSection().appendItem(Common.UIString('Save\u2026'), this._saveImage.bind(this));
    contextMenu.show();
  }

  _copyImageAsDataURL() {
    Host.InspectorFrontendHost.copyText(this._imagePreviewElement.src);
  }

  _copyImageURL() {
    Host.InspectorFrontendHost.copyText(this._url);
  }

  _saveImage() {
    const link = createElement('a');
    link.download = this._parsedURL.displayName;
    link.href = this._url;
    link.click();
  }

  _openInNewTab() {
    Host.InspectorFrontendHost.openInNewTab(this._url);
  }

  /**
   * @param {!DataTransfer} dataTransfer
   */
  async _handleDrop(dataTransfer) {
    const items = dataTransfer.items;
    if (!items.length || items[0].kind !== 'file') {
      return;
    }

    const entry = items[0].webkitGetAsEntry();
    const encoded = !entry.name.endsWith('.svg');
    entry.file(file => {
      const reader = new FileReader();
      reader.onloadend = () => {
        let result;
        try {
          result = /** @type {?string} */ (reader.result);
        } catch (e) {
          result = null;
          console.error('Can\'t read file: ' + e);
        }
        if (typeof result !== 'string') {
          return;
        }
        this._uiSourceCode.setContent(encoded ? btoa(result) : result, encoded);
      };
      if (encoded) {
        reader.readAsBinaryString(file);
      } else {
        reader.readAsText(file);
      }
    });
  }
}

/* Legacy exported object */
self.SourceFrame = self.SourceFrame || {};

/* Legacy exported object */
SourceFrame = SourceFrame || {};

/** @constructor */
SourceFrame.ImageView = ImageView;
