/* COPYRIGHT Esri - https://js.arcgis.com/5.1/LICENSE.txt */
import { c as customElement } from "../../chunks/runtime.js";
import { css, html, svg } from "lit";
import { LitElement, nothing, safeClassMap } from "@arcgis/lumina";
import { g as guid } from "../../chunks/guid.js";
import { c as createObserver } from "../../chunks/observers.js";
function slope(p0, p1, p2) {
  const dx = p1[0] - p0[0];
  const dx1 = p2[0] - p1[0];
  const dy = p1[1] - p0[1];
  const dy1 = p2[1] - p1[1];
  const m = dy / (dx || dx1 < 0 && 0);
  const m1 = dy1 / (dx1 || dx < 0 && 0);
  const p = (m * dx1 + m1 * dx) / (dx + dx1);
  return (Math.sign(m) + Math.sign(m1)) * Math.min(Math.abs(m), Math.abs(m1), 0.5 * Math.abs(p)) || 0;
}
function slopeSingle(p0, p1, m) {
  const dx = p1[0] - p0[0];
  const dy = p1[1] - p0[1];
  return dx ? (3 * dy / dx - m) / 2 : m;
}
function bezier(p0, p1, m0, m1, t) {
  const [x0, y0] = p0;
  const [x1, y1] = p1;
  const dx = (x1 - x0) / 3;
  const h1 = t([x0 + dx, y0 + dx * m0]).join(",");
  const h2 = t([x1 - dx, y1 - dx * m1]).join(",");
  const p = t([x1, y1]).join(",");
  return `C ${h1} ${h2} ${p}`;
}
function translate({ width, height, min, max }) {
  const rangeX = max[0] - min[0];
  const rangeY = max[1] - min[1];
  return (point) => {
    const x = (point[0] - min[0]) / rangeX * width;
    const y = height - (point[1] - min[1]) / rangeY * height;
    return [x, y];
  };
}
function range(data) {
  const [startX, startY] = data[0];
  const min = [startX, startY];
  const max = [startX, startY];
  return data.reduce(
    ({ min: min2, max: max2 }, [x, y]) => ({
      min: [Math.min(min2[0], x), Math.min(min2[1], y)],
      max: [Math.max(max2[0], x), Math.max(max2[1], y)]
    }),
    { min, max }
  );
}
function area({ data, min, max, t }) {
  if (data.length === 0) {
    return "";
  }
  const [startX, startY] = t(data[0]);
  const [minX, minY] = t(min);
  const [maxX] = t(max);
  let m;
  let p0;
  let p1;
  const commands = data.reduce((acc, point, i) => {
    p0 = data[i - 2];
    p1 = data[i - 1];
    if (i > 1) {
      const m1 = slope(p0, p1, point);
      const m0 = m === void 0 ? slopeSingle(p0, p1, m1) : m;
      const command = bezier(p0, p1, m0, m1, t);
      m = m1;
      return `${acc} ${command}`;
    }
    return acc;
  }, `M ${minX},${minY} L ${minX},${startY} L ${startX},${startY}`);
  const last = data[data.length - 1];
  const end = bezier(p1, last, m, slopeSingle(p1, last, m), t);
  return `${commands} ${end} L ${maxX},${minY} Z`;
}
const styles = css`:host{display:block;block-size:100%}.svg{fill:currentColor;stroke:transparent;margin:0;display:block;block-size:100%;inline-size:100%;padding:0}.svg .graph-path--highlight{fill:var(--calcite-graph-highlight-fill-color, var(--calcite-color-brand));opacity:.5}:host([hidden]){display:none}[hidden]{display:none}`;
const CSS = {
  svg: "svg",
  graphPath: "graph-path",
  graphPathHighlight: "graph-path--highlight"
};
const idPrefix = "calcite-graph";
const IDS = {
  host: (id) => `${idPrefix}-${id}`,
  linearGradient: (id) => `linear-gradient-${idPrefix}-${id}`,
  mask: (id, maskId) => `${idPrefix}-${id}${maskId}`
};
class Graph extends LitElement {
  constructor() {
    super(...arguments);
    this.graphId = guid();
    this.resizeObserver = createObserver("resize", () => this.requestUpdate());
    this.data = [];
  }
  static {
    this.properties = { colorStops: [0, {}, { attribute: false }], data: [0, {}, { attribute: false }], highlightMax: [9, {}, { type: Number }], highlightMin: [9, {}, { type: Number }], max: [11, {}, { reflect: true, type: Number }], min: [11, {}, { reflect: true, type: Number }] };
  }
  static {
    this.styles = styles;
  }
  connectedCallback() {
    super.connectedCallback();
    this.resizeObserver?.observe(this.el);
  }
  disconnectedCallback() {
    super.disconnectedCallback();
    this.resizeObserver?.disconnect();
  }
  render() {
    const { data, colorStops, el, highlightMax, highlightMin, min, max } = this;
    const id = this.graphId;
    const { clientHeight: height, clientWidth: width } = el;
    if (!data || data.length === 0) {
      return html`<svg aria-hidden=true class=${safeClassMap(CSS.svg)} height=${height ?? nothing} preserveAspectRatio=none viewBox=${`0 0 ${width} ${height}`} width=${width ?? nothing}></svg>`;
    }
    const { min: rangeMin, max: rangeMax } = range(data);
    let currentMin = rangeMin;
    let currentMax = rangeMax;
    if (min < rangeMin[0] || min > rangeMin[0]) {
      currentMin = [min, 0];
    }
    if (max > rangeMax[0] || max < rangeMax[0]) {
      currentMax = [max, rangeMax[1]];
    }
    const t = translate({ min: currentMin, max: currentMax, width, height });
    const [hMinX] = t([highlightMin, currentMax[1]]);
    const [hMaxX] = t([highlightMax, currentMax[1]]);
    const areaPath = area({ data, min: rangeMin, max: rangeMax, t });
    const fill = colorStops ? `url(#${IDS.linearGradient(id)})` : void 0;
    return html`<svg aria-hidden=true class=${safeClassMap(CSS.svg)} height=${height ?? nothing} preserveAspectRatio=none viewBox=${`0 0 ${width} ${height}`} width=${width ?? nothing}>${colorStops ? svg`<defs><linearGradient id=${IDS.linearGradient(id) ?? nothing} x1=0 x2=1 y1=0 y2=0>${colorStops.map(({ offset, color, opacity }) => svg`<stop offset=${`${offset * 100}%`} stop-color=${color ?? nothing} stop-opacity=${opacity ?? nothing} />`)}</linearGradient></defs>` : null}${highlightMin !== void 0 ? [
      svg`<mask height=100% id=${IDS.mask(id, 1) ?? nothing} width=100% x=0% y=0%><path d=${`
            M 0,0
            L ${hMinX - 1},0
            L ${hMinX - 1},${height}
            L 0,${height}
            Z
          `} fill=white /></mask>`,
      svg`<mask height=100% id=${IDS.mask(id, 2) ?? nothing} width=100% x=0% y=0%><path d=${`
            M ${hMinX + 1},0
            L ${hMaxX - 1},0
            L ${hMaxX - 1},${height}
            L ${hMinX + 1}, ${height}
            Z
          `} fill=white /></mask>`,
      svg`<mask height=100% id=${IDS.mask(id, 3) ?? nothing} width=100% x=0% y=0%><path d=${`
                M ${hMaxX + 1},0
                L ${width},0
                L ${width},${height}
                L ${hMaxX + 1}, ${height}
                Z
              `} fill=white /></mask>`,
      svg`<path class=${safeClassMap(CSS.graphPath)} d=${areaPath ?? nothing} fill=${fill ?? nothing} mask=${`url(#${IDS.mask(id, 1)})`} />`,
      svg`<path class=${safeClassMap(CSS.graphPathHighlight)} d=${areaPath ?? nothing} fill=${fill ?? nothing} mask=${`url(#${IDS.mask(id, 2)})`} />`,
      svg`<path class=${safeClassMap(CSS.graphPath)} d=${areaPath ?? nothing} fill=${fill ?? nothing} mask=${`url(#${IDS.mask(id, 3)})`} />`
    ] : svg`<path class=${safeClassMap(CSS.graphPath)} d=${areaPath ?? nothing} fill=${fill ?? nothing} />`}</svg>`;
  }
}
customElement("calcite-graph", Graph);
export {
  Graph
};
