// Copyright 2015 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.
/**
 * @unrestricted
 */
export default class DeviceModeView extends UI.VBox {
  constructor() {
    super(true);
    this.setMinimumSize(150, 150);
    this.element.classList.add('device-mode-view');
    this.registerRequiredCSS('emulation/deviceModeView.css');
    UI.Tooltip.addNativeOverrideContainer(this.contentElement);

    this._model = self.singleton(Emulation.DeviceModeModel);
    this._model.addEventListener(Emulation.DeviceModeModel.Events.Updated, this._updateUI, this);
    this._mediaInspector = new Emulation.MediaQueryInspector(
        () => this._model.appliedDeviceSize().width, this._model.setWidth.bind(this._model));
    this._showMediaInspectorSetting = Common.settings.moduleSetting('showMediaQueryInspector');
    this._showMediaInspectorSetting.addChangeListener(this._updateUI, this);
    this._showRulersSetting = Common.settings.moduleSetting('emulation.showRulers');
    this._showRulersSetting.addChangeListener(this._updateUI, this);

    this._topRuler = new Emulation.DeviceModeView.Ruler(true, this._model.setWidthAndScaleToFit.bind(this._model));
    this._topRuler.element.classList.add('device-mode-ruler-top');
    this._leftRuler = new Emulation.DeviceModeView.Ruler(false, this._model.setHeightAndScaleToFit.bind(this._model));
    this._leftRuler.element.classList.add('device-mode-ruler-left');
    this._createUI();
    UI.zoomManager.addEventListener(UI.ZoomManager.Events.ZoomChanged, this._zoomChanged, this);
  }

  _createUI() {
    this._toolbar =
        new Emulation.DeviceModeToolbar(this._model, this._showMediaInspectorSetting, this._showRulersSetting);
    this.contentElement.appendChild(this._toolbar.element());

    this._contentClip = this.contentElement.createChild('div', 'device-mode-content-clip vbox');
    this._responsivePresetsContainer = this._contentClip.createChild('div', 'device-mode-presets-container');
    this._populatePresetsContainer();
    this._mediaInspectorContainer = this._contentClip.createChild('div', 'device-mode-media-container');
    this._contentArea = this._contentClip.createChild('div', 'device-mode-content-area');

    this._outlineImage = this._contentArea.createChild('img', 'device-mode-outline-image hidden fill');
    this._outlineImage.addEventListener('load', this._onImageLoaded.bind(this, this._outlineImage, true), false);
    this._outlineImage.addEventListener('error', this._onImageLoaded.bind(this, this._outlineImage, false), false);

    this._screenArea = this._contentArea.createChild('div', 'device-mode-screen-area');
    this._screenImage = this._screenArea.createChild('img', 'device-mode-screen-image hidden');
    this._screenImage.addEventListener('load', this._onImageLoaded.bind(this, this._screenImage, true), false);
    this._screenImage.addEventListener('error', this._onImageLoaded.bind(this, this._screenImage, false), false);

    this._bottomRightResizerElement =
        this._screenArea.createChild('div', 'device-mode-resizer device-mode-bottom-right-resizer');
    this._bottomRightResizerElement.createChild('div', '');
    this._createResizer(this._bottomRightResizerElement, 2, 1);

    this._bottomLeftResizerElement =
        this._screenArea.createChild('div', 'device-mode-resizer device-mode-bottom-left-resizer');
    this._bottomLeftResizerElement.createChild('div', '');
    this._createResizer(this._bottomLeftResizerElement, -2, 1);

    this._rightResizerElement = this._screenArea.createChild('div', 'device-mode-resizer device-mode-right-resizer');
    this._rightResizerElement.createChild('div', '');
    this._createResizer(this._rightResizerElement, 2, 0);

    this._leftResizerElement = this._screenArea.createChild('div', 'device-mode-resizer device-mode-left-resizer');
    this._leftResizerElement.createChild('div', '');
    this._createResizer(this._leftResizerElement, -2, 0);

    this._bottomResizerElement = this._screenArea.createChild('div', 'device-mode-resizer device-mode-bottom-resizer');
    this._bottomResizerElement.createChild('div', '');
    this._createResizer(this._bottomResizerElement, 0, 1);
    this._bottomResizerElement.addEventListener('dblclick', this._model.setHeight.bind(this._model, 0), false);
    this._bottomResizerElement.title = Common.UIString('Double-click for full height');

    this._pageArea = this._screenArea.createChild('div', 'device-mode-page-area');
    this._pageArea.createChild('slot');
  }

