/*
 * Copyright (C) 2013 Google 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:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * 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.
 *     * Neither the name of Google Inc. 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 THE COPYRIGHT HOLDERS AND 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 THE COPYRIGHT
 * OWNER OR 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
 */
PerfUI.TimelineOverviewPane = class extends UI.VBox {
  /**
   * @param {string} prefix
   */
  constructor(prefix) {
    super();
    this.element.id = prefix + '-overview-pane';

    this._overviewCalculator = new PerfUI.TimelineOverviewCalculator();
    this._overviewGrid = new PerfUI.OverviewGrid(prefix, this._overviewCalculator);
    this.element.appendChild(this._overviewGrid.element);
    this._cursorArea = this._overviewGrid.element.createChild('div', 'overview-grid-cursor-area');
    this._cursorElement = this._overviewGrid.element.createChild('div', 'overview-grid-cursor-position');
    this._cursorArea.addEventListener('mousemove', this._onMouseMove.bind(this), true);
    this._cursorArea.addEventListener('mouseleave', this._hideCursor.bind(this), true);

    this._overviewGrid.setResizeEnabled(false);
    this._overviewGrid.addEventListener(PerfUI.OverviewGrid.Events.WindowChanged, this._onWindowChanged, this);
    this._overviewGrid.setClickHandler(this._onClick.bind(this));
    this._overviewControls = [];
    this._markers = new Map();

    this._overviewInfo = new PerfUI.TimelineOverviewPane.OverviewInfo(this._cursorElement);
    this._updateThrottler = new Common.Throttler(100);

    this._cursorEnabled = false;
    this._cursorPosition = 0;
    this._lastWidth = 0;
  }

  /**
   * @param {!Event} event
   */
  _onMouseMove(event) {
    if (!this._cursorEnabled) {
      return;
    }
    this._cursorPosition = event.offsetX + event.target.offsetLeft;
    this._cursorElement.style.left = this._cursorPosition + 'px';
    this._cursorElement.style.visibility = 'visible';
    this._overviewInfo.setContent(this._buildOverviewInfo());
  }

  /**
   * @return {!Promise<!DocumentFragment>}
   */
  async _buildOverviewInfo() {
    const document = this.element.ownerDocument;
    const x = this._cursorPosition;
    const elements = await Promise.all(this._overviewControls.map(control => control.overviewInfoPromise(x)));
    const fragment = document.createDocumentFragment();
    elements.remove(null);
    fragment.appendChildren.apply(fragment, elements);
    return fragment;
  }

  _hideCursor() {
    this._cursorElement.style.visibility = 'hidden';
    this._overviewInfo.hide();
  }

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

  /**
   * @override
   */
  willHide() {
    this._overviewInfo.hide();
  }

  /**
   * @override
   */
  onResize() {
    const width = this.element.offsetWidth;
    if (width === this._lastWidth) {
      return;
    }
    this._lastWidth = width;
    this.scheduleUpdate();
  }

  /**
   * @param {!Array.<!PerfUI.TimelineOverview>} overviewControls
   */
  setOverviewControls(overviewControls) {
    for (let i = 0; i < this._overviewControls.length; ++i) {
      this._overviewControls[i].dispose();
    }

    for (let i = 0; i < overviewControls.length; ++i) {
      overviewControls[i].setCalculator(this._overviewCalculator);
      overviewControls[i].show(this._overviewGrid.element);
    }
    this._overviewControls = overviewControls;
    this._update();
  }

  /**
   * @param {number} minimumBoundary
   * @param {number} maximumBoundary
   */
  setBounds(minimumBoundary, maximumBoundary) {
    this._overviewCalculator.setBounds(minimumBoundary, maximumBoundary);
    this._overviewGrid.setResizeEnabled(true);
    this._cursorEnabled = true;
  }

  scheduleUpdate() {
    this._updateThrottler.schedule(process.bind(this));
    /**
     * @this {PerfUI.TimelineOverviewPane}
     * @return {!Promise.<undefined>}
     */
    function process() {
      this._update();
      return Promise.resolve();
    }
  }

  _update() {
    if (!this.isShowing()) {
      return;
    }
    this._overviewCalculator.setDisplayWidth(this._overviewGrid.clientWidth());
    for (let i = 0; i < this._overviewControls.length; ++i) {
      this._overviewControls[i].update();
    }
    this._overviewGrid.updateDividers(this._overviewCalculator);
    this._updateMarkers();
    this._updateWindow();
  }

  /**
   * @param {!Map<number, !Element>} markers
   */
  setMarkers(markers) {
    this._markers = markers;
  }

  _updateMarkers() {
    const filteredMarkers = new Map();
    for (const time of this._markers.keys()) {
      const marker = this._markers.get(time);
      const position = Math.round(this._overviewCalculator.computePosition(time));
      // Limit the number of markers to one per pixel.
      if (filteredMarkers.has(position)) {
        continue;
      }
      filteredMarkers.set(position, marker);
      marker.style.left = position + 'px';
    }
    this._overviewGrid.removeEventDividers();
    this._overviewGrid.addEventDividers(filteredMarkers.valuesArray());
  }

  reset() {
    this._windowStartTime = 0;
    this._windowEndTime = Infinity;
    this._overviewCalculator.reset();
    this._overviewGrid.reset();
    this._overviewGrid.setResizeEnabled(false);
    this._cursorEnabled = false;
    this._hideCursor();
    this._markers = new Map();
    for (const control of this._overviewControls) {
      control.reset();
    }
    this._overviewInfo.hide();
    this.scheduleUpdate();
  }

  /**
   * @param {!Event} event
   * @return {boolean}
   */
  _onClick(event) {
    return this._overviewControls.some(control => control.onClick(event));
  }

  /**
   * @param {!Common.Event} event
   */
  _onWindowChanged(event) {
    if (this._muteOnWindowChanged) {
      return;
    }
    // Always use first control as a time converter.
    if (!this._overviewControls.length) {
      return;
    }

    this._windowStartTime = event.data.rawStartValue;
    this._windowEndTime = event.data.rawEndValue;
    const windowTimes = {startTime: this._windowStartTime, endTime: this._windowEndTime};

    this.dispatchEventToListeners(PerfUI.TimelineOverviewPane.Events.WindowChanged, windowTimes);
  }

  /**
   * @param {number} startTime
   * @param {number} endTime
   */
  setWindowTimes(startTime, endTime) {
    if (startTime === this._windowStartTime && endTime === this._windowEndTime) {
      return;
    }
    this._windowStartTime = startTime;
    this._windowEndTime = endTime;
    this._updateWindow();
    this.dispatchEventToListeners(
        PerfUI.TimelineOverviewPane.Events.WindowChanged, {startTime: startTime, endTime: endTime});
  }

  _updateWindow() {
    if (!this._overviewControls.length) {
      return;
    }
    const absoluteMin = this._overviewCalculator.minimumBoundary();
    const timeSpan = this._overviewCalculator.maximumBoundary() - absoluteMin;
    const haveRecords = absoluteMin > 0;
    const left =
        haveRecords && this._windowStartTime ? Math.min((this._windowStartTime - absoluteMin) / timeSpan, 1) : 0;
    const right = haveRecords && this._windowEndTime < Infinity ? (this._windowEndTime - absoluteMin) / timeSpan : 1;
    this._muteOnWindowChanged = true;
    this._overviewGrid.setWindow(left, right);
    this._muteOnWindowChanged = false;
  }
};

