/**
 * @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/checkbox-sk'
import 'elements-sk/collapse-sk'
import 'elements-sk/error-toast-sk'
import { $$ } from 'common-sk/modules/dom'
import { SKIA_VERSION } from '../../build/version.js'
import { errorMessage } from 'elements-sk/errorMessage'
import { define } from 'elements-sk/define'
import { html, render } from 'lit-html'
import { jsonOrThrow } from 'common-sk/modules/jsonOrThrow'
import { setupListeners, onUserEdit, reannotate} from '../lottie-annotations'
import { stateReflector } from 'common-sk/modules/stateReflector'
import '../skottie-gif-exporter'
import '../skottie-text-editor'
import { replaceTexts } from '../skottie-text-editor/text-replace'
import '../skottie-library-sk'
import { SoundMap, AudioPlayer } from '../audio'
import '../skottie-performance-sk'
import { renderByDomain } from '../helpers/templates'
import { supportedDomains } from '../helpers/domains'
import '../skottie-audio-sk'

const JSONEditor = require('jsoneditor/dist/jsoneditor-minimalist.js');
const bodymovin = require('lottie-web/build/player/lottie.min.js');

const DIALOG_MODE = 1;
const LOADING_MODE = 2;
const LOADED_MODE = 3;

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

// 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 LIBRARY_SUPPORTED_DOMAINS = [
  supportedDomains.SKOTTIE_INTERNAL,
  supportedDomains.SKOTTIE_TENOR,
  supportedDomains.LOCALHOST,
];

const displayDialog = (ele) => html`
<skottie-config-sk .state=${ele._state} .width=${ele._width}
    .height=${ele._height} .fps=${ele._fps} .backgroundColor=${ele._backgroundColor}></skottie-config-sk>
`;

const skottiePlayer = (ele) => html`
<skottie-player-sk paused width=${ele._width} height=${ele._height}>
</skottie-player-sk>

<figcaption>
  skottie-wasm
</figcaption>`;

const lottiePlayer = (ele) => {
  if (!ele._showLottie) {
    return '';
  }
  return html`
<figure>
  <div id=container title=lottie-web
       style='width: ${ele._width}px; height: ${ele._height}px; background-color: ${ele._backgroundColor}'></div>
  <figcaption>lottie-web (${bodymovin.version})</figcaption>
</figure>`;
}

// TODO(kjlubick): Make the live preview use skottie
const livePreview = (ele) => {
  if (!ele._hasEdits || !ele._showLottie) {
    return '';
  }
  if (ele._hasEdits) {
    return html`
<figure>
  <div id=live title=live-preview
       style='width: ${ele._width}px; height: ${ele._height}px'></div>
  <figcaption>Preview [lottie-web]</figcaption>
</figure>`;
  }
}

const iframeDirections = (ele) => {
  return `<iframe width="${ele._width}" height="${ele._height}" src="${window.location.origin}/e/${ele._hash}?w=${ele._width}&h=${ele._height}" scrolling=no>`;
}

const inlineDirections = (ele) => {
  return `<skottie-inline-sk width="${ele._width}" height="${ele._height}" src="${window.location.origin}/_/j/${ele._hash}"></skottie-inline-sk>`;
}

const jsonEditor = (ele) => {
  if (!ele._showEditor) {
    return '';
  }
  return html`
<section class=editor>
  <div id=json_editor></div>
</section>`;
}

const gifExporter = (ele) => {
  if (!ele._showGifExporter) {
    return '';
  }
  return html`
<section class=editor>
  <skottie-gif-exporter
    @start=${ele._onGifExportStart}
  >
  </skottie-gif-exporter>
</section>`;
}

const jsonTextEditor = (ele) => {
  if (!ele._showTextEditor) {
    return '';
  }
  return html`
<section class=editor>
  <skottie-text-editor
    .animation=${ele._state.lottie}
    @apply=${ele._applyTextEdits}
  >
  </skottie-text-editor>
</section>`;
};

const library = (ele) => {
  if (!ele._showLibrary) {
    return '';
  }
  return renderByDomain(
    html`
    <section class=library>
      <skottie-library-sk
        @select=${ele._updateAnimation}
      >
      </skottie-library-sk>
    </section>`,
    LIBRARY_SUPPORTED_DOMAINS,
  );
};

const audio = (ele) => {
  if (!ele._showAudio) {
    return '';
  }
  return renderByDomain(
    html`
    <section class=audio>
      <skottie-audio-sk
        .animation=${ele._state.lottie}
        @apply=${ele._applyAudioSync}
      >
      </skottie-audio-sk>
    </section>`,
    LIBRARY_SUPPORTED_DOMAINS,
  );
};

const libraryButton = (ele) => renderByDomain(
  html`<checkbox-sk label="Show library"
     ?checked=${ele._showLibrary}
     @click=${ele._toggleLibrary}>
  </checkbox-sk>`,
  LIBRARY_SUPPORTED_DOMAINS,
);

const audioButton = (ele) => renderByDomain(
  html`<checkbox-sk label="Show audio"
     ?checked=${ele._showAudio}
     @click=${ele._toggleAudio}>
  </checkbox-sk>`,
  LIBRARY_SUPPORTED_DOMAINS,
);

const performanceChart = (ele) => {
  if (!ele._showPerformanceChart) {
    return '';
  }
  return html`
<skottie-performance-sk></skottie-performance-sk>`;
};

const displayLoaded = (ele) => html`
<button class=edit-config @click=${ ele._startEdit}>
  ${ele._state.filename} ${ele._width}x${ele._height} ...
</button>
<div class=controls>
  <button @click=${ele._rewind}>Rewind</button>
  <button id=playpause @click=${ele._playpause}>Pause</button>
  <button ?hidden=${!ele._hasEdits} @click=${ele._applyEdits}>Apply Edits</button>
  <div class=download>
    <a target=_blank download=${ele._state.filename} href=${ele._downloadUrl}>
      JSON
    </a>
    ${ele._hasEdits? '(without edits)': ''}
  </div>
  <checkbox-sk label="Show lottie-web"
               ?checked=${ele._showLottie}
               @click=${ele._toggleLottie}>
  </checkbox-sk>
  <checkbox-sk label="Show editor"
               ?checked=${ele._showEditor}
               @click=${ele._toggleEditor}>
  </checkbox-sk>
  <checkbox-sk label="Show gif exporter"
               ?checked=${ele._showGifExporter}
               @click=${ele._toggleGifExporter}>
  </checkbox-sk>
  <checkbox-sk label="Show text editor"
               ?checked=${ele._showTextEditor}
               @click=${ele._toggleTextEditor}>
  </checkbox-sk>
  <checkbox-sk label="Show performance chart"
               ?checked=${ele._showPerformanceChart}
               @click=${ele._togglePerformanceChart}>
  </checkbox-sk>
  ${libraryButton(ele)}
  ${audioButton(ele)}
  <button @click=${ele._toggleEmbed}>Embed</button>
  <div class=scrub>
    <input id=scrub type=range min=0 max=${SCRUBBER_RANGE+1} step=0.1
        @input=${ele._onScrub} @change=${ele._onScrubEnd}>
  </div>
  <collapse-sk id=volume closed>
    <p>
      Volume:
    </p>
    <input id=volume-slider type=range min=0 max=1 step=.05 value=1
      @input=${ele._onVolumeChange}>
  </collapse-sk>
</div>
<collapse-sk id=embed closed>
  <p>
    <label>
      Embed using an iframe: <input size=120 value=${iframeDirections(ele)} scrolling=no>
    </label>
  </p>
  <p>
    <label>
      Embed on skia.org: <input size=140 value=${inlineDirections(ele)} scrolling=no>
    </label>
  </p>
</collapse-sk>
<section class=figures>
  <figure>
    ${skottiePlayer(ele)}
  </figure>
  ${lottiePlayer(ele)}
  ${audio(ele)}
  ${library(ele)}
  ${livePreview(ele)}
</section>

${performanceChart(ele)}
${jsonEditor(ele)}
${gifExporter(ele)}
${jsonTextEditor(ele)}
`;

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

// pick the right part of the UI to display based on ele._ui.
const pick = (ele) => {
  switch (ele._ui) {
    case DIALOG_MODE:
      return displayDialog(ele);
    case LOADING_MODE:
      return displayLoading(ele);
    case LOADED_MODE:
      return displayLoaded(ele);
  }
};

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) => domain !== supportedDomains.SKOTTIE_INTERNAL),
);

const template = (ele) => html`
<header>
  <h2>Skottie</h2>
  <span>
    <a href='https://skia.googlesource.com/skia/+show/${SKIA_VERSION}'>
      ${SKIA_VERSION.slice(0, 7)}
    </a>
  </span>
</header>
<main>
  ${pick(ele)}
</main>
<footer>
  <error-toast-sk></error-toast-sk>
  ${redir(ele)}
</footer>
`;

define('skottie-sk', class extends HTMLElement {
  constructor() {
    super();
    this._state = {
      filename: '',
      lottie: null,
      assetsZip: '',
      assetsFilename: '',
    };
    // One of 'dialog', 'loading', or 'loaded'
    this._ui = DIALOG_MODE;
    this._hash = '';
    this._skottiePlayer = null;
    this._skottiePerformanceChart = null;
    this._lottie = null;
    this._live = null;
    this._playing = true;
    this._assetsPath = '/_/a';
    this._downloadUrl = null; // The URL to download the lottie JSON from.
    this._editor = null;
    this._editorLoaded = false;
    this._hasEdits = false;
    this._showLottie = false;
    this._showEditor = false;
    this._showGifExporter = false;
    this._showTextEditor = false;
    this._showPerformanceChart = false;
    this._showLibrary = false;
    this._showAudio = false;
    this._scrubbing = false;
    this._playingOnStartOfScrub = false;

    this._width = 0;
    this._height = 0;
    this._fps = 0;
    this._speed = 1; // This is a playback multiplier
    this._backgroundColor = 'rgba(0,0,0,0)';

    this._stateChanged = stateReflector(
      /*getState*/() => {
        return {
          // provide empty values
          'l' : this._showLottie,
          'e' : this._showEditor,
          'g' : this._showGifExporter,
          't' : this._showTextEditor,
          'p' : this._showPerformanceChart,
          'i' : this._showLibrary,
          'a' : this._showAudio,
          'w' : this._width,
          'h' : this._height,
          'f' : this._fps,
          'bg': this._backgroundColor,
        }
    }, /*setState*/(newState) => {
      this._showLottie = newState.l;
      this._showEditor = newState.e;
      this._showGifExporter = newState.g;
      this._showTextEditor = newState.t;
      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._backgroundColor = newState.bg;
      this._applyTextEdits = this._applyTextEdits.bind(this);
      this._applyAudioSync = this._applyAudioSync.bind(this);
      this._onGifExportStart = this._onGifExportStart.bind(this);
      this.render();
    });

    this._duration = 0; // _duration = 0 is a sentinel value for "player not loaded yet"

    // 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).
    this._previousFrameTime = null;
     // used for remembering the time elapsed while the animation is playing.
    this._elapsedTime = 0;
  }

  connectedCallback() {
    this._reflectFromURL();
    this.addEventListener('skottie-selected', this)
    this.addEventListener('cancelled', this)
    window.addEventListener('popstate', this)
    this.render();

    // Start a continous 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;
        let 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._skottiePerformanceChart&& this._skottiePerformanceChart.start(
          progress,
          this._duration,
          this._state.lottie.fr
        );
        this._skottiePlayer && this._skottiePlayer.seek(normalizedProgress);
        this._skottiePerformanceChart && this._skottiePerformanceChart.end();
        this._skottieLibrary && this._skottieLibrary.seek(normalizedProgress);

        // lottie player takes the milliseconds from the beginning of the animation.
        this._lottie && this._lottie.goToAndStop(progress);
        this._live && this._live.goToAndStop(progress);
        const scrubber = $$('#scrub', this);
        if (scrubber) {
          // Scale from time to the arbitrary scrubber range.
          scrubber.value = SCRUBBER_RANGE * progress / this._duration;
        }
      }
    }

    window.requestAnimationFrame(drawFrame);
  }

  disconnectedCallback() {
    this.removeEventListener('skottie-selected', this)
    this.removeEventListener('cancelled', this)
  }

  attributeChangedCallback(name, oldValue, newValue) {
    this.render();
  }

  _updateAnimation(event) {
    const animation = event.detail;
    this._state.lottie = animation;

    this._upload();
  }

  _applyTextEdits(event) {
    const texts = event.detail.texts;
    this._state.lottie = replaceTexts(texts, this._state.lottie);

    this._skottieLibrary && this._skottieLibrary.replaceTexts(texts);

    this._upload();
  }

  _applyAudioSync(event) {
    const detail = event.detail;
    this._speed = detail.speed;
    this._previousFrameTime = Date.now();
    this._elapsedTime = 0;
    if (!this._playing) {
      this._playpause();
    }
  }

  _onGifExportStart() {
    if (this._playing) {
      this._playpause();
    }
  }

  _applyEdits() {
    if (!this._editor || !this._editorLoaded || !this._hasEdits) {
      return;
    }
    this._state.lottie = this._editor.get();
    this._upload();
  }

  _autoSize() {
    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;
  }

  handleEvent(e) {
    if (e.type === 'skottie-selected') {
      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_MODE;
        this.render();
        this._initializePlayer();
        // Re-sync all players
        this._rewind();
      }
    } else if (e.type === 'cancelled') {
      this._ui = LOADED_MODE;
      this.render();
      this._initializePlayer();
    } else if (e.type === 'popstate') {
      this._reflectFromURL();
    }
  }

  _initializePlayer() {
    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._skottiePerformanceChart && this._skottiePerformanceChart.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 = $$("#scrub", this);
        if (scrubber) {
          // calculate a scaled version of ms per frame as the step size.
          scrubber.step = (1000 / this._fps * SCRUBBER_RANGE / this._duration);
        }
      }

    });
  }

  _loadAssetsAndRender() {
    const toLoad = [];

    const lottie = this._state.lottie;
    let fonts  = [];
    let assets = [];
    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));

    Promise.all(toLoad).then((externalAssets) => {
      const assets = {};
      const sounds = new SoundMap();
      for (const asset of externalAssets) {
        if (asset && asset.bytes) {
          assets[asset.name] = asset.bytes;
        } else if (asset && asset.player) {
          sounds.setPlayer(asset.name, asset.player);
        }
      }

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

      this._state.assets = assets;
      this._state.soundMap = sounds;
      this.render();
      this._initializePlayer();
      // Re-sync all players
      this._rewind();
    })
    .catch(() => {
      this.render();
      this._initializePlayer();
      // Re-sync all players
      this._rewind();
    });

  }

  _loadFonts(fonts) {
    const promises = [];
    for (const font of fonts) {
      if (!font.fName) {
        continue;
      }

      const fetchFont = (fontURL) => {
        promises.push(fetch(fontURL)
          .then((resp) => {
            // fetch does not reject on 404
            if (!resp.ok) {
              return null;
            }
            return resp.arrayBuffer().then((buffer) => {
              return {
                '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;
  }

  _loadAssets(assets) {
    const promises = [];
    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({
            'name': asset.id,
            'player': new AudioPlayer(asset.p)
          });
        } else {
          promises.push({
            '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) => {
              // 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) => {
                return {
                  'name': asset.p,
                  'bytes': buffer
                };
              });
            })
          );
        }
      }
    }
    return promises;
  }

  _playpause() {
    const audioManager = $$('skottie-audio-sk');
    if (this._playing) {
      this._lottie && this._lottie.pause();
      this._live && this._live.pause();
      this._state.soundMap && this._state.soundMap.pause();
      $$('#playpause').textContent = 'Play';
      audioManager && audioManager.pause();
    } else {
      this._lottie && this._lottie.play();
      this._live && 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.
      $$('#playpause').textContent = 'Pause';
      audioManager && audioManager.resume();
    }
    this._playing = !this._playing;
  }

  _recoverFromError(msg) {
      errorMessage(msg);
      console.error(msg);
      window.history.pushState(null, '', '/');
      this._ui = DIALOG_MODE;
      this.render();
  }

  _reflectFromURL() {
    // Check URL.
    let match = window.location.pathname.match(/\/([a-zA-Z0-9]+)/);
    if (!match) {
      // Make this the hash of the lottie file you want to play on startup.
      this._hash = '1112d01d28a776d777cebcd0632da15b'; // gear.json
    } else {
      this._hash = match[1];
    }
    this._ui = LOADING_MODE;
    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 => {
        this._state = json;
        // remove legacy fields from state, if they are there.
        delete this._state.width;
        delete this._state.height;
        delete this._state.fps;

        if (this._autoSize()) {
          this._stateChanged();
        }
        this._ui = LOADED_MODE;
        this._loadAssetsAndRender();
      }).catch((msg) => this._recoverFromError(msg));
    });
  }

  render() {
    if (this._downloadUrl)  {
      URL.revokeObjectURL(this._downloadUrl);
    }
    this._downloadUrl = URL.createObjectURL(new Blob([JSON.stringify(this._state.lottie)]));
    render(template(this), this, {eventContext: this});

    this._skottiePlayer = $$('skottie-player-sk', this);
    this._skottiePerformanceChart = $$('skottie-performance-sk', this);
    this._skottieLibrary = $$('skottie-library-sk', this);

    const skottieGifExporter = $$('skottie-gif-exporter', this);
    if (skottieGifExporter) {
      skottieGifExporter.player = this._skottiePlayer;
    }

    if (this._ui === LOADED_MODE) {
      if (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._renderAudioManager();
      } catch(e) {
        console.warn('caught error while rendering third party code', e);
      }
    }
  }

  _renderAudioManager() {
    if (this._showAudio) {
      const audioManager = $$('skottie-audio-sk', this);
      if (audioManager) {
        audioManager.animation = this._state.lottie;
      }
    }
  }

  _renderTextEditor() {
    if (this._showTextEditor) {
      const textEditor = $$('skottie-text-editor', this);
      if (textEditor) {
        textEditor.animation = this._state.lottie;
      }
    }
  }

  _renderJSONEditor() {
    if (!this._showEditor) {
      this._editorLoaded = false;
      this._editor = null;
      return;
    }
    let editorContainer = $$('#json_editor');
    // See https://github.com/josdejong/jsoneditor/blob/master/docs/api.md
    // for documentation on this editor.
    let 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;
        onUserEdit(editorContainer, this._editor.get());
        this.render();
      }
    };

    if (!this._editor) {
      this._editorLoaded = false;
      editorContainer.innerHTML = '';
      this._editor = new JSONEditor(editorContainer, editorOptions);
      setupListeners(editorContainer);
    }
    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);
    }
    reannotate(editorContainer, this._state.lottie);
    // We are now pretty confident that the onChange events will only be
    // when the user modifies the JSON.
    this._editorLoaded = true;
  }

  _renderLottieWeb() {
    if (!this._showLottie) {
      return;
    }
    // Don't re-start the animation while the user edits.
    if (!this._hasEdits) {
      $$('#container').innerHTML = '';
      this._lottie = bodymovin.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)),
        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.
      $$('#live').innerHTML = '';
      this._live = bodymovin.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())),
        rendererSettings: {
          preserveAspectRatio:'xMidYMid meet'
        },
      });
    }
  }

  // This fires every time the user moves the scrub slider.
  _onScrub(e) {
    if (!this._scrubbing) {
      // Pause the animation while dragging the slider.
      this._playingOnStartOfScrub = this._playing;
      if (this._playing) {
        this._playpause()
      }
      this._scrubbing = true;
    }

    let seek = (e.currentTarget.value / SCRUBBER_RANGE);
    this._elapsedTime = seek * this._duration;
    this._live && this._live.goToAndStop(seek);
    this._lottie && this._lottie.goToAndStop(seek * this._duration);
    this._skottiePlayer && this._skottiePlayer.seek(seek);
    this._skottieLibrary && this._skottieLibrary.seek(seek);
  }

  // This fires when the user releases the scrub slider.
  _onScrubEnd(e) {
    if (this._playingOnStartOfScrub) {
      this._playpause()
    }
    this._scrubbing = false;
  }

  _onVolumeChange(e) {
    this._state.soundMap.setVolume(e.currentTarget.value);
  }

  _rewind(e) {
    // Handle rewinding when paused.
    if (!this._playing) {
      this._skottiePlayer.seek(0);
      this._skottieLibrary && this._skottieLibrary.seek(0);
      this._previousFrameTime = null;
      this._live && this._live.goToAndStop(0);
      this._lottie && this._lottie.goToAndStop(0);
      const scrubber = $$('#scrub', this);
      if (scrubber) {
        scrubber.value = 0;
      }

    } else {
      this._live && this._live.goToAndPlay(0);
      this._lottie && this._lottie.goToAndPlay(0);
      this._previousFrameTime = null;
      const audioManager = $$('skottie-audio-sk', this);
      audioManager && audioManager.rewind();
    }
  }

  _startEdit() {
    this._ui = DIALOG_MODE;
    this.render();
  }

  _toggleEditor(e) {
    // avoid double toggles
    e.preventDefault();
    this._showTextEditor = false;
    this._showEditor = !this._showEditor;
    this._stateChanged();
    this.render();
  }

  _toggleGifExporter(e) {
    // avoid double toggles
    e.preventDefault();
    this._showGifExporter = !this._showGifExporter;
    this._stateChanged();
    this.render();
  }

  _togglePerformanceChart(e) {
    // avoid double toggles
    e.preventDefault();
    this._showPerformanceChart = !this._showPerformanceChart;
    this._stateChanged();
    this.render();
  }

  _toggleTextEditor(e) {
    e.preventDefault();
    this._showEditor = false;
    this._showTextEditor = !this._showTextEditor;
    this._stateChanged();
    this.render();
  }

  _toggleLibrary(e) {
    e.preventDefault();
    this._showLibrary = !this._showLibrary;
    this._stateChanged();
    this.render();
  }

  _toggleAudio(e) {
    e.preventDefault();
    this._showAudio = !this._showAudio;
    this._stateChanged();
    this.render();
  }

  _toggleEmbed() {
    let collapse = $$('#embed', this);
    collapse.closed = !collapse.closed;
  }

  _toggleLottie(e) {
    // avoid double toggles
    e.preventDefault();
    this._showLottie = !this._showLottie;
    this._stateChanged();
    this.render();
  }

  _hideVolumeSlider(v) {
    let collapse = $$('#volume', this);
    collapse.closed = v;
  }

  _upload() {
    // 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_MODE;
      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_MODE;
      // 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_MODE;
      this.render();
    }

  }

});