  _populatePresetsContainer() {
    const sizes = [320, 375, 425, 768, 1024, 1440, 2560];
    const titles = [
      Common.UIString('Mobile S'), Common.UIString('Mobile M'), Common.UIString('Mobile L'), Common.UIString('Tablet'),
      Common.UIString('Laptop'), Common.UIString('Laptop L'), Common.UIString('4K')
    ];
    this._presetBlocks = [];
    const inner = this._responsivePresetsContainer.createChild('div', 'device-mode-presets-container-inner');
    for (let i = sizes.length - 1; i >= 0; --i) {
      const outer = inner.createChild('div', 'fill device-mode-preset-bar-outer');
      const block = outer.createChild('div', 'device-mode-preset-bar');
      block.createChild('span').textContent = titles[i] + ' \u2013 ' + sizes[i] + 'px';
      block.addEventListener('click', applySize.bind(this, sizes[i]), false);
      block.__width = sizes[i];
      this._presetBlocks.push(block);
    }

    /**
     * @param {number} width
     * @param {!Event} e
     * @this {Emulation.DeviceModeView}
     */
    function applySize(width, e) {
      this._model.emulate(Emulation.DeviceModeModel.Type.Responsive, null, null);
      this._model.setWidthAndScaleToFit(width);
      e.consume();
    }
  }

  /**
   * @param {!Element} element
   * @param {number} widthFactor
   * @param {number} heightFactor
   * @return {!UI.ResizerWidget}
   */
  _createResizer(element, widthFactor, heightFactor) {
    const resizer = new UI.ResizerWidget();
    resizer.addElement(element);
    let cursor = widthFactor ? 'ew-resize' : 'ns-resize';
    if (widthFactor * heightFactor > 0) {
      cursor = 'nwse-resize';
    }
    if (widthFactor * heightFactor < 0) {
      cursor = 'nesw-resize';
    }
    resizer.setCursor(cursor);
    resizer.addEventListener(UI.ResizerWidget.Events.ResizeStart, this._onResizeStart, this);
    resizer.addEventListener(
        UI.ResizerWidget.Events.ResizeUpdate, this._onResizeUpdate.bind(this, widthFactor, heightFactor));
    resizer.addEventListener(UI.ResizerWidget.Events.ResizeEnd, this._onResizeEnd, this);
    return resizer;
  }

  /**
   * @param {!Common.Event} event
   */
  _onResizeStart(event) {
    this._slowPositionStart = null;
    /** @type {!UI.Size} */
    this._resizeStart = this._model.screenRect().size();
  }

  /**
   * @param {number} widthFactor
   * @param {number} heightFactor
   * @param {!Common.Event} event
   */
  _onResizeUpdate(widthFactor, heightFactor, event) {
    if (event.data.shiftKey !== !!this._slowPositionStart) {
      this._slowPositionStart = event.data.shiftKey ? {x: event.data.currentX, y: event.data.currentY} : null;
    }

    let cssOffsetX = event.data.currentX - event.data.startX;
    let cssOffsetY = event.data.currentY - event.data.startY;
    if (this._slowPositionStart) {
      cssOffsetX =
          (event.data.currentX - this._slowPositionStart.x) / 10 + this._slowPositionStart.x - event.data.startX;
      cssOffsetY =
          (event.data.currentY - this._slowPositionStart.y) / 10 + this._slowPositionStart.y - event.data.startY;
    }

    if (widthFactor) {
      const dipOffsetX = cssOffsetX * UI.zoomManager.zoomFactor();
      let newWidth = this._resizeStart.width + dipOffsetX * widthFactor;
      newWidth = Math.round(newWidth / this._model.scale());
      if (newWidth >= Emulation.DeviceModeModel.MinDeviceSize && newWidth <= Emulation.DeviceModeModel.MaxDeviceSize) {
        this._model.setWidth(newWidth);
      }
    }

    if (heightFactor) {
      const dipOffsetY = cssOffsetY * UI.zoomManager.zoomFactor();
      let newHeight = this._resizeStart.height + dipOffsetY * heightFactor;
      newHeight = Math.round(newHeight / this._model.scale());
      if (newHeight >= Emulation.DeviceModeModel.MinDeviceSize &&
          newHeight <= Emulation.DeviceModeModel.MaxDeviceSize) {
        this._model.setHeight(newHeight);
      }
    }
  }

  /**
   * @param {!Common.Event} event
   */
  _onResizeEnd(event) {
    delete this._resizeStart;
    Host.userMetrics.actionTaken(Host.UserMetrics.Action.ResizedViewInResponsiveMode);
  }

