/**
 * @module skottie-sk
 * @description <h2><code>skottie-sk</code></h2>
 *
 * <p>
 *   The main application element for skottie.
 * </p>
 *
 */
import '../skottie-config-sk';
import '../skottie-player-sk';
import '../../../elements-sk/modules/checkbox-sk';
import '../../../elements-sk/modules/collapse-sk';
import '../../../elements-sk/modules/error-toast-sk';
import { html, TemplateResult } from 'lit-html';
import JSONEditor from 'jsoneditor';
import LottiePlayer from 'lottie-web';
import { $$ } from '../../../infra-sk/modules/dom';
import { errorMessage } from '../../../elements-sk/modules/errorMessage';
import { define } from '../../../elements-sk/modules/define';
import { jsonOrThrow } from '../../../infra-sk/modules/jsonOrThrow';
import { stateReflector } from '../../../infra-sk/modules/stateReflector';
import { CollapseSk } from '../../../elements-sk/modules/collapse-sk/collapse-sk';
import { SkottieGifExporterSk } from '../skottie-gif-exporter-sk/skottie-gif-exporter-sk';
import '../skottie-gif-exporter-sk';
import '../skottie-text-editor-sk';
import { replaceTexts } from '../skottie-text-editor-sk/text-replace';
import '../skottie-library-sk';
import { SoundMap, AudioPlayer } from '../audio';
import '../skottie-performance-sk';
import { renderByDomain } from '../helpers/templates';
import { isDomain, supportedDomains } from '../helpers/domains';
import '../skottie-audio-sk';
import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import {
  SkottieConfigEventDetail,
  SkottieConfigState,
} from '../skottie-config-sk/skottie-config-sk';
import { SkottiePlayerSk } from '../skottie-player-sk/skottie-player-sk';
import { SkottiePerformanceSk } from '../skottie-performance-sk/skottie-performance-sk';
import { FontAsset, LottieAnimation, LottieAsset, ViewMode } from '../types';
import { SkottieLibrarySk } from '../skottie-library-sk/skottie-library-sk';
import {
  AudioStartEventDetail,
  SkottieAudioSk,
} from '../skottie-audio-sk/skottie-audio-sk';
import {
  SkottieTextEditorSk,
  TextEditApplyEventDetail,
} from '../skottie-text-editor-sk/skottie-text-editor-sk';
import '../skottie-shader-editor-sk';
import {
  ShaderEditApplyEventDetail,
  ShaderEditorSk,
} from '../skottie-shader-editor-sk/skottie-shader-editor-sk';
import '../../../infra-sk/modules/theme-chooser-sk';
import '../../../infra-sk/modules/app-sk';
import { replaceShaders } from '../skottie-shader-editor-sk/shader-replace';
import '../../../elements-sk/modules/icons/expand-less-icon-sk';
import '../../../elements-sk/modules/icons/expand-more-icon-sk';
import '../../../elements-sk/modules/icons/play-arrow-icon-sk';
import '../../../elements-sk/modules/icons/pause-icon-sk';
import '../../../elements-sk/modules/icons/replay-icon-sk';
import '../../../elements-sk/modules/icons/file-download-icon-sk';
import '../skottie-button-sk';
import '../skottie-dropdown-sk';
import { DropdownSelectEvent } from '../skottie-dropdown-sk/skottie-dropdown-sk';
import '../skottie-exporter-sk';
import {
  ExportType,
  SkottieExporterSk,
} from '../skottie-exporter-sk/skottie-exporter-sk';
import '../skottie-file-settings-sk';
import {
  SkottieFileSettingsSk,
  SkottieFileSettingsEventDetail,
} from '../skottie-file-settings-sk/skottie-file-settings-sk';
import '../skottie-file-form-sk';
import { SkottieFilesEventDetail } from '../skottie-file-form-sk/skottie-file-form-sk';
import '../skottie-background-settings-sk';
import { SkottieBackgroundSettingsEventDetail } from '../skottie-background-settings-sk/skottie-background-settings-sk';

// It is assumed that this symbol is being provided by a version.js file loaded in before this
// file.
declare const SKIA_VERSION: string;

interface BodymovinPlayer {
  goToAndStop(t: number): void;
  goToAndPlay(t: number): void;
  pause(): void;
  play(): void;
}

interface LottieLibrary {
  version: string;
  loadAnimation(opts: Record<string, unknown>): BodymovinPlayer;
}

interface LoadedAsset {
  name: string;
  bytes?: ArrayBuffer;
  player?: AudioPlayer;
}

const GOOGLE_WEB_FONTS_HOST =
  'https://storage.googleapis.com/skia-cdn/google-web-fonts';

const PRODUCTION_ASSETS_PATH = '/_/a';

// Make this the hash of the lottie file you want to play on startup.
const DEFAULT_LOTTIE_FILE = '1112d01d28a776d777cebcd0632da15b'; // gear.json

// SCRUBBER_RANGE is the input range for the scrubbing control.
// This is an arbitrary value, and is treated as a re-scaled duration.
const SCRUBBER_RANGE = 1000;

const AUDIO_SUPPORTED_DOMAINS = [
  supportedDomains.SKOTTIE_INTERNAL,
  supportedDomains.SKOTTIE_TENOR,
  supportedDomains.LOCALHOST,
];

type UIMode = 'dialog' | 'loading' | 'loaded' | 'idle';

const caption = (text: string, mode: ViewMode) => {
  if (mode === 'presentation') {
    return null;
  }
  return html` <figcaption>${text}</figcaption> `;
};

const redir = () =>
  renderByDomain(
    html` <div>
      Googlers should use
      <a href="https://skottie-internal.skia.org">skottie-internal.skia.org</a>.
    </div>`,
    Object.values(supportedDomains).filter(
      (domain: string) => domain !== supportedDomains.SKOTTIE_INTERNAL
    )
  );

const displayLoading = () => html`
  <div class="loading">
    <spinner-sk active></spinner-sk><span>Loading...</span>
  </div>
`;

