import {BoundingBoxAttachment} from "@pixi-spine/runtime-4.1";
import {SETTINGS} from "../../../constants/constants";
import AutospinsIndicator from "../AutospinsIndicator.js";
import FreeroundsIndicator from "../FreeroundsIndicator.js";
import TextAttachment from "../../TextAttachment.js";
import Locator from "../../../services/Locator";
import {createStyles} from "../../../utils/styles";
import StatusBar from "../StatusBar";
import BalanceIndicator from "../BalanceIndicator";
import TotalBetIndicator from "../TotalBetIndicator.js";
import FreespinsIndicator from "../FreespinsIndicator.js";
import WinIndicator from "../WinIndicator";
import EmbeddedSpineButton from "../EmbeddedSpineButton";
import {State} from "@popiplay/state-machine";
import SpineScene from "../../SpineScene";

/**
 * The class represents the infoBar.
 * Tracks:
 * 0 - resize animations;
 * 1 - 'spin_start' animation;
 * 2 - 'autospin_disable' and 'autospin_enable' animations
 * 3 - menu animations
 * 4 - quick game indication
 * 5 - sound
 * 6 - freespins
 * 7 - buy_bonus_btn
 * 8 - autospins action
 * 9 - freerounds
 *
 * (i + 1) * 10 + 20 - hover/out/disable buttons animations;
 * (i + 1) * 10 + 21 - down/up buttons animations;
 */

//casinoFreespins/hide-indicator - скрытие индикатора фриспинов
// casinoFreespins/show-indicator - отображение индикатора фриспинов

const styles = createStyles({
  skin: "desktop",
  "(orientation: landscape) and (max-height: 500px)": {
    skin: "mobile",
  }
});

const BONUS_GAME_INDICATION_STATES = {
  INACTIVE: 0,
  ACTIVE: 1,
};

const AUTO_SPINS_INDICATION_STATES = {
  INACTIVE: 0,
  ACTIVE: 1,
};

const CASINO_ROUNDS_INDICATION_STATES = {
  INACTIVE: 0,
  ACTIVE: 1,
};

const TURBO_INDICATION_STATES = {
  INACTIVE: 0,
  ACTIVE: 1,
};

const SOUND_INDICATION_STATES = {
  INACTIVE: 0,
  ACTIVE: 1,
};

const MENU_STATES = {
  HIDDEN: 0,
  SHOWN: 1,
};

const BUY_BONUS_INDICATION_STATES = {
  AVAILABLE_TO_BUY: 0,
  ACTIVATED: 1,
  BET_FEATURE: 2,
};

export default class InfoBar extends SpineScene {
  constructor(inputs, options) {
    super("keyboard");

    this.inputs = inputs || {
      title: "game_name",
      balance: "0",
      win: null,
      totalWin: null,
      bet: "0",
      isMinBet: false,
      isMaxBet: false,
      areBetsLocked: false,
      canBuyBonus: false,
      isAutoGameAvailable: false,
      isAutoGameActive: false,
      autoRoundsLeft: 0,
      isTurboModeActive: false,
      isCasinoRoundsActive: false,
      casinoRoundsIssued: 0,
      casinoRoundsLeft: 0,
      bonusGameActive: false,
      bonusGameIndicatorTitle: "",
      bonusGameIndicatorIssued: 0,
      bonusGameIndicatorLeft: 0,
      isMute: false,
      isMenuShown: false,
      betFeatureActive: false,
      isMinusButtonPressed: false,
      isPlusButtonPressed: false,
      isMaxButtonPressed: false,
      isTurboButtonPressed: false,
      isSoundOnButtonPressed: false,
      isSoundOffButtonPressed: false,
      isStopAutoGameButtonPressed: false,
      isAutoGameButtonPressed: false,
      isSpinButtonPressed: false,
      isBuyBonusButtonPressed: false,
      isRoundStarted: false,
      isSettingsButtonPressed: false,
      isHomeButtonPressed: false,
      isLobbyLink: true,
    };

    this.options = options;

    this.buttons = {};
    this.menuButtons = [];

    this.tempData = {
      isRoundStarted: false,
    };

    this.createSpine();
    this.createBalanceIndicator();
    this.createBetIndicator();
    this.createFreespinsIndicator();
    this.createFreeroundsIndicator();
    this.createAutospinIndicator();
    this.createTurboIndicator();
    this.createSoundIndicator();
    this.createWinIndicator();
    this.createMaxBtnText();
    this.createStatusBar();
    this.createBuyBonusIndication();
    this.createMenuStates();
    this.setupButtons();
    this.setupMenuButtons();
    this.setupListeners();
    this.resize();
  }