/** @enum {symbol} */
PerfUI.TimelineOverviewPane.Events = {
  WindowChanged: Symbol('WindowChanged')
};

/**
 * @implements {PerfUI.TimelineGrid.Calculator}
 * @unrestricted
 */
PerfUI.TimelineOverviewCalculator = class {
  constructor() {
    this.reset();
  }

  /**
   * @override
   * @param {number} time
   * @return {number}
   */
  computePosition(time) {
    return (time - this._minimumBoundary) / this.boundarySpan() * this._workingArea;
  }

  /**
   * @param {number} position
   * @return {number}
   */
  positionToTime(position) {
    return position / this._workingArea * this.boundarySpan() + this._minimumBoundary;
  }

  /**
   * @param {number} minimumBoundary
   * @param {number} maximumBoundary
   */
  setBounds(minimumBoundary, maximumBoundary) {
    this._minimumBoundary = minimumBoundary;
    this._maximumBoundary = maximumBoundary;
  }

  /**
   * @param {number} clientWidth
   */
  setDisplayWidth(clientWidth) {
    this._workingArea = clientWidth;
  }

  reset() {
    this.setBounds(0, 100);
  }

  /**
   * @override
   * @param {number} value
   * @param {number=} precision
   * @return {string}
   */
  formatValue(value, precision) {
    return Number.preciseMillisToString(value - this.zeroTime(), precision);
  }

  /**
   * @override
   * @return {number}
   */
  maximumBoundary() {
    return this._maximumBoundary;
  }

  /**
   * @override
   * @return {number}
   */
  minimumBoundary() {
    return this._minimumBoundary;
  }

  /**
   * @override
   * @return {number}
   */
  zeroTime() {
    return this._minimumBoundary;
  }

  /**
   * @override
   * @return {number}
   */
  boundarySpan() {
    return this._maximumBoundary - this._minimumBoundary;
  }
};