  _updateUI() {
    /**
     * @param {!Element} element
     * @param {!UI.Rect} rect
     */
    function applyRect(element, rect) {
      element.style.left = rect.left + 'px';
      element.style.top = rect.top + 'px';
      element.style.width = rect.width + 'px';
      element.style.height = rect.height + 'px';
    }

    if (!this.isShowing()) {
      return;
    }

    const zoomFactor = UI.zoomManager.zoomFactor();
    let callDoResize = false;
    const showRulers = this._showRulersSetting.get() && this._model.type() !== Emulation.DeviceModeModel.Type.None;
    let contentAreaResized = false;
    let updateRulers = false;

    const cssScreenRect = this._model.screenRect().scale(1 / zoomFactor);
    if (!cssScreenRect.isEqual(this._cachedCssScreenRect)) {
      applyRect(this._screenArea, cssScreenRect);
      updateRulers = true;
      callDoResize = true;
      this._cachedCssScreenRect = cssScreenRect;
    }

    const cssVisiblePageRect = this._model.visiblePageRect().scale(1 / zoomFactor);
    if (!cssVisiblePageRect.isEqual(this._cachedCssVisiblePageRect)) {
      applyRect(this._pageArea, cssVisiblePageRect);
      callDoResize = true;
      this._cachedCssVisiblePageRect = cssVisiblePageRect;
    }

    const outlineRect = this._model.outlineRect().scale(1 / zoomFactor);
    if (!outlineRect.isEqual(this._cachedOutlineRect)) {
      applyRect(this._outlineImage, outlineRect);
      callDoResize = true;
      this._cachedOutlineRect = outlineRect;
    }
    this._contentClip.classList.toggle('device-mode-outline-visible', !!this._model.outlineImage());

    const resizable = this._model.type() === Emulation.DeviceModeModel.Type.Responsive;
    if (resizable !== this._cachedResizable) {
      this._rightResizerElement.classList.toggle('hidden', !resizable);
      this._leftResizerElement.classList.toggle('hidden', !resizable);
      this._bottomResizerElement.classList.toggle('hidden', !resizable);
      this._bottomRightResizerElement.classList.toggle('hidden', !resizable);
      this._bottomLeftResizerElement.classList.toggle('hidden', !resizable);
      this._cachedResizable = resizable;
    }

    const mediaInspectorVisible =
        this._showMediaInspectorSetting.get() && this._model.type() !== Emulation.DeviceModeModel.Type.None;
    if (mediaInspectorVisible !== this._cachedMediaInspectorVisible) {
      if (mediaInspectorVisible) {
        this._mediaInspector.show(this._mediaInspectorContainer);
      } else {
        this._mediaInspector.detach();
      }
      contentAreaResized = true;
      callDoResize = true;
      this._cachedMediaInspectorVisible = mediaInspectorVisible;
    }

    if (showRulers !== this._cachedShowRulers) {
      this._contentClip.classList.toggle('device-mode-rulers-visible', showRulers);
      if (showRulers) {
        this._topRuler.show(this._contentArea);
        this._leftRuler.show(this._contentArea);
      } else {
        this._topRuler.detach();
        this._leftRuler.detach();
      }
      contentAreaResized = true;
      callDoResize = true;
      this._cachedShowRulers = showRulers;
    }

    if (this._model.scale() !== this._cachedScale) {
      updateRulers = true;
      callDoResize = true;
      for (const block of this._presetBlocks) {
        block.style.width = block.__width * this._model.scale() + 'px';
      }
      this._cachedScale = this._model.scale();
    }

    this._toolbar.update();
    this._loadImage(this._screenImage, this._model.screenImage());
    this._loadImage(this._outlineImage, this._model.outlineImage());
    this._mediaInspector.setAxisTransform(this._model.scale());
    if (callDoResize) {
      this.doResize();
    }
    if (updateRulers) {
      this._topRuler.render(this._model.scale());
      this._leftRuler.render(this._model.scale());
      this._topRuler.element.positionAt(
          this._cachedCssScreenRect ? this._cachedCssScreenRect.left : 0,
          this._cachedCssScreenRect ? this._cachedCssScreenRect.top : 0);
      this._leftRuler.element.positionAt(
          this._cachedCssScreenRect ? this._cachedCssScreenRect.left : 0,
          this._cachedCssScreenRect ? this._cachedCssScreenRect.top : 0);
    }
    if (contentAreaResized) {
      this._contentAreaResized();
    }
  }

  /**
   * @param {!Element} element
   * @param {string} srcset
   */
  _loadImage(element, srcset) {
    if (element.getAttribute('srcset') === srcset) {
      return;
    }
    element.setAttribute('srcset', srcset);
    if (!srcset) {
      element.classList.toggle('hidden', true);
    }
  }