  setupListeners() {
    this.handleKeyDown = this.handleKeyDown.bind(this);
    this.handleKeyUp = this.handleKeyUp.bind(this);
    window.addEventListener("keydown", this.handleKeyDown);
    window.addEventListener("keyup", this.handleKeyUp);
    this.state.addListener({
      event: (entry, event) => {
        if (event.data.name === "menu_btn/up") this.handleMenuBtnUp();
        if (event.data.name === "menu_btn/upoutside") this.handleMenuBtnUp();
        if (event.data.name === "minus_btn/down") this.inputs.isMinusButtonPressed = true;
        if (event.data.name === "plus_btn/down") this.inputs.isPlusButtonPressed = true;
        if (event.data.name === "max_btn/down") this.inputs.isMaxButtonPressed = true;
        if (event.data.name === "quick_btn/down") this.inputs.isTurboButtonPressed = true;
        if (event.data.name === "sound_on_btn/down") this.inputs.isSoundOnButtonPressed = true;
        if (event.data.name === "sound_off_btn/down") this.inputs.isSoundOffButtonPressed = true;
        if (event.data.name === "autospin_stop_btn/down") this.inputs.isStopAutoGameButtonPressed = true;
        if (event.data.name === "autospin_btn/down") this.inputs.isAutoGameButtonPressed = true;
        if (event.data.name === "settings_btn/down") this.inputs.isSettingsButtonPressed = true;
        if (event.data.name === "spin_btn/down") this.inputs.isSpinButtonPressed = true;
        if (event.data.name === "minus_btn/up") this.inputs.isMinusButtonPressed = false;
        if (event.data.name === "minus_btn/upoutside") this.inputs.isMinusButtonPressed = false;
        if (event.data.name === "plus_btn/down") this.inputs.isPlusButtonPressed = true;
        if (event.data.name === "plus_btn/up") this.inputs.isPlusButtonPressed = false;
        if (event.data.name === "plus_btn/upoutside") this.inputs.isPlusButtonPressed = false;
        if (event.data.name === "max_btn/down") this.inputs.isMaxButtonPressed = true;
        if (event.data.name === "max_btn/up") this.inputs.isMaxButtonPressed = false;
        if (event.data.name === "max_btn/upoutside") this.inputs.isMaxButtonPressed = false;
        if (event.data.name === "quick_btn/down") this.inputs.isTurboButtonPressed = true;
        if (event.data.name === "quick_btn/up") this.inputs.isTurboButtonPressed = false;
        if (event.data.name === "quick_btn/upoutside") this.inputs.isTurboButtonPressed = false;
        if (event.data.name === "sound_on_btn/up") this.inputs.isSoundOnButtonPressed = false;
        if (event.data.name === "sound_on_btn/upoutside") this.inputs.isSoundOnButtonPressed = false;
        if (event.data.name === "sound_off_btn/up") this.inputs.isSoundOffButtonPressed = false;
        if (event.data.name === "sound_off_btn/upoutside") this.inputs.isSoundOffButtonPressed = false;
        if (event.data.name === "autospin_stop_btn/up") this.inputs.isStopAutoGameButtonPressed = false;
        if (event.data.name === "autospin_stop_btn/upoutside") this.inputs.isStopAutoGameButtonPressed = false;
        if (event.data.name === "autospin_btn/up") this.inputs.isAutoGameButtonPressed = false;
        if (event.data.name === "autospin_btn/upoutside") this.inputs.isAutoGameButtonPressed = false;
        if (event.data.name === "spin_btn/down") this.inputs.isSpinButtonPressed = true;
        if (event.data.name === "spin_btn/up") this.inputs.isSpinButtonPressed = false;
        if (event.data.name === "spin_btn/upoutside") this.inputs.isSpinButtonPressed = false;
        if (event.data.name === "settings_btn/up") this.inputs.isSettingsButtonPressed = false;
        if (event.data.name === "settings_btn/upoutside") this.inputs.isSettingsButtonPressed = false;
        if (event.data.name === "paytable_btn/up") this.inputs.isPaytableButtonPressed = false;
        if (event.data.name === "paytable_btn/upoutside") this.inputs.isPaytableButtonPressed = false;
        if (event.data.name === 'paytable_btn/down') {
          this.inputs.isUserInputLocked = true;
          this.inputs.isPaytableButtonPressed = true;
        }

        if (event.data.name === "info_btn/up") this.inputs.isRulesButtonPressed = false;
        if (event.data.name === "info_btn/upoutside") this.inputs.isRulesButtonPressed = false;
        if (event.data.name === 'info_btn/down') {
          this.inputs.isUserInputLocked = true;
          this.inputs.isRulesButtonPressed = true;
        }

        if (event.data.name === "buy_bonus_btn/down") this.inputs.isBuyBonusButtonPressed = true;
        if (event.data.name === "buy_bonus_btn/up") this.inputs.isBuyBonusButtonPressed = false;
        if (event.data.name === "buy_bonus_btn/upoutside") this.inputs.isBuyBonusButtonPressed = false;
        if (event.data.name === "home_btn/down") this.inputs.isHomeButtonPressed = true;
        if (event.data.name === "home_btn/up") this.inputs.isHomeButtonPressed = false;
        if (event.data.name === "home_btn/upoutside") this.inputs.isHomeButtonPressed = false;
        this.emit("infobar/" + event.data.name, event);
      }
    });
  }

