/*
How to create a battle scene.
Scene(createBattleScene([
  [`avenger`, [0, 0, 0]],
  [`child`, [1, 0, -1]],
  [`protector`, [-1, 1, 0]],
  [`persecutor`, [-1, 0, 1]],
],5));
*/

import { add } from 'pura/vector/tuple';
import { camera, } from 'camera';
import { uiElements } from 'ui';
import Song from 'audio';
import battleMusic from 'songs/summer';
import finalBossMusic from 'songs/winter';
import Menu from 'menu';
import StatusBar from 'battle/statusBar';
import BattleMap from 'battle/map';
import { initializeMap, turnOrder, moveCharacter, getGridHexFromVector2d } from 'battle/grid';
import Move from 'battle/actions/Move';
import {
  Attack, Defend, Magic, Item,
} from 'battle/actions/PlayerAbilities';
import Swarmer from 'battle/actions/Swarmer';
import Vamp from 'battle/actions/Vamp';
import Skeli from 'battle/actions/Skeli';
import Resentment from 'battle/actions/Resentment';
import Doubt from 'battle/actions/Doubt';
import Deceit from 'battle/actions/Deceit';
import state from 'state';
import { handlStatuses } from 'battle/actions/utility';

const cameraOffset = [0, -150];

function* generateGetCharacter(turnOrder) {
  let i = 0;
  while(true) {
    const char = turnOrder[i % (turnOrder.length)];
    ++i;
    const [, health] = char;
    if(health > 0) {
      yield char;
    }
  }
}

let harmTurns = 0;

export default function createBattleScene(characters, mapSize) {
  initializeMap(characters, mapSize);

  let turn = null;
  let selectedAction = null;
  const action = {
    // Player Controlled Character Movement
    move: [`Move`, () => selectedAction = Move],
    attack: [`Avenge`, () => selectedAction = Attack],
    defend: [`Protect`, () => selectedAction = Defend],
    magic: [`Forget`, () => selectedAction = Magic],
    item: [`Use`, () => selectedAction = Item],
    swarmer: Swarmer,
    vamp: Vamp,
    skeli: Skeli,
    resentment: Resentment,
    doubt: Doubt,
    deceit: Deceit,
    *harm() {
      yield* [Doubt, Resentment, Deceit][++harmTurns % 9 / 3 | 0];
    }
  };

  const getCharacter = generateGetCharacter(turnOrder);
  function* Turn() {
    // 1) Determine who's turn it is.
    const { value: character } = getCharacter.next();
    const [data, health, position] = character;
    state.target = getGridHexFromVector2d(position);
    console.log(`------------------------------`);
    console.log(`${data.name} : ${health}`);
    // 2) Center Camera on that person.
    const panCamera = moveCharacter(camera, add(cameraOffset, position), 2000);
    console.log(`Paning Camera from ${camera} to ${add(cameraOffset, position)}`);
    while(!panCamera()) yield;
    // 3) Look up actions
    selectedAction = null;
    if(data.type) {
      let actions;
      switch(data.name) {
        case `Persecutor`:
          actions = [
            action.move,
            action.item,
          ];
          break;
        default:
          actions = Object.keys(data.abilities).map(name => action[name]);
        // 4) Add actions to the menu
      }
      const menuUIIndex = uiElements.push(Menu(actions));
      // 5) Wait for player to select an action.
      while(!selectedAction) yield;
      uiElements.splice(menuUIIndex - 1, 1);
    } else {
      selectedAction = action[data.name.toLowerCase()];
    }
    // 6) Execute selected action
    yield* selectedAction(character);
    handlStatuses(character);
    // 7) Check to see if battle is over
    const isVictory = false;//!!turnOrder.find(([data, health]) => !data.alignment && health > 0);
    const isDefeat = false;//!isVictory && !!turnOrder.find(([data, health]) => data.alignment && health > 0);
    console.log(`------------------------------`);
    return isVictory ? 1 :
      isDefeat ? 2 :
        0;
  }

  const bgMusic = new Song(battleMusic || finalBossMusic);

  return {
    init: () => {
      bgMusic.play(bgMusic);
      camera[2] = 340;
      uiElements.push(BattleMap, StatusBar);
      turn = Turn();
      state.logic = () => {
        // done: is turn over.
        // value: battle status, 0: ongoing, 1: victory, 2: defeat;
        const { value, done } = turn.next();
        if(done && value === 0) {
          // 8) Increment turn counter
          // 9A) Create New turn
          turn = Turn();
        } else if(done && value === 1) {
          // 9B) VICTORY
        } else if(done && value === 2) {
          // 9C) DEFEAT
        }
      };
    },
    dismiss: () => {
      bgMusic.stop();
    },
  };
}

@@ -277,24 +277,27 @@
  from 'ui';%0A
+// 
 import Song 
@@ -310,16 +310,19 @@
 audio';%0A
+// 
 import b
@@ -349,24 +349,27 @@
 gs/summer';%0A
+// 
 import final
@@ -3744,16 +3744,19 @@
 ;%0A  %7D%0A%0A 
+ //
  const b
@@ -3832,32 +3832,35 @@
 t: () =%3E %7B%0A     
+ //
  bgMusic.play(bg
@@ -4442,16 +4442,19 @@
  %7B%0A     
+ //
  bgMusic

Remove background music