export class SkottieSk extends ElementSk {
  private static template = (ele: SkottieSk) => html`
    <app-sk>
      <div class="app-container">
        <header>
          <h2>Skottie Web Player</h2>
          <span>
            <a
              href="https://skia.googlesource.com/skia/+show/${SKIA_VERSION}"
              class="header__skia-version"
            >
              ${SKIA_VERSION.slice(0, 7)}
            </a>

            <skottie-dropdown-sk
              id="view-exporter"
              .name="dropdown-exporter"
              .options=${[
                { id: '', value: 'Export' },
                { id: 'gif', value: 'GIF' },
                { id: 'webM', value: 'WebM' },
                { id: 'png', value: 'PNG sequence' },
              ]}
              reset
              @select=${ele.exportSelectHandler}
              border
            >
            </skottie-dropdown-sk>
            <skottie-button-sk
              id="view-perf-chart"
              @select=${ele.togglePerformanceChart}
              type="outline"
              .content=${'Performance chart'}
              .classes=${['header__button']}
            >
            </skottie-button-sk>
            <skottie-button-sk
              id="view-json-layers"
              @select=${ele.toggleEditor}
              type="outline"
              .content=${'View JSON code'}
              .classes=${['header__button']}
            >
            </skottie-button-sk>

            <theme-chooser-sk></theme-chooser-sk>
          </span>
        </header>
        <main>${ele.pick()}</main>
        <footer>
          <error-toast-sk></error-toast-sk>
          ${redir()}
        </footer>
      </div>
      <skottie-exporter-sk @start=${ele.onExportStart}></skottie-exporter-sk>
    </app-sk>
  `;

  // pick the right part of the UI to display based on ele._ui.
  private pick = () => {
    switch (this.ui) {
      default:
      case 'dialog':
        return this.displayDialog();
      case 'idle':
        return this.displayIdle();
      case 'loading':
        return displayLoading();
      case 'loaded':
        return this.displayLoaded();
    }
  };

  private displayDialog = () => html`
    <skottie-config-sk
      .state=${this.state}
      .width=${this.width}
      .height=${this.height}
      .fps=${this.fps}
      .backgroundColor=${this.backgroundColor}
      @skottie-selected=${this.skottieFileSelected}
      @cancelled=${this.selectionCancelled}
    ></skottie-config-sk>
  `;

  private displayIdle = () => html`
    <div class="threecol">
      <div class="left">${this.leftControls()}</div>
      <div class="main"></div>
      <div class="right">${this.rightControls()}</div>
    </div>
  `;

  private displayLoaded = () => html`
    <div class="threecol">
      <div class="left">${this.leftControls()}</div>
      <div class="main">${this.mainContent()}</div>
      <div class="right">${this.rightControls()}</div>
    </div>
  `;

  private mainContent = () => html`
    <div class="players">
      <figure class="players-container">
        ${this.skottiePlayerTemplate()} ${this.lottiePlayerTemplate()}
      </figure>
      ${this.livePreview()}
    </div>
    <div class="playback">
      <div class="playback-content">
        <skottie-button-sk
          id="playpause"
          .content=${html`<play-arrow-icon-sk
              id="playpause-play"
            ></play-arrow-icon-sk>
            <pause-icon-sk id="playpause-pause"></pause-icon-sk>`}
          .classes=${['playback-content__button']}
          @select=${this.playpause}
        ></skottie-button-sk>
        <div class="scrub">
          <input
            id="scrub"
            type="range"
            min="0"
            max=${SCRUBBER_RANGE}
            step="0.1"
            @input=${this.onScrub}
            @change=${this.onScrubEnd}
          />
          <label class="number">
            Frame:
            <input
              type="number"
              id="frameInput"
              class="playback-content-frameInput"
              @focus=${this.onFrameFocus}
              @change=${this.onFrameChange}
            /><!--
            --><span class="playback-content-frameTotal" id="frameTotal"
              >of 0</span
            >
          </label>
        </div>
        <skottie-button-sk
          id="rewind"
          .content=${html`<replay-icon-sk></replay-icon-sk>`}
          .classes=${['playback-content__button']}
          @select=${this.rewind}
        ></skottie-button-sk>
      </div>
    </div>

    <div @click=${this.onChartClick}>${this.performanceChartTemplate()}</div>
    ${this.jsonEditor()} ${this.gifExporter()}

    <collapse-sk id="volume" closed>
      <p>Volume:</p>
      <input
        id="volume-slider"
        type="range"
        min="0"
        max="1"
        step=".05"
        value="1"
        @input=${this.onVolumeChange}
      />
    </collapse-sk>
  `;

  private embedDialog() {
    return html`
      <details class="embed expando">
        <summary id="embed-open">
          <span>Embed</span><expand-less-icon-sk></expand-less-icon-sk>
          <expand-more-icon-sk></expand-more-icon-sk>
        </summary>
        <label>
          Embed using an iframe
          <input value=${this.iframeDirections()} />
        </label>
        <label>
          Embed on skia.org
          <input value=${this.inlineDirections()} />
        </label>
      </details>
    `;
  }

  private performanceChartTemplate() {
    return html`
      <dialog class="perf-chart" ?open=${this.showPerformanceChart}>
        <div class="top-ribbon">
          <span>Performance Chart</span>
          <button @click=${this.togglePerformanceChart}>Close</button>
        </div>
        <skottie-performance-sk id="chart"></skottie-performance-sk>
      </dialog>
    `;
  }

  private leftControls = () => {
    if (this.viewMode === 'presentation') {
      return null;
    }

    return html`
      <div class="json-chooser">
        <div class="title">JSON File</div>
        ${this.renderDownload()}
        <skottie-file-form-sk
          @files-selected=${this.skottieFilesSelected}
        ></skottie-file-form-sk>
      </div>

      ${this.fileSettingsDialog()} ${this.backgroundDialog()}
      ${this.audioDialog()} ${this.optionsDialog()}

      <button
        class="apply-button"
        ?hidden=${!this.hasEdits}
        @click=${this.applyEdits}
      >
        Apply Edits
      </button>
    `;
  };

  private rightControls = () => html`
    ${this.jsonTextEditor()} ${this.library()} ${this.embedDialog()}
  `;

