% Font-family registry and catalog dispatch.
% This layer separates registration from actual loading.

\RequirePackage{expl3}
\RequirePackage{xparse}

\ExplSyntaxOn

\prop_new:N \g__font_registry_decl_prop
\prop_new:N \g__font_registry_loaded_prop

\tl_new:N \l__font_registry_id_tl
\tl_new:N \l__font_registry_decl_tl
\tl_new:N \l__font_registry_scope_tl
\tl_new:N \l__font_registry_name_tl
\tl_new:N \l__font_registry_path_tl
\tl_new:N \l__font_registry_regular_tl
\tl_new:N \l__font_registry_bold_tl
\tl_new:N \l__font_registry_italic_tl
\tl_new:N \l__font_registry_bolditalic_tl
\tl_new:N \l__font_registry_sans_tl
\tl_new:N \l__font_registry_sansbold_tl
\tl_new:N \l__font_registry_mono_tl
\tl_new:N \l__font_registry_monobold_tl
\tl_new:N \l__font_registry_script_tl
\tl_new:N \l__font_registry_scriptclass_tl
\tl_new:N \l__font_registry_inlineaxis_tl
\tl_new:N \l__font_registry_inlinedirection_tl
\tl_new:N \l__font_registry_blockprogression_tl
\tl_new:N \l__font_registry_preservespaces_tl
\tl_new:N \l__font_registry_inlinebehavior_tl
\tl_new:N \l__font_registry_layout_tl
\tl_new:N \l__font_registry_verticalstrategy_tl
\tl_new:N \l__font_registry_verticalrotation_tl
\tl_new:N \l__font_registry_verticalorigin_tl
\tl_new:N \l__font_registry_verticaltopcorrection_tl
\tl_new:N \l__font_registry_features_tl
\tl_new:N \l__font_registry_command_tl
\tl_new:N \l__font_registry_familyid_tl
\tl_new:N \l__font_registry_specialmodule_tl
\tl_new:N \l__font_registry_externalcommand_tl
\tl_new:N \l__font_registry_externalengine_tl
\tl_new:N \l__font_registry_externalrendercommand_tl
\tl_new:N \l__font_registry_externalclusterwise_tl

\cs_new_protected:Npn \__font_registry_reset:
  {
    \tl_clear:N \l__font_registry_id_tl
    \tl_clear:N \l__font_registry_decl_tl
    \tl_clear:N \l__font_registry_scope_tl
    \tl_clear:N \l__font_registry_name_tl
    \tl_clear:N \l__font_registry_path_tl
    \tl_clear:N \l__font_registry_regular_tl
    \tl_clear:N \l__font_registry_bold_tl
    \tl_clear:N \l__font_registry_italic_tl
    \tl_clear:N \l__font_registry_bolditalic_tl
    \tl_clear:N \l__font_registry_sans_tl
    \tl_clear:N \l__font_registry_sansbold_tl
    \tl_clear:N \l__font_registry_mono_tl
    \tl_clear:N \l__font_registry_monobold_tl
    \tl_clear:N \l__font_registry_script_tl
    \tl_clear:N \l__font_registry_scriptclass_tl
    \tl_clear:N \l__font_registry_inlineaxis_tl
    \tl_clear:N \l__font_registry_inlinedirection_tl
    \tl_clear:N \l__font_registry_blockprogression_tl
    \tl_clear:N \l__font_registry_preservespaces_tl
    \tl_clear:N \l__font_registry_inlinebehavior_tl
    \tl_clear:N \l__font_registry_layout_tl
    \tl_clear:N \l__font_registry_verticalstrategy_tl
    \tl_clear:N \l__font_registry_verticalrotation_tl
    \tl_clear:N \l__font_registry_verticalorigin_tl
    \tl_clear:N \l__font_registry_verticaltopcorrection_tl
    \tl_clear:N \l__font_registry_features_tl
    \tl_clear:N \l__font_registry_command_tl
    \tl_clear:N \l__font_registry_familyid_tl
    \tl_clear:N \l__font_registry_specialmodule_tl
    \tl_clear:N \l__font_registry_externalcommand_tl
    \tl_clear:N \l__font_registry_externalengine_tl
    \tl_clear:N \l__font_registry_externalrendercommand_tl
    \tl_clear:N \l__font_registry_externalclusterwise_tl
  }

