<commit_before>import { observable, computed, transaction } from "mobx";
import Immutable from "seamless-immutable";
import { generate } from "shortid";

import elementMap from "../elements";

// TODO: REMOVE. Useful for testing
const allColors = [
  "#EF767A", "#456990", "#49BEAA", "#49DCB1", "#EEB868", "#EF767A", "#456990",
  "#49BEAA", "#49DCB1", "#EEB868", "#EF767A"
];

export default class SlidesStore {
  // Default slides state
  // history will be an array of slides arrays
  @observable history = Immutable.from([{
    currentSlideIndex: 0,
    currentElementIndex: null,
    slides: [{
      // Default first slide
      id: generate(),
      props: {},
      children: [],
      color: allColors[0]
    }, {
      id: generate(),
      props: {},
      children: [],
      color: allColors[1]
    }, {
      id: generate(),
      props: {},
      children: [],
      color: allColors[2]
    }, {
      id: generate(),
      props: {},
      children: [],
      color: allColors[3]
    }, {
      id: generate(),
      props: {},
      children: [],
      color: allColors[4]
    }
  ] }]);

  @observable historyIndex = 0;

  // Returns a new mutable object. Functions as a cloneDeep.
  @computed get slides() {
    return this.history[this.historyIndex].slides.asMutable({ deep: true });
  }

  @computed get currentSlideIndex() {
    return this.history[this.historyIndex].currentSlideIndex;
  }

  @computed get currentElementIndex() {
    return this.history[this.historyIndex].currentElementIndex;
  }

  // Returns a new mutable object. Functions as a cloneDeep.
  @computed get currentSlide() {
    return this.slides[this.currentSlideIndex];
  }

  // Returns a new mutable object. Functions as a cloneDeep.
  @computed get currentElement() {
    return this.currentElementIndex && this.currentSlide[this.currentElementIndex];
  }

  @computed get undoDisabled() {
    return this.historyIndex === 0 || this.history.length <= 1;
  }

  @computed get redoDisabled() {
    return this.historyIndex >= this.history.length - 1;
  }

  @computed get snapshot() {
    return this.history[this.historyIndex].asMutable({ deep: true });
  }

  constructor(slides) {
    if (slides) {
      this.history = Immutable.from([{
        currentSlideIndex: 0,
        currentElementIndex: null,
        slides
      }]);
    }
  }

  dropElement(elementType) {
    const slideToAddTo = this.currentSlide;
    const newSlidesArray = this.slides;

    slideToAddTo.children.push({
      ...elementMap[elementType],
      id: generate()
    });

    newSlidesArray[this.currentSlideIndex] = slideToAddTo;
    const elementIndex = this.currentElementIndex ?
        this.currentElementIndex + 1 :
        slideToAddTo.children.length - 1;

    this._addToHistory({
      currentSlideIndex: this.currentSlideIndex,
      currentElementIndex: elementIndex,
      slides: newSlidesArray
    });
  }

  setCurrentElementIndex(newIndex) {
    const snapshot = this.snapshot;
    snapshot.currentElementIndex = newIndex;

    transaction(() => {
      const left = this.history.slice(0, this.historyIndex);
      const right = this.history.slice(this.historyIndex + 1, this.history.length);
      this.history = left.concat([snapshot], right);
    });
  }

  setSelectedSlideIndex(newSlideIndex) {
    const snapshot = this.snapshot;
    snapshot.currentElementIndex = null;
    snapshot.currentSlideIndex = newSlideIndex;

    transaction(() => {
      const left = this.history.slice(0, this.historyIndex);
      const right = this.history.slice(this.historyIndex + 1, this.history.length);
      this.history = left.concat([snapshot], right);
    });
  }

  moveSlide(currentIndex, newIndex) {
    const slidesArray = this.slides;

    slidesArray.splice(newIndex, 0, slidesArray.splice(currentIndex, 1)[0]);

    this._addToHistory({
      currentSlideIndex: newIndex,
      slides: slidesArray
    });
  }

