// Copyright 2019 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.

// A class that represents a node of a graph, consisting of the information needed to layout the
// node and display the node. Each node has zero or more ports, including input, output, and param ports.
export class NodeView {
  /**
   * @param {!WebAudio.GraphVisualizer.NodeCreationData} data
   * @param {string} label
   */
  constructor(data, label) {
    this.id = data.nodeId;
    this.type = data.nodeType;
    this.numberOfInputs = data.numberOfInputs;
    this.numberOfOutputs = data.numberOfOutputs;
    this.label = label;

    this.size = {width: 0, height: 0};
    // Position of the center. If null, it means the graph layout has not been computed
    // and this node should not be rendered. It will be set after layouting.
    this.position = null;

    /** @type {!WebAudio.GraphVisualizer.NodeLayout} */
    this._layout = {
      inputPortSectionHeight: 0,
      outputPortSectionHeight: 0,
      maxTextLength: 0,
      totalHeight: 0,
    };
    /** @type {!Map<string, !WebAudio.GraphVisualizer.Port>} */
    this.ports = new Map();

    this._initialize(data);
  }

  /**
   * @param {!WebAudio.GraphVisualizer.NodeCreationData} data
   */
  _initialize(data) {
    this._updateNodeLayoutAfterAddingNode(data);
    this._setupInputPorts();
    this._setupOutputPorts();
  }

  /**
   * Add an AudioParam to this node.
   * Note for @method removeParamPort: removeParamPort is not necessary because it will only happen
   * when the parent NodeView is destroyed. So there is no need to remove port individually
   * when the whole NodeView will be gone.
   * @param {string} paramId
   * @param {string} paramType
   */
  addParamPort(paramId, paramType) {
    const paramPorts = this.getPortsByType(WebAudio.GraphVisualizer.PortTypes.Param);
    const numberOfParams = paramPorts.length;

    const {x, y} = WebAudio.GraphVisualizer.NodeRendererUtility.calculateParamPortXY(
        numberOfParams, this._layout.inputPortSectionHeight);
    this._addPort({
      id: generateParamPortId(this.id, paramId),
      type: WebAudio.GraphVisualizer.PortTypes.Param,
      label: paramType,
      x,
      y,
    });

    this._updateNodeLayoutAfterAddingParam(numberOfParams + 1, paramType);

    // The position of output ports may be changed if adding a param increases the total height.
    this._setupOutputPorts();
  }

  /**
   * @param {!WebAudio.GraphVisualizer.PortTypes} type
   * @return {!Array<!WebAudio.GraphVisualizer.Port>}
   */
  getPortsByType(type) {
    const result = [];
    this.ports.forEach(port => {
      if (port.type === type) {
        result.push(port);
      }
    });
    return result;
  }

  /**
   * Use number of inputs and outputs to compute the layout
   * for text and ports.
   * Credit: This function is mostly borrowed from Audion/
   *      `audion.entryPoints.handleNodeCreated_()`.
   *      https://github.com/google/audion/blob/master/js/entry-points/panel.js
   * @param {!WebAudio.GraphVisualizer.NodeCreationData} data
   */
  _updateNodeLayoutAfterAddingNode(data) {
    // Even if there are no input ports, leave room for the node label.
    const {
      TotalInputPortHeight,
      LeftSideTopPadding,
      BottomPaddingWithoutParam,
      TotalOutputPortHeight,
      NodeLabelFontStyle,
    } = WebAudio.GraphVisualizer.GraphStyles;
    const inputPortSectionHeight = TotalInputPortHeight * Math.max(1, data.numberOfInputs) + LeftSideTopPadding;
    this._layout.inputPortSectionHeight = inputPortSectionHeight;
    this._layout.outputPortSectionHeight = TotalOutputPortHeight * data.numberOfOutputs;

    // Use the max of the left and right side heights as the total height.
    // Include a little padding on the left.
    this._layout.totalHeight =
        Math.max(inputPortSectionHeight + BottomPaddingWithoutParam, this._layout.outputPortSectionHeight);

    // Update max length with node label.
    const nodeLabelLength = measureTextWidth(this.label, NodeLabelFontStyle);
    this._layout.maxTextLength = Math.max(this._layout.maxTextLength, nodeLabelLength);

    this._updateNodeSize();
  }

  /**
   * After adding a param port, update the node layout based on the y value
   * and label length.
   * @param {number} numberOfParams
   * @param {string} paramType
   */
  _updateNodeLayoutAfterAddingParam(numberOfParams, paramType) {
    // The height after adding param ports and input ports.
    // Include a little padding on the left.
    const leftSideMaxHeight = this._layout.inputPortSectionHeight +
        numberOfParams * WebAudio.GraphVisualizer.GraphStyles.TotalParamPortHeight +
        WebAudio.GraphVisualizer.GraphStyles.BottomPaddingWithParam;

    // Use the max of the left and right side heights as the total height.
    this._layout.totalHeight = Math.max(leftSideMaxHeight, this._layout.outputPortSectionHeight);

    // Update max length with param label.
    const paramLabelLength = measureTextWidth(paramType, WebAudio.GraphVisualizer.GraphStyles.ParamLabelFontStyle);
    this._layout.maxTextLength = Math.max(this._layout.maxTextLength, paramLabelLength);

    this._updateNodeSize();
  }