\keys_define:nn { font/register }
  {
    id .tl_set:N = \l__font_registry_id_tl,
    scope .tl_set:N = \l__font_registry_scope_tl,
    name .tl_set:N = \l__font_registry_name_tl,
    path .tl_set:N = \l__font_registry_path_tl,
    regular .tl_set:N = \l__font_registry_regular_tl,
    bold .tl_set:N = \l__font_registry_bold_tl,
    italic .tl_set:N = \l__font_registry_italic_tl,
    bolditalic .tl_set:N = \l__font_registry_bolditalic_tl,
    sans .tl_set:N = \l__font_registry_sans_tl,
    sansbold .tl_set:N = \l__font_registry_sansbold_tl,
    mono .tl_set:N = \l__font_registry_mono_tl,
    monobold .tl_set:N = \l__font_registry_monobold_tl,
    script .tl_set:N = \l__font_registry_script_tl,
    scriptclass .tl_set:N = \l__font_registry_scriptclass_tl,
    inlineaxis .tl_set:N = \l__font_registry_inlineaxis_tl,
    inlinedirection .tl_set:N = \l__font_registry_inlinedirection_tl,
    blockprogression .tl_set:N = \l__font_registry_blockprogression_tl,
    preservespaces .tl_set:N = \l__font_registry_preservespaces_tl,
    inlinebehavior .tl_set:N = \l__font_registry_inlinebehavior_tl,
    layout .tl_set:N = \l__font_registry_layout_tl,
    verticalstrategy .tl_set:N = \l__font_registry_verticalstrategy_tl,
    verticalrotation .tl_set:N = \l__font_registry_verticalrotation_tl,
    verticalorigin .tl_set:N = \l__font_registry_verticalorigin_tl,
    verticaltopcorrection .tl_set:N = \l__font_registry_verticaltopcorrection_tl,
    features .tl_set:N = \l__font_registry_features_tl,
    command .tl_set:N = \l__font_registry_command_tl,
    familyid .tl_set:N = \l__font_registry_familyid_tl,
    specialmodule .tl_set:N = \l__font_registry_specialmodule_tl,
    externalcommand .tl_set:N = \l__font_registry_externalcommand_tl,
    externalengine .tl_set:N = \l__font_registry_externalengine_tl,
    externalrendercommand .tl_set:N = \l__font_registry_externalrendercommand_tl,
    externalclusterwise .tl_set:N = \l__font_registry_externalclusterwise_tl,
  }

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

\cs_new_protected:Npn \__font_registry_build_decl:
  {
    \tl_clear:N \l__font_registry_decl_tl
    \__font_registry_append:NVn \l__font_registry_scope_tl { scope }
    \__font_registry_append:NVn \l__font_registry_name_tl { name }
    \__font_registry_append:NVn \l__font_registry_path_tl { path }
    \__font_registry_append:NVn \l__font_registry_regular_tl { regular }
    \__font_registry_append:NVn \l__font_registry_bold_tl { bold }
    \__font_registry_append:NVn \l__font_registry_italic_tl { italic }
    \__font_registry_append:NVn \l__font_registry_bolditalic_tl { bolditalic }
    \__font_registry_append:NVn \l__font_registry_sans_tl { sans }
    \__font_registry_append:NVn \l__font_registry_sansbold_tl { sansbold }
    \__font_registry_append:NVn \l__font_registry_mono_tl { mono }
    \__font_registry_append:NVn \l__font_registry_monobold_tl { monobold }
    \__font_registry_append:NVn \l__font_registry_script_tl { script }
    \__font_registry_append:NVn \l__font_registry_scriptclass_tl { scriptclass }
    \__font_registry_append:NVn \l__font_registry_inlineaxis_tl { inlineaxis }
    \__font_registry_append:NVn \l__font_registry_inlinedirection_tl { inlinedirection }
    \__font_registry_append:NVn \l__font_registry_blockprogression_tl { blockprogression }
    \__font_registry_append:NVn \l__font_registry_preservespaces_tl { preservespaces }
    \__font_registry_append:NVn \l__font_registry_inlinebehavior_tl { inlinebehavior }
    \__font_registry_append:NVn \l__font_registry_layout_tl { layout }
    \__font_registry_append:NVn \l__font_registry_verticalstrategy_tl { verticalstrategy }
    \__font_registry_append:NVn \l__font_registry_verticalrotation_tl { verticalrotation }
    \__font_registry_append:NVn \l__font_registry_verticalorigin_tl { verticalorigin }
    \__font_registry_append:NVn \l__font_registry_verticaltopcorrection_tl { verticaltopcorrection }
    \__font_registry_append:NVn \l__font_registry_features_tl { features }
    \__font_registry_append:NVn \l__font_registry_command_tl { command }
    \__font_registry_append:NVn \l__font_registry_familyid_tl { familyid }
    \__font_registry_append:NVn \l__font_registry_specialmodule_tl { specialmodule }
    \__font_registry_append:NVn \l__font_registry_externalcommand_tl { externalcommand }
    \__font_registry_append:NVn \l__font_registry_externalengine_tl { externalengine }
    \__font_registry_append:NVn \l__font_registry_externalrendercommand_tl { externalrendercommand }
    \__font_registry_append:NVn \l__font_registry_externalclusterwise_tl { externalclusterwise }
  }

\NewDocumentCommand{\FontRegister}{m}
  {
    \__font_registry_reset:
    \keys_set:nn { font/register } {#1}
    \tl_if_blank:VTF \l__font_registry_id_tl
      { \PackageError{font-registry}{Missing~id~field}{Set~id~=...~when~registering~a~font.} }
      { }
    \__font_registry_build_decl:
    \prop_put:NVV \g__font_registry_decl_prop \l__font_registry_id_tl \l__font_registry_decl_tl
  }

\cs_new_protected:Npn \__font_registry_use:n #1
  {
    \prop_if_in:NnTF \g__font_registry_decl_prop {#1}
      {
        \prop_if_in:NnTF \g__font_registry_loaded_prop {#1}
          { }
          {
            \prop_get:NnN \g__font_registry_decl_prop {#1} \l_tmpa_tl
            \exp_args:NV \FontDeclare \l_tmpa_tl
            \prop_put:Nnn \g__font_registry_loaded_prop {#1} { loaded }
          }
      }
      {
        \PackageError{font-registry}{Unknown~font~id~`#1`}{Register~the~font~with~\string\FontRegister\ before~using~it.}
      }
  }

\NewDocumentCommand{\UseFont}{m}
  { \__font_registry_use:n {#1} }

\NewDocumentCommand{\UseFonts}{m}
  { \clist_map_inline:nn {#1} { \__font_registry_use:n {##1} } }

\ExplSyntaxOff
