% Layout-preset registry and catalog dispatch.
% This layer separates preset registration from actual loading.

\RequirePackage{expl3}
\RequirePackage{xparse}

\ExplSyntaxOn

\prop_new:N \g__layout_preset_registry_decl_prop
\prop_new:N \g__layout_preset_registry_loaded_prop

\tl_new:N \l__layout_preset_registry_id_tl
\tl_new:N \l__layout_preset_registry_targets_tl
\tl_new:N \l__layout_preset_registry_page_tl
\tl_new:N \l__layout_preset_registry_text_tl
\tl_new:N \l__layout_preset_registry_head_tl
\tl_new:N \l__layout_preset_registry_book_tl
\tl_new:N \l__layout_preset_registry_slides_tl
\tl_new:N \l__layout_preset_registry_decl_tl

\cs_new_protected:Npn \__layout_preset_registry_reset:
  {
    \tl_clear:N \l__layout_preset_registry_id_tl
    \tl_clear:N \l__layout_preset_registry_targets_tl
    \tl_clear:N \l__layout_preset_registry_page_tl
    \tl_clear:N \l__layout_preset_registry_text_tl
    \tl_clear:N \l__layout_preset_registry_head_tl
    \tl_clear:N \l__layout_preset_registry_book_tl
    \tl_clear:N \l__layout_preset_registry_slides_tl
    \tl_clear:N \l__layout_preset_registry_decl_tl
  }

\keys_define:nn { layout/preset-register }
  {
    id .tl_set:N = \l__layout_preset_registry_id_tl,
    targets .tl_set:N = \l__layout_preset_registry_targets_tl,
    page .tl_set:N = \l__layout_preset_registry_page_tl,
    text .tl_set:N = \l__layout_preset_registry_text_tl,
    head .tl_set:N = \l__layout_preset_registry_head_tl,
    book .tl_set:N = \l__layout_preset_registry_book_tl,
    slides .tl_set:N = \l__layout_preset_registry_slides_tl,
  }

\cs_new_protected:Npn \__layout_preset_registry_append:NVn #1#2
  {
    \tl_if_blank:VTF #1
      { }
      {
        \tl_put_right:Nx \l__layout_preset_registry_decl_tl
          { #2 = { \exp_not:V #1 }, }
      }
  }

\cs_new_protected:Npn \__layout_preset_registry_build_decl:
  {
    \tl_clear:N \l__layout_preset_registry_decl_tl
    \__layout_preset_registry_append:NVn \l__layout_preset_registry_targets_tl { targets }
    \__layout_preset_registry_append:NVn \l__layout_preset_registry_page_tl { page }
    \__layout_preset_registry_append:NVn \l__layout_preset_registry_text_tl { text }
    \__layout_preset_registry_append:NVn \l__layout_preset_registry_head_tl { head }
    \__layout_preset_registry_append:NVn \l__layout_preset_registry_book_tl { book }
    \__layout_preset_registry_append:NVn \l__layout_preset_registry_slides_tl { slides }
  }

\NewDocumentCommand{\LayoutPresetRegister}{m}
  {
    \__layout_preset_registry_reset:
    \keys_set:nn { layout/preset-register } {#1}
    \tl_if_blank:VTF \l__layout_preset_registry_id_tl
      {
        \PackageError{layout-registry}
          {Missing~id~field}
          {Set~id~=...~when~registering~a~layout~preset.}
      }
      { }
    \__layout_preset_registry_build_decl:
    \prop_put:NVV \g__layout_preset_registry_decl_prop
      \l__layout_preset_registry_id_tl
      \l__layout_preset_registry_decl_tl
  }

\cs_new_protected:Npn \__layout_preset_registry_use:n #1
  {
    \prop_if_in:NnTF \g__layout_preset_registry_decl_prop {#1}
      {
        \prop_if_in:NnTF \g__layout_preset_registry_loaded_prop {#1}
          { }
          {
            \prop_get:NnN \g__layout_preset_registry_decl_prop {#1} \l_tmpa_tl
            \exp_args:NV \LayoutPresetDeclare \l_tmpa_tl
            \prop_put:Nnn \g__layout_preset_registry_loaded_prop {#1} { loaded }
          }
      }
      {
        \PackageError{layout-registry}
          {Unknown~layout~preset~id~`#1`}
          {Register~the~preset~with~\string\LayoutPresetRegister\ before~using~it.}
      }
  }

\NewDocumentCommand{\UseLayout}{m}
  { \__layout_preset_registry_use:n {#1} }

\NewDocumentCommand{\UseLayouts}{m}
  { \clist_map_inline:nn {#1} { \__layout_preset_registry_use:n {##1} } }

\ExplSyntaxOff