  private renderDownload() {
    if (this.state.lottie) {
      return html`
        <div class="upload-download">
          <button class="large edit-config">
            ${this.state.filename} ${this.width}x${this.height} ...
          </button>
          <div class="download">
            <a
              target="_blank"
              download=${this.state.filename}
              href=${this.downloadURL}
            >
              <file-download-icon-sk></file-download-icon-sk>
            </a>
            ${this.hasEdits ? '(without edits)' : ''}
          </div>
        </div>
      `;
    }
    return null;
  }

  private optionsDialog = () => html`
    <details class="expando">
      <summary id="options-open">
        <span>Options</span><expand-less-icon-sk></expand-less-icon-sk>
        <expand-more-icon-sk></expand-more-icon-sk>
      </summary>
      <div class="options-container">
        <checkbox-sk
          label="Show lottie-web"
          ?checked=${this.showLottie}
          @click=${this.toggleLottie}
        >
        </checkbox-sk>
      </div>
    </details>
  `;

  private audioDialog = () =>
    renderByDomain(
      html`
        <details
          class="expando"
          ?open=${this.showAudio}
          @toggle=${(e: Event) =>
            this.toggleAudio((e.target! as HTMLDetailsElement).open)}
        >
          <summary id="audio-open">
            <span>Audio</span><expand-less-icon-sk></expand-less-icon-sk>
            <expand-more-icon-sk></expand-more-icon-sk>
          </summary>

          <skottie-audio-sk
            .animation=${this.state.lottie}
            @apply=${this.applyAudioSync}
          >
          </skottie-audio-sk>
        </details>
      `,
      AUDIO_SUPPORTED_DOMAINS
    );

  private fileSettingsDialog = () =>
    html`
      <details
        class="expando"
        ?open=${this.showFileSettings}
        @toggle=${(e: Event) =>
          this.toggleFileSettings((e.target! as HTMLDetailsElement).open)}
      >
        <summary id="fileSettings-open">
          <span>File Settings</span><expand-less-icon-sk></expand-less-icon-sk>
          <expand-more-icon-sk></expand-more-icon-sk>
        </summary>
        <skottie-file-settings-sk
          .width=${this.width}
          .height=${this.height}
          .fps=${this.fps}
          @settings-change=${this.skottieFileSettingsUpdated}
        ></skottie-file-settings-sk>
      </details>
    `;

  private backgroundDialog = () =>
    html`
      <details
        class="expando"
        ?open=${this.showBackgroundSettings}
        @toggle=${(e: Event) =>
          this.toggleBackgroundSettings((e.target! as HTMLDetailsElement).open)}
      >
        <summary>
          <span>Background color</span>
          <expand-less-icon-sk></expand-less-icon-sk>
          <expand-more-icon-sk></expand-more-icon-sk>
        </summary>
        <skottie-background-settings-sk
          @background-change=${this.skottieBackgroundUpdated}
        ></skottie-background-settings-sk>
      </details>
    `;

  private iframeDirections = () =>
    `<iframe width="${this.width}" height="${this.height}" src="${window.location.origin}/e/${this.hash}?w=${this.width}&h=${this.height}" scrolling=no>`;

  private inlineDirections = () =>
    `<skottie-inline-sk width="${this.width}" height="${this.height}" src="${window.location.origin}/_/j/${this.hash}"></skottie-inline-sk>`;

  private skottiePlayerTemplate = () => html` <figure
    class="players-container-player"
  >
    <skottie-player-sk paused width=${this.width} height=${this.height}>
    </skottie-player-sk>
    ${this.wasmCaption()}
  </figure>`;

  private lottiePlayerTemplate = () => {
    if (!this.showLottie) {
      return '';
    }
    return html` <figure class="players-container-player">
      <div
        id="container"
        title="lottie-web"
        style="width: 100%; aspect-ratio: ${this.width /
        this.height}; background-color: ${this.backgroundColor}"
      ></div>
      ${caption('lottie-web', this.viewMode)}
    </figure>`;
  };

  private library = () => html` <details
    class="expando"
    ?open=${this.showLibrary}
    @toggle=${(e: Event) =>
      this.toggleLibrary((e.target! as HTMLDetailsElement).open)}
  >
    <summary id="library-open">
      <span>Library</span><expand-less-icon-sk></expand-less-icon-sk>
      <expand-more-icon-sk></expand-more-icon-sk>
    </summary>

    <skottie-library-sk @select=${this.updateAnimation}> </skottie-library-sk>
  </details>`;

  // TODO(kjlubick): Make the live preview use skottie
  private livePreview = () => {
    if (!this.hasEdits || !this.showLottie) {
      return '';
    }
    if (this.hasEdits) {
      return html` <figure>
        <div
          id="live"
          title="live-preview"
          style="width: ${this.width}px; height: ${this.height}px"
        ></div>
        <figcaption>Preview [lottie-web]</figcaption>
      </figure>`;
    }
    return '';
  };

  private jsonEditor = (): TemplateResult => html` <dialog
    class="editor"
    ?open=${this.showJSONEditor}
  >
    <div class="top-ribbon">
      <span>Layer Information</span>
      <button @click=${this.toggleEditor}>Close</button>
    </div>
    <div id="json_editor"></div>
  </dialog>`;

  private gifExporter = () => html`
    <dialog class="export" ?open=${this.showGifExporter}>
      <div class="top-ribbon">
        <span>Export</span>
        <button @click=${this.toggleGifExporter}>Close</button>
      </div>
      <skottie-gif-exporter-sk @start=${this.onExportStart}>
      </skottie-gif-exporter-sk>
    </dialog>
  `;

  private jsonTextEditor = () => html`
    <details
      class="expando"
      ?open=${this.showTextEditor}
      @toggle=${(e: Event) =>
        this.toggleTextEditor((e.target! as HTMLDetailsElement).open)}
    >
      <summary id="edit-text-open">
        <span>Edit Text</span><expand-less-icon-sk></expand-less-icon-sk>
        <expand-more-icon-sk></expand-more-icon-sk>
      </summary>

      <skottie-text-editor-sk
        .animation=${this.state.lottie}
        .mode=${this.viewMode}
        @apply=${this.applyTextEdits}
      >
      </skottie-text-editor-sk>
    </details>
  `;