/**
 * @interface
 */
PerfUI.TimelineOverview = function() {};

PerfUI.TimelineOverview.prototype = {
  /**
   * @param {!Element} parentElement
   * @param {?Element=} insertBefore
   */
  show(parentElement, insertBefore) {},

  update() {},

  dispose() {},

  reset() {},

  /**
   * @param {number} x
   * @return {!Promise<?Element>}
   */
  overviewInfoPromise(x) {},

  /**
   * @param {!Event} event
   * @return {boolean}
   */
  onClick(event) {},
};

/**
 * @implements {PerfUI.TimelineOverview}
 * @unrestricted
 */
PerfUI.TimelineOverviewBase = class extends UI.VBox {
  constructor() {
    super();
    /** @type {?PerfUI.TimelineOverviewCalculator} */
    this._calculator = null;
    this._canvas = this.element.createChild('canvas', 'fill');
    this._context = this._canvas.getContext('2d');
  }

  /** @return {number} */
  width() {
    return this._canvas.width;
  }

  /** @return {number} */
  height() {
    return this._canvas.height;
  }

  /** @return {!CanvasRenderingContext2D} */
  context() {
    return this._context;
  }

  /**
   * @protected
   * @return {?PerfUI.TimelineOverviewCalculator}
   */
  calculator() {
    return this._calculator;
  }

  /**
   * @override
   */
  update() {
    this.resetCanvas();
  }

  /**
   * @override
   */
  dispose() {
    this.detach();
  }

  /**
   * @override
   */
  reset() {
  }

  /**
   * @override
   * @param {number} x
   * @return {!Promise<?Element>}
   */
  overviewInfoPromise(x) {
    return Promise.resolve(/** @type {?Element} */ (null));
  }

  /**
   * @param {!PerfUI.TimelineOverviewCalculator} calculator
   */
  setCalculator(calculator) {
    this._calculator = calculator;
  }

  /**
   * @override
   * @param {!Event} event
   * @return {boolean}
   */
  onClick(event) {
    return false;
  }

  resetCanvas() {
    if (this.element.clientWidth) {
      this.setCanvasSize(this.element.clientWidth, this.element.clientHeight);
    }
  }

  /**
   * @param {number} width
   * @param {number} height
   */
  setCanvasSize(width, height) {
    this._canvas.width = width * window.devicePixelRatio;
    this._canvas.height = height * window.devicePixelRatio;
  }
};

PerfUI.TimelineOverviewPane.OverviewInfo = class {
  /**
   * @param {!Element} anchor
   */
  constructor(anchor) {
    this._anchorElement = anchor;
    this._glassPane = new UI.GlassPane();
    this._glassPane.setPointerEventsBehavior(UI.GlassPane.PointerEventsBehavior.PierceContents);
    this._glassPane.setMarginBehavior(UI.GlassPane.MarginBehavior.Arrow);
    this._glassPane.setSizeBehavior(UI.GlassPane.SizeBehavior.MeasureContent);
    this._visible = false;
    this._element =
        UI.createShadowRootWithCoreStyles(this._glassPane.contentElement, 'perf_ui/timelineOverviewInfo.css')
            .createChild('div', 'overview-info');
  }

  /**
   * @param {!Promise<!DocumentFragment>} contentPromise
   */
  async setContent(contentPromise) {
    this._visible = true;
    const content = await contentPromise;
    if (!this._visible) {
      return;
    }
    this._element.removeChildren();
    this._element.appendChild(content);
    this._glassPane.setContentAnchorBox(this._anchorElement.boxInWindow());
    if (!this._glassPane.isShowing()) {
      this._glassPane.show(/** @type {!Document} */ (this._anchorElement.ownerDocument));
    }
  }

  hide() {
    this._visible = false;
    this._glassPane.hide();
  }
};