  _updateNodeSize() {
    this.size = {
      width: Math.ceil(
          WebAudio.GraphVisualizer.GraphStyles.LeftMarginOfText + this._layout.maxTextLength +
          WebAudio.GraphVisualizer.GraphStyles.RightMarginOfText),
      height: this._layout.totalHeight,
    };
  }

  // Setup the properties of each input port.
  _setupInputPorts() {
    for (let i = 0; i < this.numberOfInputs; i++) {
      const {x, y} = WebAudio.GraphVisualizer.NodeRendererUtility.calculateInputPortXY(i);
      this._addPort({
        id: generateInputPortId(this.id, i),
        type: WebAudio.GraphVisualizer.PortTypes.In,
        x,
        y,
      });
    }
  }

  // Setup the properties of each output port.
  _setupOutputPorts() {
    for (let i = 0; i < this.numberOfOutputs; i++) {
      const portId = generateOutputPortId(this.id, i);
      const {x, y} =
          WebAudio.GraphVisualizer.NodeRendererUtility.calculateOutputPortXY(i, this.size, this.numberOfOutputs);
      if (this.ports.has(portId)) {
        // Update y value of an existing output port.
        const port = this.ports.get(portId);
        port.x = x;
        port.y = y;
      } else {
        this._addPort({
          id: portId,
          type: WebAudio.GraphVisualizer.PortTypes.Out,
          x,
          y,
        });
      }
    }
  }

  /** @param {!WebAudio.GraphVisualizer.Port} port */
  _addPort(port) {
    this.ports.set(port.id, port);
  }
}

/**
 * Generates the port id for the input of node.
 * @param {string} nodeId
 * @param {number | undefined} inputIndex
 * @return {string}
 */
export const generateInputPortId = (nodeId, inputIndex) => {
  return `${nodeId}-input-${inputIndex || 0}`;
};

/**
 * Generates the port id for the output of node.
 * @param {string} nodeId
 * @param {number | undefined} outputIndex
 * @return {string}
 */
export const generateOutputPortId = (nodeId, outputIndex) => {
  return `${nodeId}-output-${outputIndex || 0}`;
};

/**
 * Generates the port id for the param of node.
 * @param {string} nodeId
 * @param {string} paramId
 * @return {string}
 */
export const generateParamPortId = (nodeId, paramId) => {
  return `${nodeId}-param-${paramId}`;
};

// A label generator to convert UUID of node to shorter label to display.
// Each graph should have its own generator since the node count starts from 0.
export class NodeLabelGenerator {
  constructor() {
    this._totalNumberOfNodes = 0;
  }

  /**
   * Generates the label for a node of a graph.
   * @param {string} nodeType
   * @return {string}
   */
  generateLabel(nodeType) {
    // To make the label concise, remove the suffix "Node" from the nodeType.
    if (nodeType.endsWith('Node')) {
      nodeType = nodeType.slice(0, nodeType.length - 4);
    }

    // Also, use an integer to replace the long UUID.
    this._totalNumberOfNodes += 1;
    const label = `${nodeType} ${this._totalNumberOfNodes}`;
    return label;
  }
}

/**
 * Get the text width using given font style.
 * @param {string} text
 * @param {?string} fontStyle
 * @return {number}
 */
export const measureTextWidth = (text, fontStyle) => {
  if (!WebAudio.GraphVisualizer._contextForFontTextMeasuring) {
    WebAudio.GraphVisualizer._contextForFontTextMeasuring = createElement('canvas').getContext('2d');
  }

  const context = WebAudio.GraphVisualizer._contextForFontTextMeasuring;
  context.save();
  context.font = fontStyle;
  const width = UI.measureTextWidth(context, text);
  context.restore();
  return width;
};


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

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

/* Legacy exported object */
WebAudio.GraphVisualizer = WebAudio.GraphVisualizer || {};

/**
 * @constructor
 */
WebAudio.GraphVisualizer.NodeView = NodeView;

/**
 * @constructor
 */
WebAudio.GraphVisualizer.NodeLabelGenerator = NodeLabelGenerator;

WebAudio.GraphVisualizer.generateInputPortId = generateInputPortId;
WebAudio.GraphVisualizer.generateOutputPortId = generateOutputPortId;
WebAudio.GraphVisualizer.generateParamPortId = generateParamPortId;
WebAudio.GraphVisualizer.measureTextWidth = measureTextWidth;