  private shaderEditor = () => html`
    <details
      class="expando"
      ?open=${this.showShaderEditor}
      @toggle=${(e: Event) =>
        this.toggleShaderEditor((e.target! as HTMLDetailsElement).open)}
    >
      <summary>
        <span>Edit Shader</span><expand-less-icon-sk></expand-less-icon-sk>
        <expand-more-icon-sk></expand-more-icon-sk>
      </summary>

      <skottie-shader-editor-sk
        .animation=${this.state.lottie}
        .mode=${this.viewMode}
        @apply=${this.applyShaderEdits}
      >
      </skottie-shader-editor-sk>
    </details>
  `;

  private buildFileName = () => {
    const fileName =
      this.state.filename || this.state.lottie?.metadata?.filename;
    if (fileName) {
      return html`<div title="${fileName}">${fileName}</div>`;
    }
    return null;
  };

  private wasmCaption = () => {
    if (this.viewMode === 'presentation') {
      return null;
    }
    return html` <figcaption style="max-width: ${this.width}px;">
      <div>skottie-wasm</div>
      ${this.buildFileName()}
    </figcaption>`;
  };

  private assetsPath = PRODUCTION_ASSETS_PATH; // overridable for testing

  // The URL referring to the lottie JSON Blob.
  private backgroundColor: string = 'rgba(0,0,0,0)';

  private downloadURL: string = '';

  private duration: number = 0; // 0 is a sentinel value for "player not loaded yet"

  private editor: JSONEditor | null = null;

  private editorLoaded: boolean = false;

  // used for remembering the time elapsed while the animation is playing.
  private elapsedTime: number = 0;

  private fps: number = 0;

  private hasEdits: boolean = false;

  private hash: string = '';

  private height: number = 0;

  private live: BodymovinPlayer | null = null;

  private lottiePlayer: BodymovinPlayer | null = null;

  private performanceChart: SkottiePerformanceSk | null = null;

  private playing: boolean = true;

  private playingOnStartOfScrub: boolean = false;

  // The wasm animation computes how long it has been since the previous rendered time and
  // uses arithmetic to figure out where to seek (i.e. which frame to draw).
  private previousFrameTime: number = 0;

  private scrubbing: boolean = false;

  private showAudio: boolean = false;

  private showGifExporter: boolean = false;

  private showJSONEditor: boolean = false;

  private showLibrary: boolean = false;

  private showLottie: boolean = false;

  private showPerformanceChart: boolean = false;

  private showTextEditor: boolean = false;

  private showShaderEditor: boolean = false;

  private showFileSettings: boolean = false;

  private showBackgroundSettings: boolean = false;

  private skottieLibrary: SkottieLibrarySk | null = null;

  private skottiePlayer: SkottiePlayerSk | null = null;

  private speed: number = 1; // this is a playback multiplier

  private state: SkottieConfigState;

  private stateChanged: () => void;

  private ui: UIMode = 'idle';

  private viewMode: ViewMode = 'default';

  private width: number = 0;

  constructor() {
    super(SkottieSk.template);

    this.state = {
      filename: '',
      lottie: null,
      assetsZip: '',
      assetsFilename: '',
    };

    this.stateChanged = stateReflector(
      /* getState */ () => ({
        // provide empty values
        l: this.showLottie,
        e: this.showJSONEditor,
        g: this.showGifExporter,
        t: this.showTextEditor,
        s: this.showShaderEditor,
        p: this.showPerformanceChart,
        i: this.showLibrary,
        a: this.showAudio,
        w: this.width,
        h: this.height,
        f: this.fps,
        bg: this.backgroundColor,
        mode: this.viewMode,
        fs: this.showFileSettings,
        b: this.showBackgroundSettings,
      }),
      /* setState */ (newState) => {
        this.showLottie = !!newState.l;
        this.showJSONEditor = !!newState.e;
        this.showGifExporter = !!newState.g;
        this.showTextEditor = !!newState.t;
        this.showShaderEditor = !!newState.s;
        this.showPerformanceChart = !!newState.p;
        this.showLibrary = !!newState.i;
        this.showAudio = !!newState.a;
        this.width = +newState.w;
        this.height = +newState.h;
        this.fps = +newState.f;
        this.showFileSettings = !!newState.fs;
        this.showBackgroundSettings = !!newState.b;
        this.viewMode =
          newState.mode === 'presentation' ? 'presentation' : 'default';
        this.backgroundColor = String(newState.bg);
        this.render();
      }
    );
  }

  connectedCallback(): void {
    super.connectedCallback();
    this.reflectFromURL();
    window.addEventListener('popstate', this.reflectFromURL);
    this.render();

    // Start a continuous animation loop.
    const drawFrame = () => {
      window.requestAnimationFrame(drawFrame);

      // Elsewhere, the _previousFrameTime is set to null to restart
      // the animation. If null, we assume the user hit re-wind
      // and restart both the Skottie animation and the lottie-web one.
      // This avoids the (small) boot-up lag while we wait for the
      // skottie animation to be parsed and loaded.
      if (!this.previousFrameTime && this.playing) {
        this.previousFrameTime = Date.now();
        this.elapsedTime = 0;
      }
      if (this.playing && this.duration > 0) {
        const currentTime = Date.now();
        this.elapsedTime += (currentTime - this.previousFrameTime) * this.speed;
        this.previousFrameTime = currentTime;
        const progress = this.elapsedTime % this.duration;

        // If we want to have synchronized playing, it's best to force
        // all players to draw the same frame rather than letting them play
        // on their own timeline.
        const normalizedProgress = progress / this.duration;
        this.performanceChart?.start(
          progress,
          this.duration,
          this.state.lottie?.fr || 0
        );
        this.skottiePlayer?.seek(normalizedProgress);
        this.performanceChart?.end();
        this.skottieLibrary?.seek(normalizedProgress);

        // lottie player takes the milliseconds from the beginning of the animation.
        this.lottiePlayer?.goToAndStop(progress);
        this.live?.goToAndStop(progress);
        this.updateScrubber();
        this.updateFrameLabel();
      }
    };

    window.requestAnimationFrame(drawFrame);
  }

