// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import {isString} from '../base/object_utils';
import {globals} from '../frontend/globals';

export function cropText(str: string, charWidth: number, rectWidth: number) {
  let displayText = '';
  const maxLength = Math.floor(rectWidth / charWidth) - 1;
  if (str.length <= maxLength) {
    displayText = str;
  } else {
    let limit = maxLength;
    let maybeTripleDot = '';
    if (maxLength > 1) {
      limit = maxLength - 1;
      maybeTripleDot = '\u2026';
    }
    // Javascript strings are UTF-16. |limit| could point in the middle of a
    // 32-bit double-wchar codepoint (e.g., an emoji). Here we detect if the
    // |limit|-th wchar is a leading surrogate and attach the trailing one.
    const lastCharCode = str.charCodeAt(limit - 1);
    limit += (lastCharCode >= 0xD800 && lastCharCode < 0xDC00) ? 1 : 0;
    displayText = str.substring(0, limit) + maybeTripleDot;
  }
  return displayText;
}

export function drawDoubleHeadedArrow(
  ctx: CanvasRenderingContext2D,
  x: number,
  y: number,
  length: number,
  showArrowHeads: boolean,
  width = 2,
  color = 'black') {
  ctx.beginPath();
  ctx.lineWidth = width;
  ctx.lineCap = 'round';
  ctx.strokeStyle = color;
  ctx.moveTo(x, y);
  ctx.lineTo(x + length, y);
  ctx.stroke();
  ctx.closePath();
  // Arrowheads on the each end of the line.
  if (showArrowHeads) {
    ctx.beginPath();
    ctx.moveTo(x + length - 8, y - 4);
    ctx.lineTo(x + length, y);
    ctx.lineTo(x + length - 8, y + 4);
    ctx.stroke();
    ctx.closePath();
    ctx.beginPath();
    ctx.moveTo(x + 8, y - 4);
    ctx.lineTo(x, y);
    ctx.lineTo(x + 8, y + 4);
    ctx.stroke();
    ctx.closePath();
  }
}

export function drawIncompleteSlice(
  ctx: CanvasRenderingContext2D,
  x: number,
  y: number,
  width: number,
  height: number,
  showGradient: boolean = true) {
  if (width <= 0 || height <= 0) {
    return;
  }
  ctx.beginPath();
  const triangleSize = height / 4;
  ctx.moveTo(x, y);
  ctx.lineTo(x + width, y);
  ctx.lineTo(x + width - 3, y + triangleSize * 0.5);
  ctx.lineTo(x + width, y + triangleSize);
  ctx.lineTo(x + width - 3, y + (triangleSize * 1.5));
  ctx.lineTo(x + width, y + 2 * triangleSize);
  ctx.lineTo(x + width - 3, y + (triangleSize * 2.5));
  ctx.lineTo(x + width, y + 3 * triangleSize);
  ctx.lineTo(x + width - 3, y + (triangleSize * 3.5));
  ctx.lineTo(x + width, y + 4 * triangleSize);
  ctx.lineTo(x, y + height);

  const fillStyle = ctx.fillStyle;
  if (isString(fillStyle)) {
    if (showGradient) {
      const gradient = ctx.createLinearGradient(x, y, x + width, y + height);
      gradient.addColorStop(0.66, fillStyle);
      gradient.addColorStop(1, '#FFFFFF');
      ctx.fillStyle = gradient;
    }
  } else {
    throw new Error(
      `drawIncompleteSlice() expects fillStyle to be a simple color not ${
        fillStyle}`);
  }

  ctx.fill();
  ctx.fillStyle = fillStyle;
}

export function drawTrackHoverTooltip(
  ctx: CanvasRenderingContext2D,
  pos: {x: number, y: number},
  maxHeight: number,
  text: string,
  text2?: string) {
  ctx.font = '10px Roboto Condensed';
  ctx.textBaseline = 'middle';
  ctx.textAlign = 'left';

  // TODO(hjd): Avoid measuring text all the time (just use monospace?)
  const textMetrics = ctx.measureText(text);
  const text2Metrics = ctx.measureText(text2 || '');

  // Padding on each side of the box containing the tooltip:
  const paddingPx = 4;

  // Figure out the width of the tool tip box:
  let width = Math.max(textMetrics.width, text2Metrics.width);
  width += paddingPx * 2;

  // and the height:
  let height = 0;
  height += textMetrics.fontBoundingBoxAscent;
  height += textMetrics.fontBoundingBoxDescent;
  if (text2 !== undefined) {
    height += text2Metrics.fontBoundingBoxAscent;
    height += text2Metrics.fontBoundingBoxDescent;
  }
  height += paddingPx * 2;

  let x = pos.x;
  let y = pos.y;

  // Move box to the top right of the mouse:
  x += 10;
  y -= 10;

  // Ensure the box is on screen:
  const endPx = globals.timeline.visibleTimeScale.pxSpan.end;
  if (x + width > endPx) {
    x -= x + width - endPx;
  }
  if (y < 0) {
    y = 0;
  }
  if (y + height > maxHeight) {
    y -= y + height - maxHeight;
  }

  // Draw everything:
  ctx.fillStyle = 'rgba(255, 255, 255, 0.9)';
  ctx.fillRect(x, y, width, height);

  ctx.fillStyle = 'hsl(200, 50%, 40%)';
  ctx.fillText(
    text, x + paddingPx, y + paddingPx + textMetrics.fontBoundingBoxAscent);
  if (text2 !== undefined) {
    const yOffsetPx = textMetrics.fontBoundingBoxAscent +
        textMetrics.fontBoundingBoxDescent + text2Metrics.fontBoundingBoxAscent;
    ctx.fillText(text2, x + paddingPx, y + paddingPx + yOffsetPx);
  }
}

export function canvasClip(
  ctx: CanvasRenderingContext2D,
  x: number,
  y: number,
  w: number,
  h: number): void {
  ctx.beginPath();
  ctx.rect(x, y, w, h);
  ctx.clip();
}