  createBetIndicator() {
    this.betIndicator = new TotalBetIndicator({width: 100, height: 50}, this.options);
    this.betIndicator.attachTo(this, "bet_indicator");
    this.betIndicator.boundaries = false;
  }

  createBalanceIndicator() {
    this.balanceIndicator = new BalanceIndicator({width: 130, height: 50}, this.options);
    this.balanceIndicator.attachTo(this, "balance_indicator");
    this.balanceIndicator.boundaries = false;
  }

  createFreespinsIndicator() {
    this.bonusIndicatorStates = [
      new BonusGameIndicatorInactiveState(this),
      new BonusGameIndicatorActiveState(this)
    ];
    this.freespinsIndicator = new FreespinsIndicator({width: 110, height: 50}, this.options);
    this.freespinsIndicator.attachTo(this, "freespins_indicator");
    this.freespinsIndicator.boundaries = false;
    this.setBonusIndicatorState(BONUS_GAME_INDICATION_STATES.INACTIVE);
  }

  createFreeroundsIndicator() {
    this.casinoRoundsIndicatorStates = [
      new CasinoRoundsIndicatorInactiveState(this),
      new CasinoRoundsIndicatorActiveState(this)
    ];
    this.freeroundsIndicator = new FreeroundsIndicator({width: 140, height: 25}, this.options);
    this.freeroundsIndicator.attachTo(this, "freerounds_indicator");
    this.freeroundsIndicator.boundaries = false;
    this.setCasinoRoundsIndicatorState(CASINO_ROUNDS_INDICATION_STATES.INACTIVE);
  }

  createAutospinIndicator() {
    this.autospinsStates = [
      new AutoSpinsInactiveState(this),
      new AutoSpinsActiveState(this),
    ];
    this.autospinsIndicator = new AutospinsIndicator({width: 50, height: 30}, this.options);
    this.autospinsIndicator.attachTo(this, "autospins_indicator");
    this.autospinsIndicator.boundaries = false;

    this.setAutoSpinsState(AUTO_SPINS_INDICATION_STATES.INACTIVE);
  }

  createWinIndicator() {
    this.winIndicator = new WinIndicator({width: 300, height: 50}, this.options);
    this.winIndicator.attachTo(this, "win_indicator");
    this.winIndicator.boundaries = false;
  }