  disconnectedCallback(): void {
    super.disconnectedCallback();
    window.removeEventListener('popstate', this.reflectFromURL);
  }

  attributeChangedCallback(): void {
    this.render();
  }

  private updateAnimation(e: CustomEvent<LottieAnimation>): void {
    this.state.lottie = e.detail;
    this.state.filename = e.detail.metadata?.filename || this.state.filename;
    this.upload();
  }

  private applyTextEdits(e: CustomEvent<TextEditApplyEventDetail>): void {
    const texts = e.detail.texts;
    this.state.lottie = replaceTexts(texts, this.state.lottie!);
    this.skottieLibrary?.replaceTexts(texts);

    this.upload();
  }

  private applyShaderEdits(e: CustomEvent<ShaderEditApplyEventDetail>): void {
    const shaders = e.detail.shaders;
    this.state.lottie = replaceShaders(shaders, this.state.lottie!);
    // TODO(jmbetancourt): support skottieLibrary
    // this.skottieLibrary?.replaceShaders(shaders);

    this.upload();
  }

  private applyAudioSync(e: CustomEvent<AudioStartEventDetail>): void {
    const detail = e.detail;
    this.speed = detail.speed;
    this.previousFrameTime = Date.now();
    this.elapsedTime = 0;
    if (!this.playing) {
      this.playpause();
    }
  }

  private onExportStart(): void {
    if (this.playing) {
      this.playpause();
    }
  }

  private applyEdits(): void {
    if (!this.editor || !this.editorLoaded || !this.hasEdits) {
      return;
    }
    this.state.lottie = this.editor.get();
    this.upload();
  }

  private autoSize(): boolean {
    let changed = false;
    if (!this.width) {
      this.width = this.state.lottie!.w;
      changed = true;
    }
    if (!this.height) {
      this.height = this.state.lottie!.h;
      changed = true;
    }
    // By default, leave FPS at 0, instead of reading them from the lottie,
    // because that will cause it to render as smoothly as possible,
    // which looks better in most cases. If a user gives a negative value
    // for fps (e.g. -1), then we use either what the lottie tells us or
    // as fast as possible.
    if (this.fps < 0) {
      this.fps = this.state.lottie!.fr || 0;
    }
    return changed;
  }

  private skottieFileSelected(e: CustomEvent<SkottieConfigEventDetail>) {
    this.state = e.detail.state;
    this.width = e.detail.width;
    this.height = e.detail.height;
    this.fps = e.detail.fps;
    this.backgroundColor = e.detail.backgroundColor;
    this.autoSize();
    this.stateChanged();
    if (e.detail.fileChanged) {
      this.upload();
    } else {
      this.ui = 'loaded';
      this.render();
      this.initializePlayer();
      // Re-sync all players
      this.rewind();
    }
  }

  private skottieFileSettingsUpdated(
    e: CustomEvent<SkottieFileSettingsEventDetail>
  ) {
    this.width = e.detail.width;
    this.height = e.detail.height;
    this.fps = e.detail.fps;
    this.stateChanged();
    if (this.state.lottie) {
      this.autoSize();
      this.initializePlayer();
      // Re-sync all players
      this.rewind();
    }
    this.render();
  }

  private skottieFilesSelected(e: CustomEvent<SkottieFilesEventDetail>) {
    const state = e.detail;
    const width = state.lottie?.w || this.width;
    const height = state.lottie?.h || this.height;
    const fileSettings = $$<SkottieFileSettingsSk>('#file-settings', this);
    if (fileSettings) {
      fileSettings.width = width;
      fileSettings.height = height;
    }
    this.width = width;
    this.height = height;
    this.state = state;
    this.upload();
  }

  private skottieBackgroundUpdated(
    e: CustomEvent<SkottieBackgroundSettingsEventDetail>
  ) {
    const background = e.detail;
    this.backgroundColor = background.color;
    this.stateChanged();
    if (this.state.lottie) {
      this.autoSize();
      this.initializePlayer();
      // Re-sync all players
      this.rewind();
    }

    this.render();
  }

  private selectionCancelled() {
    this.ui = 'loaded';
    this.render();
    this.initializePlayer();
  }

  private initializePlayer(): Promise<void> {
    return this.skottiePlayer!.initialize({
      width: this.width,
      height: this.height,
      lottie: this.state.lottie!,
      assets: this.state.assets,
      soundMap: this.state.soundMap,
      fps: this.fps,
    }).then(() => {
      this.performanceChart?.reset();
      this.duration = this.skottiePlayer!.duration();
      // If the user has specified a value for FPS, we want to lock the
      // size of the scrubber so it is as discrete as the frame rate.
      if (this.fps) {
        const scrubber = $$<HTMLInputElement>('#scrub', this);
        if (scrubber) {
          // calculate a scaled version of ms per frame as the step size.
          scrubber.step = String(
            (1000 / this.fps) * (SCRUBBER_RANGE / this.duration)
          );
        }
      }
      const frameTotal = $$<HTMLInputElement>('#frameTotal', this);
      if (frameTotal) {
        if (this.state.lottie!.fr) {
          frameTotal.textContent =
            'of ' +
            String(Math.round(this.duration * (this.state.lottie!.fr / 1000)));
        }
      }
    });
  }

