package dev.cf.recipe;

import dev.cf.Tones;

import dev.crossfly.ui.*;
import dev.crossfly.ui.color.*;
import dev.crossfly.ui.graphics.*;
import dev.crossfly.ui.layout.*;
import dev.crossfly.ui.style.*;

import static dev.crossfly.ui.Widgets.*;

/**
 * The floating action button, and the rule that keeps it useful.
 *
 * <p>A FAB is a claim: <b>this is the thing you came here to do</b>. One per screen, and it must be
 * the same verb the screen's title implies — on a list of orders, "new order". A FAB that opens a
 * menu of six unrelated actions has stopped being a claim and become a second navigation bar, in
 * the corner, that nobody looks in.</p>
 *
 * <p>{@link ActionButtonMenu} exists for the case where the main action has two or three near
 * relatives. Past that, the answer is a screen.</p>
 */
public class R24Fab extends Recipe
{
   private Label last;

   public String title()
   {
      return "Floating action button";
   }

   public String note()
   {
      return "It floats over the content, so leave room at the bottom of the list — bottomInset is"
         + " what stops it covering the last row nobody can then scroll past.";
   }

   public void build(Component body) throws Exception
   {
      last = label("Nothing chosen yet.", 1.2f, true, Tones.accent(), Position.START);
      body.add(LAY_AUTO, outgap(last, 0, 0, 0, .8f));

      for (int i = 1; i <= 8; i++)
      {
         Card c = new Card();
         c.setLayout(new GridLayout(Position.START, Position.CENTER));
         c.getStyle()
            .outgap(Gap.ofFont(0, 0, 0, .5f));
         Component t = new Component();
         t.setLayout(new VerticalLayout(Position.START, Position.START));
         t.add(LAY_AUTO, label("Order " + (4180 + i), 1.2f, true, Styles.textColor,
            Position.START));
         t.add(LAY_AUTO, label("Placed this week", 1f, false, Styles.captionColor,
            Position.START));
         c.add(0f, 1f, Tones.tile(0xE8CC, Tones.cycle(i)), outgap(t, .6f, 0, 0, 0));
         body.add(LAY_AUTO, c);
      }

      ActionButtonMenu fab = new ActionButtonMenu(Styles.primaryColor.color(),
         Styles.backColor.color());
      // Two or three near relatives of the main action. Each says what it DOES, not what it is.
      fab.item(0xE8CC, Styles.primaryColor, "New order", () -> chose("New order"));
      fab.item(0xE7FD, secondary(), "New customer", () -> chose("New customer"));
      fab.item(0xE2C3, tertiary(), "Import a file", () -> chose("Import a file"));
      // Room for the bottom navigation, if there is one. Measured in font units like everything.
      fab.bottomInset(1f);
      fab.testTag("recipe.fab");
      // The FAB is added to the WINDOW, not to the scrolling body: it floats over the content and
      // must not scroll away with it.
      //
      // Two details, and getting either wrong empties the page. It covers the WHOLE window on
      // purpose: the widget dims what is behind it and catches the tap that closes the menu
      // anywhere outside the items, so it is only correct at full size, and since 09/09 it
      // reclaims the parent rect itself if the host hands it less. And it is added WITHOUT a
      // layout weight, so the vertical flow never reserves height for it. As a LAY_AUTO sibling of
      // the LAY_FILL content area it takes the window height for itself and the page below renders
      // EMPTY — which is exactly what happened, and what Test58 caught.
      fab.setRelativeBounds(Relative.START, Relative.START, Relative.FULL, Relative.FULL);
      addFloating(fab);
   }

   private void chose(String what)
   {
      last.setText("Chose: " + what);
      last.setValidLayout(false);
      Screen.repaint();
   }
}