  createTurboIndicator() {
    this.turboIndicatorStates = [
      new TurboIndicatorInactiveState(this),
      new TurboIndicatorActiveState(this)
    ];
    this.setTurboIndicatorState(TURBO_INDICATION_STATES.INACTIVE);
  }

  createSoundIndicator() {
    this.soundIndicatorStates = [
      new SoundIndicatorInactiveState(this),
      new SoundIndicatorActiveState(this)
    ];
    this.setSoundIndicatorState(SOUND_INDICATION_STATES.INACTIVE);
  }

  createStatusBar() {
    this.statusBar = new StatusBar(this.inputs, this.options);
    this.statusBar.attachTo(this, "statusbar");
    this.statusBar.boundaries = false;
  }

  createBuyBonusIndication() {
    this.buyBonusText = new TextAttachment({width: 30, height: 30}, this.options);
    this.buyBonusText.style = {
      fontFamily: "Oxanium, Opensans",
      fontSize: 10,
      fill: 0xffffff,
      wordWrap: true,
      wordWrapWidth: 30,
      fontWeight: "bold",
      align: "center",
      lineHeight: 10,
    };
    this.buyBonusText.autoScaleToFit = true;
    this.buyBonusText.boundaries = false;
    this.buyBonusText.center();
    this.buyBonusText.attachTo(this, "buy_bonus_btn_text");

    this.buyBonusIndicationStates = [
      new BuyBonusAvailableState(this),
      new BuyBonusActiveState(this),
      new BetFeatureActiveState(this)
    ];
    this.setBuyBonusIndicationState(BUY_BONUS_INDICATION_STATES.AVAILABLE_TO_BUY);
  }

  createMaxBtnText() {
    this.maxBtnText = new TextAttachment({width: 30, height: 30}, this.options);
    this.maxBtnText.style = {
      fontFamily: "Oxanium, Opensans",
      fontSize: 10,
      fill: 0xffffff,
      align: "center",
      lineHeight: 10,
    };
    this.maxBtnText.content = {key: "max_btn"};
    this.maxBtnText.autoScaleToFit = true;
    this.maxBtnText.boundaries = false;
    this.maxBtnText.center();
    this.maxBtnText.attachTo(this, "max_btn_txt");
    this.maxBtnText.update();
  }

  createMenuStates() {
    this.menuStates = [
      new MenuHiddenState(this),
      new MenuShownState(this)
    ];
    this.setMenuState(MENU_STATES.HIDDEN);
    this.state.setAnimation(3, "commands/menu_hidden", false);
  }

  createSpine() {
    this.stateData.setMix("commands/autospins_on", "commands/autospins_off", 0.2);
    this.stateData.setMix("commands/autospins_off", "commands/autospins_on", 0.2);
    this.stateData.setMix("commands/freerounds_on", "commands/freerounds_off", 0.2);
    this.stateData.setMix("commands/freerounds_off", "commands/freerounds_on", 0.2);
    this.autoUpdate = false;
    super.update(0);
    this.skeleton.setToSetupPose();
  }