  private loadAssetsAndRender(): Promise<void> {
    const toLoad: Promise<LoadedAsset | null>[] = [];

    const lottie = this.state.lottie!;
    let fonts: FontAsset[] = [];
    let assets: LottieAsset[] = [];
    if (lottie.fonts && lottie.fonts.list) {
      fonts = lottie.fonts.list;
    }
    if (lottie.assets && lottie.assets.length) {
      assets = lottie.assets;
    }

    toLoad.push(...this.loadFonts(fonts));
    toLoad.push(...this.loadAssets(assets));

    return Promise.all(toLoad)
      .then((externalAssets: (LoadedAsset | null)[]) => {
        const loadedAssets: Record<string, ArrayBuffer> = {};
        const sounds = new SoundMap();
        for (const asset of externalAssets) {
          if (asset && asset.bytes) {
            loadedAssets[asset.name] = asset.bytes;
          } else if (asset && asset.player) {
            sounds.setPlayer(asset.name, asset.player);
          }
        }

        // check fonts
        fonts.forEach((font: FontAsset) => {
          if (!loadedAssets[font.fName]) {
            console.error(`Could not load font '${font.fName}'.`);
          }
        });

        this.state.assets = loadedAssets;
        this.state.soundMap = sounds;
        this.render();
        return this.initializePlayer().then(() => {
          // Re-sync all players
          this.rewind();
        });
      })
      .catch(() => {
        this.render();
        return this.initializePlayer().then(() => {
          // Re-sync all players
          this.rewind();
        });
      });
  }

  private loadFonts(fonts: FontAsset[]): Promise<LoadedAsset | null>[] {
    const promises: Promise<LoadedAsset | null>[] = [];
    for (const font of fonts) {
      if (!font.fName) {
        continue;
      }

      const fetchFont = (fontURL: string) => {
        promises.push(
          fetch(fontURL).then((resp: Response) => {
            // fetch does not reject on 404
            if (!resp.ok) {
              return null;
            }
            return resp.arrayBuffer().then((buffer: ArrayBuffer) => ({
              name: font.fName,
              bytes: buffer,
            }));
          })
        );
      };

      // We have a mirror of google web fonts with a flattened directory structure which
      // makes them easier to find. Additionally, we can host the full .ttf
      // font, instead of the .woff2 font which is served by Google due to
      // it's smaller size by being a subset based on what glyphs are rendered.
      // Since we don't know all the glyphs we need up front, it's easiest
      // to just get the full font as a .ttf file.
      fetchFont(`${GOOGLE_WEB_FONTS_HOST}/${font.fName}.ttf`);

      // Also try using uploaded assets.
      // We may end up with two different blobs for the same font name, in which case
      // the user-provided one takes precedence.
      fetchFont(`${this.assetsPath}/${this.hash}/${font.fName}.ttf`);
    }
    return promises;
  }

  private loadAssets(assets: LottieAsset[]): Promise<LoadedAsset | null>[] {
    const promises: Promise<LoadedAsset | null>[] = [];
    for (const asset of assets) {
      if (asset.id.startsWith('audio_')) {
        // Howler handles our audio assets, they don't provide a promise when making a new Howl.
        // We push the audio asset as is and hope that it loads before playback starts.
        const inline =
          asset.p && asset.p.startsWith && asset.p.startsWith('data:');
        if (inline) {
          promises.push(
            Promise.resolve({
              name: asset.id,
              player: new AudioPlayer(asset.p),
            })
          );
        } else {
          promises.push(
            Promise.resolve({
              name: asset.id,
              player: new AudioPlayer(
                `${this.assetsPath}/${this.hash}/${asset.p}`
              ),
            })
          );
        }
      } else {
        // asset.p is the filename, if it's an image.
        // Don't try to load inline/dataURI images.
        const should_load =
          asset.p && asset.p.startsWith && !asset.p.startsWith('data:');
        if (should_load) {
          promises.push(
            fetch(`${this.assetsPath}/${this.hash}/${asset.p}`).then(
              (resp: Response) => {
                // fetch does not reject on 404
                if (!resp.ok) {
                  console.error(
                    `Could not load ${asset.p}: status ${resp.status}`
                  );
                  return null;
                }
                return resp.arrayBuffer().then((buffer) => ({
                  name: asset.p,
                  bytes: buffer,
                }));
              }
            )
          );
        }
      }
    }
    return promises;
  }

  private playpause(): void {
    const audioManager = $$<SkottieAudioSk>('skottie-audio-sk');
    if (this.playing) {
      this.lottiePlayer?.pause();
      this.live?.pause();
      this.state.soundMap?.pause();
      $$<HTMLElement>('#playpause-pause')!.style.display = 'none';
      $$<HTMLElement>('#playpause-play')!.style.display = 'inherit';
      audioManager?.pause();
    } else {
      this.lottiePlayer?.play();
      this.live?.play();
      this.previousFrameTime = Date.now();
      // There is no need call a soundMap.play() function here.
      // Skottie invokes the play by calling seek on the needed audio track.
      $$<HTMLElement>('#playpause-pause')!.style.display = 'inherit';
      $$<HTMLElement>('#playpause-play')!.style.display = 'none';
      audioManager?.resume();
    }
    this.playing = !this.playing;
  }

  private recoverFromError(msg: string): void {
    errorMessage(msg);
    console.error(msg);
    window.history.pushState(null, '', '/');
    // For development we recover to the loaded state to see the animation
    // even if the upload didn't work
    this.ui = isDomain(supportedDomains.LOCALHOST) ? 'loaded' : 'idle';
    this.render();
  }

  private reflectFromURL(): void {
    // Check URL.
    const match = window.location.pathname.match(/\/([a-zA-Z0-9]+)/);
    if (!match) {
      this.hash = DEFAULT_LOTTIE_FILE;
    } else {
      this.hash = match[1];
    }
    this.ui = 'loading';
    this.render();
    // Run this on the next micro-task to allow mocks to be set up if needed.
    setTimeout(() => {
      fetch(`/_/j/${this.hash}`, {
        credentials: 'include',
      })
        .then(jsonOrThrow)
        .then((json) => {
          // remove legacy fields from state, if they are there.
          delete json.width;
          delete json.height;
          delete json.fps;
          this.state = json;

          if (this.autoSize()) {
            this.stateChanged();
          }
          this.ui = 'loaded';
          this.loadAssetsAndRender().then(() => {
            this.dispatchEvent(
              new CustomEvent('initial-animation-loaded', { bubbles: true })
            );
          });
        })
        .catch((msg) => this.recoverFromError(msg));
    });
  }

