package dev.cf.recipe;

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

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

/**
 * The same screen under Material 3, Fluent and iOS — with no per-skin code anywhere.
 */
public class R03Skins extends Recipe
{
   public String title()
   {
      return "Switching skins";
   }

   public String note()
   {
      return "Shape, radius, padding and typeface all come from the skin. Nothing below knows which"
         + " one is in force.";
   }

   public void build(Component body) throws Exception
   {
      Component linha = new Component();
      linha.setLayout(new HorizontalLayout(Position.START, Position.CENTER));
      // One per call: the add with several weights belongs to GridLayout (see R01Layouts).
      linha.add(LAY_AUTO, outgap(botao("Material", new MaterialSkin()), 0, 0, .5f, 0));
      linha.add(LAY_AUTO, outgap(botao("Fluent", new FluentSkin()), 0, 0, .5f, 0));
      linha.add(LAY_AUTO, botao("iOS", new IOSSkin()));
      body.add(LAY_AUTO, outgap(linha, 0, 0, 0, 1f));

      // Pieces whose shape comes entirely from the skin — that is where the switch shows.
      body.add(LAY_AUTO, outgap(new TextField().caption("A field"), 0, 0, 0, .6f));
      body.add(LAY_AUTO, outgap(new Button("A button"), 0, 0, 0, .6f));
      body.add(LAY_AUTO, outgap(new Switch("A switch"), 0, 0, 0, .6f));
      Card cartao = new Card();
      cartao.add(LAY_AUTO, label("A card", 1.2f, true, Styles.textColor, Position.START));
      body.add(LAY_AUTO, cartao);
   }

   /**
    * {@code apply(skin, onApplied)}, never {@code apply(skin)}.
    *
    * <p>On the web the font atlas of a skin the app did not start with is downloaded on demand, and
    * only the callback form waits for it. On native builds the callback runs before the method
    * returns, so this one line is right on every platform.</p>
    */
   private Button botao(String rotulo, Skin skin)
   {
      Button b = new Button(rotulo);
      b.onAction(c -> Skin.apply(skin, this::recriar));
      return b;
   }

   /** Switching skins is the app's decision, so the rebuild is here — never inside the rebuild itself. */
   private void recriar()
   {
      try
      {
         removeAll();
         onAdd(false);
         setValidLayout(false);
         Screen.repaint();
      }
      catch (Exception e)
      {
         dev.crossfly.util.Debug.handle(e);
      }
   }
}