  update(delta) {
    this.currentBonusIndicatorState.handleInput(this.inputs.bonusGameActive);
    this.currentAutospinsState.handleInput(this.inputs.isAutoGameActive);
    this.currentCasinoRoundsIndicatorState.handleInput(this.inputs.isCasinoRoundsActive);
    this.currentTurboIndicatorState.handleInput(this.inputs.isTurboModeActive);
    this.currentSoundIndicatorState.handleInput(!this.inputs.isMute);
    this.currentMenuState.handleInput(this.inputs.isMenuShown);
    this.currentBuyBonusIndicatorState.handleInput({
      bonusGameActive: this.inputs.bonusGameActive,
      betFeatureActive: this.inputs.betFeatureActive,
    });

    this.balanceIndicator.value = this.inputs.balance;
    this.balanceIndicator.update();
    this.betIndicator.value = this.inputs.bet;
    this.betIndicator.update();
    this.statusBar.text = this.inputs.title;
    this.statusBar.update();
    this.freespinsIndicator.label = Locator.locales.get(this.inputs.bonusGameIndicatorTitle);
    this.freespinsIndicator.issued = this.inputs.bonusGameIndicatorIssued;
    this.freespinsIndicator.left = this.inputs.bonusGameIndicatorTitle === 'freespins_label'
      ? this.inputs.bonusGameIndicatorIssued - this.inputs.bonusGameIndicatorLeft
      : this.inputs.bonusGameIndicatorLeft;
    this.freespinsIndicator.update();
    this.freeroundsIndicator.issued = this.inputs.casinoRoundsIssued;
    this.freeroundsIndicator.left = this.inputs.casinoRoundsLeft;
    this.freeroundsIndicator.update();
    this.winIndicator.win = this.inputs.win;
    this.winIndicator.totalWin = this.inputs.totalWin;
    this.winIndicator.update();
    this.autospinsIndicator.left = this.inputs.autoRoundsLeft;
    this.autospinsIndicator.update();
    const {isSpinButtonHold, isSpinButtonPressed} = this.inputs;
    this.buttons.menu_btn.disabled = this.inputs.isAutoGameActive || this.inputs.isSpinButtonHold;
    this.buttons.minus_btn.disabled = this.inputs.areBetsLocked || this.inputs.isMinBet;
    this.buttons.plus_btn.disabled = this.inputs.areBetsLocked || this.inputs.isMaxBet;
    this.buttons.max_btn.disabled = this.inputs.areBetsLocked || this.inputs.isMaxBet;
    this.buttons.bet_btn.disabled = this.inputs.areBetsLocked;
    this.buttons.bet_indicator.disabled = this.inputs.areBetsLocked;
    this.buttons.autospin_btn.disabled = !this.inputs.isAutoGameAvailable || this.inputs.isAutoGameActive;
    this.buttons.buy_bonus_btn.disabled = !this.inputs.canBuyBonus;
    this.buttons.home_btn.disabled = !__OPTIONS__.ui.home_button || !this.inputs.isLobbyLink ;

    this.handleStartRound();

    super.update(Locator.clock.deltaMS * 0.001);
  }

  handleStartRound() {
    if (!this.tempData.isRoundStarted && this.inputs.isRoundStarted) {
      this.state.setAnimation(1, "spin_btn/action", false);
      this.state.setAnimation(8, "autospin_indicator/action", false);
    }
    this.tempData.isRoundStarted = this.inputs.isRoundStarted;
  }


  resize() {
    this.position.set(
      SETTINGS.viewport.width * 0.5,
      SETTINGS.viewport.height
    );
    this.skeleton.setSkin(null);
    this.skeleton.setSkinByName(this.resizeSkin);
    this.skeleton.setToSetupPose();
    this.statusBar.resize();
    this.setupButtons();

    const x = Math.min(SETTINGS.viewport.width * 0.5 - Locator.viewport.left, 450);
    this.skeleton.findBone("right").x = x;
    this.skeleton.findBone("left").x = -x;
    this.skeleton.findBone("top").y = SETTINGS.viewport.height;

    const portraitScaleBone = this.skeleton.findBone("portrait_scale/>20");
    const portraitScale = Math.min(Locator.viewport.cropWidthRatio * SETTINGS.viewport.width / 250, 1);
    portraitScaleBone.scaleX = portraitScale;
    portraitScaleBone.scaleY = portraitScale;

    this.autospinsIndicator.resize();
  }

  get resizeSkinPrefix() {
    return styles.skin + "/" + ">";
  }

  setupButtons() {
    this.skeleton.slots.forEach((slot, i) => {
      if (slot.attachment instanceof BoundingBoxAttachment) {
        const slotName = slot.attachment.name.replace("_bbx", "");
        const track = i * 10 + 20;
        this.buttons[slotName]?.removeAllListeners();
        this.buttons[slotName] = new EmbeddedSpineButton(this, slotName, track, track + 1);
      }
    });
  }

  // --------------------------------------
  // Bonus indicator state control
  // --------------------------------------

  setBonusIndicatorInactive() {
    this.state.setAnimation(6, "commands/freespins_off", false);
  }

  setBonusIndicatorActive() {
    this.state.setAnimation(6, "commands/freespins_on", false);
  }

  setBonusIndicatorState(state) {
    this.currentBonusIndicatorState = this.bonusIndicatorStates[state];
    this.currentBonusIndicatorState.enter();
  }

