
// Fireworks.java
// Thomas E. Dickey, Feb. 2020
// Modified by Andrew Davison, ad@coe.psu.ac.th, March 2023

/* Shoot off a firework from a random location on the
   'floor' of the window, see it travel upward, and then
   explode in a random color. A 'bang' sound is played (if
   possible).

   Uses Lanterna 3
   https://github.com/mabe02/lanterna

   Usage (Windows):
     > compile.bat Fireworks.java
     > run.bat Fireworks

   Usage (Linux):
     > ./compile.sh Fireworks.java
     > ./run.sh Fireworks

*/

import java.io.*;
import java.util.*;

import com.googlecode.lanterna.*;
import com.googlecode.lanterna.screen.*;
import com.googlecode.lanterna.terminal.*;
import com.googlecode.lanterna.graphics.*;
import com.googlecode.lanterna.input.*;


public class Fireworks
{
  private static TextColor.ANSI BG = TextColor.ANSI.BLACK;
                                    // TextColor.ANSI.BLUE;
                            // background color for the scene

  private static Random rand = new Random();


  public static void main(String[] args)
  {
    Screen scr = Utils.createScreen();
    scr.setCursorPosition(null);

    TerminalSize termSz = scr.getTerminalSize();
    int numCols = termSz.getColumns();
    int numRows = termSz.getRows();

    Utils.fill(scr, BG);
    while(true) {
      KeyStroke ks = Utils.pollInput(scr);
      if (Utils.hasQuit(ks))
        break;

      // calculate firework path upwards
      int xStart, xEnd, direction, diff;
      do {
        // random x-coords, away from the edges
        xStart = rand.nextInt() % (numCols-3);
        xEnd = rand.nextInt() % (numCols-3);
        xStart = (xStart < 2) ? 2 : xStart;
        xEnd = (xEnd < 2) ? 2 : xEnd;

        direction = (xStart > xEnd) ? -1 : 1;
        diff = Math.abs(xStart-xEnd); // angle between start and end
      } while ((diff < 5) || (diff >= numRows-2));

      // shoot the firework
      boolean wipeNow = false;
      int row;
      for (row = 1; row < diff; row++) {
        Utils.putString(scr, xStart+(row * direction),
                numRows-row, (direction < 0) ? "\\" : "/",
                      TextColor.ANSI.WHITE_BRIGHT, BG);
        Utils.pause(50);
        if (wipeNow)  // deletes the trail as the firework ascends
          Utils.fill(scr, BG);
        wipeNow = !wipeNow;
      }

      explode(scr, numRows-row, xStart+(diff * direction));

      Utils.pause(100);
      Utils.fill(scr, BG);
    }

    Utils.close(scr);
  }  // end of main()



  private static void explode(Screen scr, int row, int col)
  // explode a firework in stages at (col, row)
  {
    Utils.fill(scr, BG);
    TextColor.ANSI cl = Utils.randomColor(BG);

    Utils.putString(scr, col, row, "-", cl, BG);
    Utils.pause(100);

    SoundUtils.bang();

    Utils.putString(scr, col-1, row-1, "-", cl, BG);
    Utils.putString(scr, col-1, row+0, "-+-", cl, BG);
    Utils.putString(scr, col-1, row+1, "-", cl, BG);
    Utils.pause(100);

    Utils.putString(scr, col-2, row-2, " --- ", cl, BG);
    Utils.putString(scr, col-2, row-1, "-+++-", cl, BG);
    Utils.putString(scr, col-2, row+0, "-+#+-", cl, BG);
    Utils.putString(scr, col-2, row+1, "-+++-", cl, BG);
    Utils.putString(scr, col-2, row+2, " --- ", cl, BG);
    Utils.pause(100);

    Utils.putString(scr, col-2, row-2, " +++ ", cl, BG);
    Utils.putString(scr, col-2, row-1, "++#++", cl, BG);
    Utils.putString(scr, col-2, row+0, "+# #+", cl, BG);
    Utils.putString(scr, col-2, row+1, "++#++", cl, BG);
    Utils.putString(scr, col-2, row+2, " +++ ", cl, BG);
    Utils.pause(100);

    Utils.putString(scr, col-2, row-2, "  #  ", cl, BG);
    Utils.putString(scr, col-2, row-1, "## ##", cl, BG);
    Utils.putString(scr, col-2, row+0, "#   #", cl, BG);
    Utils.putString(scr, col-2, row+1, "## ##", cl, BG);
    Utils.putString(scr, col-2, row+2, "  #  ", cl, BG);
    Utils.pause(100);

    Utils.putString(scr, col-2, row-2, " # # ", cl, BG);
    Utils.putString(scr, col-2, row-1, "#   #", cl, BG);
    Utils.putString(scr, col-2, row+0, "   ", cl, BG);
    Utils.putString(scr, col-2, row+1, "#   #", cl, BG);
    Utils.putString(scr, col-2, row+2, " # # ", cl, BG);
    Utils.pause(100);
  }  // xEnd of explode()



}  // xEnd of Fireworks class