  addSlide() {
    const slidesArray = this.slides;

    // TODO: Figure out new slide defaults/interface
    const newSlide = {
      id: generate(),<commit_msg>rename this.snapshot to this.currentState<commit_after>import { observable, computed, transaction } from "mobx";
import Immutable from "seamless-immutable";
import { generate } from "shortid";

import elementMap from "../elements";

// TODO: REMOVE. Useful for testing
const allColors = [
  "#EF767A", "#456990", "#49BEAA", "#49DCB1", "#EEB868", "#EF767A", "#456990",
  "#49BEAA", "#49DCB1", "#EEB868", "#EF767A"
];

export default class SlidesStore {
  // Default slides state
  // history will be an array of slides arrays
  @observable history = Immutable.from([{
    currentSlideIndex: 0,
    currentElementIndex: null,
    slides: [{
      // Default first slide
      id: generate(),
      props: {},
      children: [],
      color: allColors[0]
    }, {
      id: generate(),
      props: {},
      children: [],
      color: allColors[1]
    }, {
      id: generate(),
      props: {},
      children: [],
      color: allColors[2]
    }, {
      id: generate(),
      props: {},
      children: [],
      color: allColors[3]
    }, {
      id: generate(),
      props: {},
      children: [],
      color: allColors[4]
    }
  ] }]);

  @observable historyIndex = 0;

  // Returns a new mutable object. Functions as a cloneDeep.
  @computed get slides() {
    return this.history[this.historyIndex].slides.asMutable({ deep: true });
  }

  @computed get currentSlideIndex() {
    return this.history[this.historyIndex].currentSlideIndex;
  }

  @computed get currentElementIndex() {
    return this.history[this.historyIndex].currentElementIndex;
  }

  // Returns a new mutable object. Functions as a cloneDeep.
  @computed get currentSlide() {
    return this.slides[this.currentSlideIndex];
  }

  // Returns a new mutable object. Functions as a cloneDeep.
  @computed get currentElement() {
    return this.currentElementIndex && this.currentSlide[this.currentElementIndex];
  }

  @computed get undoDisabled() {
    return this.historyIndex === 0 || this.history.length <= 1;
  }

  @computed get redoDisabled() {
    return this.historyIndex >= this.history.length - 1;
  }

  @computed get currentState() {
    return this.history[this.historyIndex].asMutable({ deep: true });
  }

  constructor(slides) {
    if (slides) {
      this.history = Immutable.from([{
        currentSlideIndex: 0,
        currentElementIndex: null,
        slides
      }]);
    }
  }

  dropElement(elementType) {
    const slideToAddTo = this.currentSlide;
    const newSlidesArray = this.slides;

    slideToAddTo.children.push({
      ...elementMap[elementType],
      id: generate()
    });

    newSlidesArray[this.currentSlideIndex] = slideToAddTo;
    const elementIndex = this.currentElementIndex ?
        this.currentElementIndex + 1 :
        slideToAddTo.children.length - 1;

    this._addToHistory({
      currentSlideIndex: this.currentSlideIndex,
      currentElementIndex: elementIndex,
      slides: newSlidesArray
    });
  }

  setCurrentElementIndex(newIndex) {
    const snapshot = this.currentState;
    snapshot.currentElementIndex = newIndex;

    transaction(() => {
      const left = this.history.slice(0, this.historyIndex);
      const right = this.history.slice(this.historyIndex + 1, this.history.length);
      this.history = left.concat([snapshot], right);
    });
  }

  setSelectedSlideIndex(newSlideIndex) {
    const snapshot = this.currentState;
    snapshot.currentElementIndex = null;
    snapshot.currentSlideIndex = newSlideIndex;

    transaction(() => {
      const left = this.history.slice(0, this.historyIndex);
      const right = this.history.slice(this.historyIndex + 1, this.history.length);
      this.history = left.concat([snapshot], right);
    });
  }

  moveSlide(currentIndex, newIndex) {
    const slidesArray = this.slides;

    slidesArray.splice(newIndex, 0, slidesArray.splice(currentIndex, 1)[0]);

    this._addToHistory({
      currentSlideIndex: newIndex,
      slides: slidesArray
    });
  }

  addSlide() {
    const slidesArray = this.slides;

    // TODO: Figure out new slide defaults/interface
    const newSlide = {
      id: generate(),
{'fraction_non_alphanumeric': 0.12909535452322737, 'fraction_numerical': 0.01393643031784841, 'mean_word_length': 2.998533724340176, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2235612', 'n_tokens_mistral': 2576, 'n_tokens_neox': 2493, 'n_words': 556}