  // --------------------------------------
  // Auto spins indicator state control
  // --------------------------------------

  setAutoSpinsInactive() {
    this.state.setAnimation(2, "commands/autospins_off", false);
  }

  setAutoSpinsActive() {
    this.state.setAnimation(2, "commands/autospins_on", false);
  }

  setAutoSpinsState(state) {
    this.currentAutospinsState = this.autospinsStates[state];
    this.currentAutospinsState.enter();
  }

  // --------------------------------------
  // Casino rounds indicator state control
  // --------------------------------------

  setCasinoRoundsIndicatorInactive() {
    this.state.setAnimation(9, "commands/freerounds_off", false);
  }

  setCasinoRoundsIndicatorActive() {
    this.state.setAnimation(9, "commands/freerounds_on", false);
  }

  setCasinoRoundsIndicatorState(state) {
    this.currentCasinoRoundsIndicatorState = this.casinoRoundsIndicatorStates[state];
    this.currentCasinoRoundsIndicatorState.enter();
  }

  // --------------------------------------
  // Turbo indicator state control
  // --------------------------------------

  setTurboIndicatorInactive() {
    this.state.setAnimation(4, "commands/quick_off", false);
  }

  setTurboIndicatorActive() {
    this.state.setAnimation(4, "commands/quick_on", false);
  }

  setTurboIndicatorState(state) {
    this.currentTurboIndicatorState = this.turboIndicatorStates[state];
    this.currentTurboIndicatorState.enter();
  }

  // --------------------------------------
  // Sound indicator state control
  // --------------------------------------

  setSoundIndicatorInactive() {
    this.state.setAnimation(5, "commands/sound_off", false);
  }

  setSoundIndicatorActive() {
    this.state.setAnimation(5, "commands/sound_on", false);
  }

  setSoundIndicatorState(state) {
    this.currentSoundIndicatorState = this.soundIndicatorStates[state];
    this.currentSoundIndicatorState.enter();
  }

  // --------------------------------------
  // Menu state control
  // --------------------------------------

  setMenuHidden() {
    Locator.events.off("globalpointerdown", this.handleGlobalPointerDown, this);
    this.state.setAnimation(3, "commands/hide_menu", false);
    this.state.addAnimation(3, "commands/menu_hidden", false, 0);
  }

  setMenuShown() {
    Locator.events.on("globalpointerdown", this.handleGlobalPointerDown, this);
    this.state.setAnimation(3, "commands/show_menu", false);
    this.state.addAnimation(3, "commands/menu_shown", false, 0);
  }

  setMenuState(state) {
    this.currentMenuState = this.menuStates[state];
    this.currentMenuState.enter();
  }

  handleMenuBtnUp() {
    this.inputs.isMenuShown = !this.inputs.isMenuShown;
  }

  setupMenuButtons() {
    const menuBone = this.skeleton.findBone("menu_group");
    this.menuButtons = menuBone.children.map(btnBone => this.buttons[btnBone.data.name]);
  }

  handleGlobalPointerDown(e) {
    this.checkPointerOnMenu(e);
  }

  checkPointerOnMenu(e) {
    const obj = Locator.renderer.events.rootBoundary.hitTest(e.global.x, e.global.y);
    const isHit = this.menuButtons.some(btn => btn.container === obj);
    if (!isHit) {
      this.inputs.isMenuShown = false;
    }
  }

  handleKeyDown(e) {
    if (e.keyCode === 32) {
      if (this.inputs.isSpaceBarHandlingActive && !this.inputs.isUserInputLocked) {
        this.inputs.isSpinButtonPressed = true;
      }
    }
  }

  handleKeyUp(e) {
    if (e.keyCode === 32) {
      if (this.inputs.isSpaceBarHandlingActive && !this.inputs.isUserInputLocked) {
        this.inputs.isSpinButtonPressed = false;
      }
    }
  }

  // --------------------------------------
  // Bonus buy indication state control
  // --------------------------------------

  setBuyBonusIndicationState(state) {
    this.currentBuyBonusIndicatorState = this.buyBonusIndicationStates[state];
    this.currentBuyBonusIndicatorState.enter();
  }