  /**
   * @param {!Element} element
   * @param {boolean} success
   */
  _onImageLoaded(element, success) {
    element.classList.toggle('hidden', !success);
  }

  /**
   * @param {!Element} element
   */
  setNonEmulatedAvailableSize(element) {
    if (this._model.type() !== Emulation.DeviceModeModel.Type.None) {
      return;
    }
    const zoomFactor = UI.zoomManager.zoomFactor();
    const rect = element.getBoundingClientRect();
    const availableSize = new UI.Size(Math.max(rect.width * zoomFactor, 1), Math.max(rect.height * zoomFactor, 1));
    this._model.setAvailableSize(availableSize, availableSize);
  }

  _contentAreaResized() {
    const zoomFactor = UI.zoomManager.zoomFactor();
    const rect = this._contentArea.getBoundingClientRect();
    const availableSize = new UI.Size(Math.max(rect.width * zoomFactor, 1), Math.max(rect.height * zoomFactor, 1));
    const preferredSize = new UI.Size(
        Math.max((rect.width - 2 * this._handleWidth) * zoomFactor, 1),
        Math.max((rect.height - this._handleHeight) * zoomFactor, 1));
    this._model.setAvailableSize(availableSize, preferredSize);
  }

  _measureHandles() {
    const hidden = this._rightResizerElement.classList.contains('hidden');
    this._rightResizerElement.classList.toggle('hidden', false);
    this._bottomResizerElement.classList.toggle('hidden', false);
    this._handleWidth = this._rightResizerElement.offsetWidth;
    this._handleHeight = this._bottomResizerElement.offsetHeight;
    this._rightResizerElement.classList.toggle('hidden', hidden);
    this._bottomResizerElement.classList.toggle('hidden', hidden);
  }

  _zoomChanged() {
    delete this._handleWidth;
    delete this._handleHeight;
    if (this.isShowing()) {
      this._measureHandles();
      this._contentAreaResized();
    }
  }

  /**
   * @override
   */
  onResize() {
    if (this.isShowing()) {
      this._contentAreaResized();
    }
  }

  /**
   * @override
   */
  wasShown() {
    this._measureHandles();
    this._toolbar.restore();
  }

  /**
   * @override
   */
  willHide() {
    this._model.emulate(Emulation.DeviceModeModel.Type.None, null, null);
  }

  /**
   * @return {!Promise}
   */
  async captureScreenshot() {
    const screenshot = await this._model.captureScreenshot(false);
    if (screenshot === null) {
      return;
    }

    const pageImage = new Image();
    pageImage.src = 'data:image/png;base64,' + screenshot;
    pageImage.onload = async () => {
      const scale = pageImage.naturalWidth / this._model.screenRect().width;
      const outlineRect = this._model.outlineRect().scale(scale);
      const screenRect = this._model.screenRect().scale(scale);
      const visiblePageRect = this._model.visiblePageRect().scale(scale);
      const contentLeft = screenRect.left + visiblePageRect.left - outlineRect.left;
      const contentTop = screenRect.top + visiblePageRect.top - outlineRect.top;

      const canvas = createElement('canvas');
      canvas.width = Math.floor(outlineRect.width);
      canvas.height = Math.floor(outlineRect.height);
      const ctx = canvas.getContext('2d');
      ctx.imageSmoothingEnabled = false;

      if (this._model.outlineImage()) {
        await this._paintImage(ctx, this._model.outlineImage(), outlineRect.relativeTo(outlineRect));
      }
      if (this._model.screenImage()) {
        await this._paintImage(ctx, this._model.screenImage(), screenRect.relativeTo(outlineRect));
      }
      ctx.drawImage(pageImage, Math.floor(contentLeft), Math.floor(contentTop));
      this._saveScreenshot(canvas);
    };
  }

  /**
   * @return {!Promise}
   */
  async captureFullSizeScreenshot() {
    const screenshot = await this._model.captureScreenshot(true);
    if (screenshot === null) {
      return;
    }
    return this._saveScreenshotBase64(screenshot);
  }

  /**
   * @param {!Protocol.Page.Viewport=} clip
   * @return {!Promise}
   */
  async captureAreaScreenshot(clip) {
    const screenshot = await this._model.captureScreenshot(false, clip);
    if (screenshot === null) {
      return;
    }
    return this._saveScreenshotBase64(screenshot);
  }