  private render(): void {
    if (this.downloadURL) {
      URL.revokeObjectURL(this.downloadURL);
    }
    this.downloadURL = URL.createObjectURL(
      new Blob([JSON.stringify(this.state.lottie)])
    );
    super._render();

    this.skottiePlayer = $$<SkottiePlayerSk>('skottie-player-sk', this);
    this.performanceChart = $$<SkottiePerformanceSk>(
      'skottie-performance-sk',
      this
    );
    this.skottieLibrary = $$<SkottieLibrarySk>('skottie-library-sk', this);

    const skottieGifExporter = $$<SkottieGifExporterSk>(
      'skottie-gif-exporter-sk',
      this
    );
    if (skottieGifExporter && this.skottiePlayer) {
      skottieGifExporter.player = this.skottiePlayer;
    }

    if (this.ui === 'loaded') {
      if (this.state.soundMap && this.state.soundMap.map.size > 0) {
        this.hideVolumeSlider(false);
        // Stop any audio assets that start playing on frame 0
        // Pause the playback to force a user gesture to resume the AudioContext
        if (this.playing) {
          this.playpause();
          this.rewind();
        }
        this.state.soundMap.stop();
      } else {
        this.hideVolumeSlider(true);
      }
      try {
        this.renderLottieWeb();
        this.renderJSONEditor();
        this.renderTextEditor();
        this.renderShaderEditor();
        this.renderAudioManager();
      } catch (e) {
        console.warn('caught error while rendering third party code', e);
      }
    }
  }

  private renderAudioManager(): void {
    if (this.showAudio) {
      const audioManager = $$<SkottieAudioSk>('skottie-audio-sk', this);
      if (audioManager) {
        audioManager.animation = this.state.lottie!;
      }
    }
  }

  private renderTextEditor(): void {
    if (this.showTextEditor) {
      const textEditor = $$<SkottieTextEditorSk>(
        'skottie-text-editor-sk',
        this
      );
      if (textEditor) {
        textEditor.animation = this.state.lottie!;
      }
    }
  }

  private renderShaderEditor(): void {
    if (this.showShaderEditor) {
      const shaderEditor = $$<ShaderEditorSk>('skottie-shader-editor-sk', this);
      if (shaderEditor) {
        shaderEditor.animation = this.state.lottie!;
      }
    }
  }

  private renderJSONEditor(): void {
    if (!this.showJSONEditor) {
      this.editorLoaded = false;
      this.editor = null;
      return;
    }
    const editorContainer = $$<HTMLDivElement>('#json_editor')!;
    // See https://github.com/josdejong/jsoneditor/blob/master/docs/api.md
    // for documentation on this editor.
    const editorOptions = {
      // Use original key order (this preserves related fields locality).
      sortObjectKeys: false,
      // There are sometimes a few onChange events that happen
      // during the initial .set(), so we have a safety variable
      // _editorLoaded to prevent a bunch of recursion
      onChange: () => {
        if (!this.editorLoaded) {
          return;
        }
        this.hasEdits = true;
        this.render();
      },
    };

    if (!this.editor) {
      this.editorLoaded = false;
      editorContainer.innerHTML = '';
      this.editor = new JSONEditor(editorContainer, editorOptions);
    }
    if (!this.hasEdits) {
      this.editorLoaded = false;
      // Only set the JSON when it is loaded, either because it's
      // the first time we got it from the server or because the user
      // hit applyEdits.
      this.editor.set(this.state.lottie);
    }
    // We are now pretty confident that the onChange events will only be
    // when the user modifies the JSON.
    this.editorLoaded = true;
  }

  private renderLottieWeb(): void {
    if (!this.showLottie) {
      return;
    }
    // Don't re-start the animation while the user edits.
    if (!this.hasEdits) {
      $$<HTMLDivElement>('#container')!.innerHTML = '';
      this.lottiePlayer = LottiePlayer.loadAnimation({
        container: $$('#container')!,
        renderer: 'svg',
        loop: true,
        autoplay: this.playing,
        assetsPath: `${this.assetsPath}/${this.hash}/`,
        // Apparently the lottie player modifies the data as it runs?
        animationData: JSON.parse(
          JSON.stringify(this.state.lottie)
        ) as LottieAnimation,
        rendererSettings: {
          preserveAspectRatio: 'xMidYMid meet',
        },
      });
      this.live = null;
    } else {
      // we have edits, update the live preview version.
      // It will re-start from the very beginning, but the user can
      // hit "rewind" to re-sync them.
      $$<HTMLDivElement>('#live')!.innerHTML = '';
      this.live = LottiePlayer.loadAnimation({
        container: $$('#live')!,
        renderer: 'svg',
        loop: true,
        autoplay: this.playing,
        assetsPath: `${this.assetsPath}/${this.hash}/`,
        // Apparently the lottie player modifies the data as it runs?
        animationData: JSON.parse(
          JSON.stringify(this.editor!.get())
        ) as LottieAnimation,
        rendererSettings: {
          preserveAspectRatio: 'xMidYMid meet',
        },
      });
    }
  }

  // This fires every time the user moves the scrub slider.
  private onScrub(e: Event): void {
    if (!this.scrubbing) {
      // Pause the animation while dragging the slider.
      this.playingOnStartOfScrub = this.playing;
      if (this.playing) {
        this.playpause();
      }
      this.scrubbing = true;
    }
    const scrubber = (e.target as HTMLInputElement)!;
    const seek = +scrubber.value / SCRUBBER_RANGE;
    this.seek(seek);
    this.updateFrameLabel();
  }

  // This fires when the user releases the scrub slider.
  private onScrubEnd(): void {
    if (this.playingOnStartOfScrub) {
      this.playpause();
    }
    this.scrubbing = false;
  }

  private onFrameFocus(): void {
    if (this.playing) {
      this.playpause();
    }
  }

  private onFrameChange(e: Event): void {
    if (this.playing) {
      this.playpause();
    }
    const frameInput = $$<HTMLInputElement>('#frameInput', this);
    if (frameInput) {
      const frame = +frameInput.value;
      this.seekFrame(frame);
    }
  }

  private onChartClick(e: Event): void {
    const chart = $$<SkottiePerformanceSk>('#chart', this);
    const frame: number | undefined = chart?.getClickedFrame(e);
    if (frame !== undefined && frame !== -1) {
      if (this.playing) {
        this.playpause();
      }
      const frameInput = $$<HTMLInputElement>('#frameInput', this);
      if (frameInput) frameInput.value = String(frame);
      this.seekFrame(frame);
    }
  }