  setBuyBonusAvailable() {
    this.state.setAnimation(10, "buy_bonus_btn/set_buy_bonus", false);
    this.buyBonusText.content = { key: "buy_bonus", transformMethod: 'toUpperCase' };
    this.buyBonusText.center();
    this.buyBonusText.update();
  }

  setBuyBonusActive() {
    this.state.setAnimation(10, "buy_bonus_btn/set_active", false);
    this.buyBonusText.content = { key: "active", transformMethod: 'toUpperCase' };
    this.buyBonusText.center();
    this.buyBonusText.update();
  }

  setBetFeatureActive() {
    this.state.setAnimation(10, "buy_bonus_btn/set_wild_spin", false);
    this.buyBonusText.content = { key: "wild_spin", transformMethod: 'toUpperCase' };
    this.buyBonusText.center();
    this.buyBonusText.update();
  }
}

//-----------------------------------------------------------
// States
//-----------------------------------------------------------

class BonusGameIndicatorInactiveState extends State {
  constructor(infoBar) {
    super("BonusGameIndicatorInactive");
    this.infoBar = infoBar;
  }

  enter() {
    this.infoBar.setBonusIndicatorInactive();
  }

  handleInput(inputState) {
    if (inputState === true) {
      this.infoBar.setBonusIndicatorState(BONUS_GAME_INDICATION_STATES.ACTIVE);
    }
  }
}

class BonusGameIndicatorActiveState extends State {
  constructor(infoBar) {
    super("BonusGameIndicatorActive");
    this.infoBar = infoBar;
  }

  enter() {
    this.infoBar.setBonusIndicatorActive();
  }

  handleInput(inputState) {
    if (inputState === false) {
      this.infoBar.setBonusIndicatorState(BONUS_GAME_INDICATION_STATES.INACTIVE);
    }
  }
}

class AutoSpinsInactiveState extends State {
  constructor(infoBar) {
    super("AutoSpinsInactiveState");
    this.infoBar = infoBar;
  }

  enter() {
    this.infoBar.setAutoSpinsInactive();
  }

  handleInput(inputState) {
    if (inputState === true) {
      this.infoBar.setAutoSpinsState(AUTO_SPINS_INDICATION_STATES.ACTIVE);
    }
  }
}

class AutoSpinsActiveState extends State {
  constructor(infoBar) {
    super("AutoSpinsActiveState");
    this.infoBar = infoBar;
  }

  enter() {
    this.infoBar.setAutoSpinsActive();
  }

  handleInput(inputState) {
    if (inputState === false) {
      this.infoBar.setAutoSpinsState(AUTO_SPINS_INDICATION_STATES.INACTIVE);
    }
  }
}

class CasinoRoundsIndicatorInactiveState extends State {
  constructor(infoBar) {
    super("CasinoRoundsIndicatorInactiveState");
    this.infoBar = infoBar;
  }

  enter() {
    this.infoBar.setCasinoRoundsIndicatorInactive();
  }

  handleInput(inputState) {
    if (inputState === true) {
      this.infoBar.setCasinoRoundsIndicatorState(CASINO_ROUNDS_INDICATION_STATES.ACTIVE);
    }
  }
}

class CasinoRoundsIndicatorActiveState extends State {
  constructor(infoBar) {
    super("CasinoRoundsIndicatorActiveState");
    this.infoBar = infoBar;
  }

  enter() {
    this.infoBar.setCasinoRoundsIndicatorActive();
  }

  handleInput(inputState) {
    if (inputState === false) {
      this.infoBar.setCasinoRoundsIndicatorState(CASINO_ROUNDS_INDICATION_STATES.INACTIVE);
    }
  }
}

class TurboIndicatorInactiveState extends State {
  constructor(infoBar) {
    super("TurboIndicatorInactiveState");
    this.infoBar = infoBar;
  }

  enter() {
    this.infoBar.setTurboIndicatorInactive();
  }

  handleInput(inputState) {
    if (inputState === true) {
      this.infoBar.setTurboIndicatorState(TURBO_INDICATION_STATES.ACTIVE);
    }
  }
}