  /**
   * @param {string} screenshot
   */
  _saveScreenshotBase64(screenshot) {
    const pageImage = new Image();
    pageImage.src = 'data:image/png;base64,' + screenshot;
    pageImage.onload = () => {
      const canvas = createElement('canvas');
      canvas.width = pageImage.naturalWidth;
      canvas.height = pageImage.naturalHeight;
      const ctx = canvas.getContext('2d');
      ctx.imageSmoothingEnabled = false;
      ctx.drawImage(pageImage, 0, 0);
      this._saveScreenshot(canvas);
    };
  }

  /**
   * @param {!CanvasRenderingContext2D} ctx
   * @param {string} src
   * @param {!UI.Rect} rect
   * @return {!Promise}
   */
  _paintImage(ctx, src, rect) {
    return new Promise(fulfill => {
      const image = new Image();
      image.crossOrigin = 'Anonymous';
      image.srcset = src;
      image.onerror = fulfill;
      image.onload = () => {
        ctx.drawImage(image, rect.left, rect.top, rect.width, rect.height);
        fulfill();
      };
    });
  }

  /**
   * @param {!Element} canvas
   */
  _saveScreenshot(canvas) {
    const url = this._model.inspectedURL();
    let fileName = url ? url.trimURL().removeURLFragment() : '';
    if (this._model.type() === Emulation.DeviceModeModel.Type.Device) {
      fileName += Common.UIString('(%s)', this._model.device().title);
    }
    const link = createElement('a');
    link.download = fileName + '.png';
    canvas.toBlob(blob => {
      link.href = URL.createObjectURL(blob);
      link.click();
    });
  }
}

/**
 * @unrestricted
 */
export class Ruler extends UI.VBox {
  /**
   * @param {boolean} horizontal
   * @param {function(number)} applyCallback
   */
  constructor(horizontal, applyCallback) {
    super();
    this.element.classList.add('device-mode-ruler');
    this._contentElement =
        this.element.createChild('div', 'device-mode-ruler-content').createChild('div', 'device-mode-ruler-inner');
    this._horizontal = horizontal;
    this._scale = 1;
    this._count = 0;
    this._throttler = new Common.Throttler(0);
    this._applyCallback = applyCallback;
  }

  /**
   * @param {number} scale
   */
  render(scale) {
    this._scale = scale;
    this._throttler.schedule(this._update.bind(this));
  }

  /**
   * @override
   */
  onResize() {
    this._throttler.schedule(this._update.bind(this));
  }

  /**
   * @return {!Promise.<?>}
   */
  _update() {
    const zoomFactor = UI.zoomManager.zoomFactor();
    const size = this._horizontal ? this._contentElement.offsetWidth : this._contentElement.offsetHeight;

    if (this._scale !== this._renderedScale || zoomFactor !== this._renderedZoomFactor) {
      this._contentElement.removeChildren();
      this._count = 0;
      this._renderedScale = this._scale;
      this._renderedZoomFactor = zoomFactor;
    }

    const dipSize = size * zoomFactor / this._scale;
    const count = Math.ceil(dipSize / 5);
    let step = 1;
    if (this._scale < 0.8) {
      step = 2;
    }
    if (this._scale < 0.6) {
      step = 4;
    }
    if (this._scale < 0.4) {
      step = 8;
    }
    if (this._scale < 0.2) {
      step = 16;
    }
    if (this._scale < 0.1) {
      step = 32;
    }

    for (let i = count; i < this._count; i++) {
      if (!(i % step)) {
        this._contentElement.lastChild.remove();
      }
    }

    for (let i = this._count; i < count; i++) {
      if (i % step) {
        continue;
      }
      const marker = this._contentElement.createChild('div', 'device-mode-ruler-marker');
      if (i) {
        if (this._horizontal) {
          marker.style.left = (5 * i) * this._scale / zoomFactor + 'px';
        } else {
          marker.style.top = (5 * i) * this._scale / zoomFactor + 'px';
        }
        if (!(i % 20)) {
          const text = marker.createChild('div', 'device-mode-ruler-text');
          text.textContent = i * 5;
          text.addEventListener('click', this._onMarkerClick.bind(this, i * 5), false);
        }
      }
      if (!(i % 10)) {
        marker.classList.add('device-mode-ruler-marker-large');
      } else if (!(i % 5)) {
        marker.classList.add('device-mode-ruler-marker-medium');
      }
    }

    this._count = count;
    return Promise.resolve();
  }

  /**
   * @param {number} size
   */
  _onMarkerClick(size) {
    this._applyCallback.call(null, size);
  }
}

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

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

/**
 * @constructor
 */
Emulation.DeviceModeView = DeviceModeView;

/**
 * @constructor
 */
Emulation.DeviceModeView.Ruler = Ruler;