  private seekFrame(frame: number): void {
    if (frame > 0 && frame < this.duration) {
      let seek = 0;
      if (this.state.lottie?.fr) {
        seek = ((frame / this.state.lottie.fr) * 1000) / this.duration;
      }
      this.seek(seek);
      this.updateScrubber();
    }
  }

  private updateScrubber(): void {
    const scrubber = $$<HTMLInputElement>('#scrub', this);
    if (scrubber) {
      // Scale from time to the arbitrary scrubber range.
      const progress = this.elapsedTime % this.duration;
      scrubber.value = String((SCRUBBER_RANGE * progress) / this.duration);
    }
  }

  private updateFrameLabel(): void {
    const frameLabel = $$<HTMLInputElement>('#frameInput', this);
    if (frameLabel) {
      const progress = this.elapsedTime % this.duration;
      if (this.state.lottie!.fr) {
        frameLabel.value = String(
          Math.round(progress * (this.state.lottie!.fr / 1000))
        );
      }
    }
  }

  private seek(t: number): void {
    // catch case where t = 1
    t = Math.min(t, 0.9999);
    this.elapsedTime = t * this.duration;
    this.live?.goToAndStop(t);
    this.lottiePlayer?.goToAndStop(t * this.duration);
    this.skottiePlayer?.seek(t);
    this.skottieLibrary?.seek(t);
  }

  private onVolumeChange(e: Event): void {
    const scrubber = (e.target as HTMLInputElement)!;
    this.state.soundMap?.setVolume(+scrubber.value);
  }

  private rewind(): void {
    // Handle rewinding when paused.
    if (!this.playing) {
      this.skottiePlayer!.seek(0);
      this.skottieLibrary?.seek(0);
      this.previousFrameTime = 0;
      this.live?.goToAndStop(0);
      this.lottiePlayer?.goToAndStop(0);
      const scrubber = $$<HTMLInputElement>('#scrub', this);
      if (scrubber) {
        scrubber.value = '0';
      }
    } else {
      this.live?.goToAndPlay(0);
      this.lottiePlayer?.goToAndPlay(0);
      this.previousFrameTime = 0;
      const audioManager = $$<SkottieAudioSk>('skottie-audio-sk', this);
      audioManager?.rewind();
    }
  }

  private startEdit(): void {
    this.ui = 'dialog';
    this.render();
  }

  private toggleEditor(e: Event): void {
    // avoid double toggles
    e.preventDefault();
    this.showTextEditor = false;
    this.showJSONEditor = !this.showJSONEditor;
    this.stateChanged();
    this.render();
  }

  private toggleGifExporter(e: Event): void {
    // avoid double toggles
    e.preventDefault();
    this.showGifExporter = !this.showGifExporter;
    this.stateChanged();
    this.render();
  }

  private exportSelectHandler(e: CustomEvent<DropdownSelectEvent>): void {
    if (!this.skottiePlayer) {
      return;
    }
    const exportManager = $$<SkottieExporterSk>('skottie-exporter-sk');
    exportManager?.export(e.detail.value as ExportType, this.skottiePlayer);
  }

  private togglePerformanceChart(e: Event): void {
    // avoid double toggles
    e.preventDefault();
    this.showPerformanceChart = !this.showPerformanceChart;
    this.stateChanged();
    this.render();
  }

  private toggleTextEditor(open: boolean): void {
    this.showJSONEditor = false;
    this.showTextEditor = open;
    this.stateChanged();
    this.render();
  }

  private toggleShaderEditor(open: boolean): void {
    this.showJSONEditor = false;
    this.showShaderEditor = open;
    this.stateChanged();
    this.render();
  }

  private toggleLibrary(open: boolean): void {
    this.showLibrary = open;
    this.stateChanged();
    this.render();
  }

  private toggleAudio(open: boolean): void {
    this.showAudio = open;
    this.stateChanged();
    this.render();
  }

  private toggleFileSettings(open: boolean): void {
    this.showFileSettings = open;
    this.stateChanged();
    this.render();
  }

  private toggleBackgroundSettings(open: boolean): void {
    this.showBackgroundSettings = open;
    this.stateChanged();
    this.render();
  }

  private toggleLottie(e: Event): void {
    // avoid double toggles
    e.preventDefault();
    this.showLottie = !this.showLottie;
    this.stateChanged();
    this.render();
  }

  private hideVolumeSlider(v: boolean) {
    const collapse = $$<CollapseSk>('#volume', this);
    if (collapse) {
      collapse.closed = v;
    }
  }

  private upload(): void {
    // POST the JSON to /_/upload
    this.hash = '';
    this.hasEdits = false;
    this.editorLoaded = false;
    this.editor = null;
    // Clean up the old animation and other wasm objects
    this.render();
    fetch('/_/upload', {
      credentials: 'include',
      body: JSON.stringify(this.state),
      headers: {
        'Content-Type': 'application/json',
      },
      method: 'POST',
    })
      .then(jsonOrThrow)
      .then((json) => {
        // Should return with the hash and the lottie file
        this.ui = 'loaded';
        this.hash = json.hash;
        this.state.lottie = json.lottie;
        window.history.pushState(null, '', `/${this.hash}`);
        this.stateChanged();
        if (this.state.assetsZip) {
          this.loadAssetsAndRender();
        }
        this.render();
      })
      .catch((msg) => this.recoverFromError(msg));

    if (!this.state.assetsZip) {
      this.ui = 'loaded';
      // Start drawing right away, no need to wait for
      // the JSON to make a round-trip to the server, since there
      // are no assets that we need to unzip server-side.
      // We still need to check for things like webfonts.
      this.render();
      this.loadAssetsAndRender();
    } else {
      // We have to wait for the server to process the zip file.
      this.ui = 'loading';
      this.render();
    }
  }

  overrideAssetsPathForTesting(p: string): void {
    this.assetsPath = p;
  }
}

define('skottie-sk', SkottieSk);