class TurboIndicatorActiveState extends State {
  constructor(infoBar) {
    super("TurboIndicatorActiveState");
    this.infoBar = infoBar;
  }

  enter() {
    this.infoBar.setTurboIndicatorActive();
  }

  handleInput(inputState) {
    if (inputState === false) {
      this.infoBar.setTurboIndicatorState(TURBO_INDICATION_STATES.INACTIVE);
    }
  }
}

class SoundIndicatorInactiveState extends State {
  constructor(infoBar) {
    super("SoundIndicatorInactiveState");
    this.infoBar = infoBar;
  }

  enter() {
    this.infoBar.setSoundIndicatorInactive();
  }

  handleInput(inputState) {
    if (inputState === true) {
      this.infoBar.setSoundIndicatorState(SOUND_INDICATION_STATES.ACTIVE);
    }
  }
}

class SoundIndicatorActiveState extends State {
  constructor(infoBar) {
    super("SoundIndicatorActiveState");
    this.infoBar = infoBar;
  }

  enter() {
    this.infoBar.setSoundIndicatorActive();
  }

  handleInput(inputState) {
    if (inputState === false) {
      this.infoBar.setSoundIndicatorState(SOUND_INDICATION_STATES.INACTIVE);
    }
  }
}

class MenuHiddenState extends State {
  constructor(infoBar) {
    super("MenuHiddenState");
    this.infoBar = infoBar;
  }

  enter() {
    this.infoBar.setMenuHidden();
  }

  handleInput(inputState) {
    if (inputState === true) {
      this.infoBar.setMenuState(MENU_STATES.SHOWN);
    }
  }
}

class MenuShownState extends State {
  constructor(infoBar) {
    super("MenuShownState");
    this.infoBar = infoBar;
  }

  enter() {
    this.infoBar.setMenuShown();
  }

  handleInput(inputState) {
    if (inputState === false) {
      this.infoBar.setMenuState(MENU_STATES.HIDDEN);
    }
  }
}


class BuyBonusAvailableState extends State {
  constructor(infoBar) {
    super("BuyBonusAvailableState");
    this.infoBar = infoBar;
  }

  enter() {
    this.infoBar.setBuyBonusAvailable();
  }

  handleInput({bonusGameActive, betFeatureActive}) {
    if (bonusGameActive) {
      this.infoBar.setBuyBonusIndicationState(BUY_BONUS_INDICATION_STATES.ACTIVATED);
    } else if (betFeatureActive) {
      this.infoBar.setBuyBonusIndicationState(BUY_BONUS_INDICATION_STATES.BET_FEATURE);
    }
  }
}

class BuyBonusActiveState extends State {
  constructor(infoBar) {
    super("BuyBonusActiveState");
    this.infoBar = infoBar;
  }

  enter() {
    this.infoBar.setBuyBonusActive();
  }

  handleInput({bonusGameActive}) {
    if (bonusGameActive === false) {
      this.infoBar.setBuyBonusIndicationState(BUY_BONUS_INDICATION_STATES.AVAILABLE_TO_BUY);
    }
  }
}

class BetFeatureActiveState extends State {
  constructor(infoBar) {
    super("BetFeatureActiveState");
    this.infoBar = infoBar;
  }

  enter() {
    this.infoBar.setBetFeatureActive();
  }

  handleInput({bonusGameActive, betFeatureActive}) {
    if (bonusGameActive) {
      this.infoBar.setBuyBonusIndicationState(BUY_BONUS_INDICATION_STATES.ACTIVATED);
    } else if (betFeatureActive === false) {
      this.infoBar.setBuyBonusIndicationState(BUY_BONUS_INDICATION_STATES.AVAILABLE_TO_BUY);
    }
  }

  destroy() {
    window.removeEventListener("keydown", this.handleKeyDown);
    window.removeEventListener("keyup", this.handleKeyUp);
    this.statusBar.destroy();
    this.buyBonusText.destroy();
    this.maxBtnText.destroy();
    this.betIndicator.destroy();
    this.balanceIndicator.destroy();
    this.freespinsIndicator.destroy();
    this.freeroundsIndicator.destroy();
    this.autospinsIndicator.destroy();
    this.winIndicator.destroy();
  }
}
