% ----------------------------------------------------------------------------
% the XSIM package - interface module
% 
%   eXercise Sheets IMproved
% 
% ----------------------------------------------------------------------------
% Clemens Niederberger
% Web:    https://github.com/cgnieder/xsim
% E-Mail: contact@mychemistry.eu
% ----------------------------------------------------------------------------
% Copyright 2017--2020 Clemens Niederberger
% 
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
% of this license or (at your option) any later version.
% The latest version of this license is in
%   http://www.latex-project.org/lppl.txt
% and version 1.3 or later is part of all distributions of LaTeX
% version 2005/12/01 or later.
% 
% This work has the LPPL maintenance status `maintained'.
% 
% The Current Maintainer of this work is Clemens Niederberger.
% ----------------------------------------------------------------------------
% If you have any ideas, questions, suggestions or bugs to report, please
% feel free to contact me.
% ----------------------------------------------------------------------------
\XSIMmodule{interface}{user interface}

\NewDocumentCommand \DeclareExerciseEnvironmentTemplate {m+m+m}
  { \xsim_declare_environment_template:nnn {#1} {#2} {#3} }
\@onlypreamble \DeclareExerciseEnvironmentTemplate

\NewDocumentCommand \DeclareExerciseHeadingTemplate {m+m}
  { \xsim_declare_heading_template:nn {#1} {#2} }
\@onlypreamble \DeclareExerciseHeadingTemplate

\NewDocumentCommand \DeclareExerciseTableTemplate {m+m}
  { \xsim_declare_table_template:nn {#1} {#2} }
\@onlypreamble \DeclareExerciseTableTemplate

\NewDocumentCommand \UseExerciseTemplate {mm}
  { \xsim_use_template:nn {#1} {#2} }

% ----------------------------------------------------------------------------

\NewDocumentCommand \DeclareExerciseType {mm}
  { \xsim_declare_exercise_type:nn {#1} {#2} }
\@onlypreamble \DeclareExerciseType

\NewExpandableDocumentCommand \numberofusedexercises {}
  { \int_use:N \g_xsim_max_id_int }

% ----------------------------------------------------------------------------

\ProvideDocumentCommand \IfExistSolutionTF {+m+m}
  { \xsim_if_solution_exist:ooTF {\ExerciseType} {\ExerciseID} {#1} {#2} }

\NewDocumentCommand \IfExistSolutionT {+m}
  { \IfExistSolutionTF {#1} {} }

\NewDocumentCommand \IfExistSolutionF {+m}
  { \IfExistSolutionTF {} {#1} }

\NewExpandableDocumentCommand \IfInsideSolutionTF {+m+m}
  { \xsim_if_inside_solution:TF {#1} {#2} }

\NewExpandableDocumentCommand \IfInsideSolutionT {+m}
  { \IfInsideSolutionTF {#1} {} }

\NewExpandableDocumentCommand \IfInsideSolutionF {+m}
  { \IfInsideSolutionTF {} {#1} }

\NewExpandableDocumentCommand \IfSolutionPrintTF {+m+m}
  { \xsim_if_solution_print:nTF {\ExerciseType} {#1} {#2} }

\NewExpandableDocumentCommand \IfSolutionPrintT {+m}
  { \IfSolutionPrintTF {#1} {} }

\NewExpandableDocumentCommand \IfSolutionPrintF {+m}
  { \IfSolutionPrintTF {} {#1} }

% ----------------------------------------------------------------------------

\NewDocumentCommand \DeclareExerciseProperty {t!st-m}
  {
    \IfBooleanTF {#2}
      {
        \IfBooleanTF {#3}
          {
            \xsim_declare_property:nnnn
              { \c_false_bool }
              { \c_true_bool }
              { \c_true_bool }
              {#4}
          }
          {
            \xsim_declare_property:nnnn
              { \c_false_bool }
              { \c_true_bool }
              { \c_false_bool }
              {#4}
          }
      }
      {
        \IfBooleanTF {#1}
          {
            \IfBooleanTF {#3}
              {
                \xsim_declare_property:nnnn
                  { \c_true_bool }
                  { \c_false_bool }
                  { \c_true_bool }
                  {#4}
              }
              {
                \xsim_declare_property:nnnn
                  { \c_true_bool }
                  { \c_false_bool }
                  { \c_false_bool }
                  {#4}
              }
          }
          {
            \IfBooleanTF {#3}
              {
                \xsim_declare_property:nnnn
                  { \c_false_bool }
                  { \c_false_bool }
                  { \c_true_bool }
                  {#4}
              }
              {
                \xsim_declare_property:nnnn
                  { \c_false_bool }
                  { \c_false_bool }
                  { \c_false_bool }
                  {#4}
              }
          }
      }
  }
\@onlypreamble \DeclareExerciseProperty

\NewDocumentCommand \DeclareExercisePropertyAlias {mm}
  { \xsim_make_property_alias:nn {#1} {#2} }
\@onlypreamble \DeclareExercisePropertyAlias

\NewDocumentCommand \SetExerciseProperty {m+m}
  { \xsim_set_property:xxnn {\ExerciseType} {\ExerciseID} {#1} {#2} }

\NewDocumentCommand \SetExpandedExerciseProperty {m+m}
  { \xsim_set_property:xxnx {\ExerciseType} {\ExerciseID} {#1} {#2} }

\NewDocumentCommand \ExerciseSetProperty {mmm+m}
  { \xsim_set_property:nnnn {#1} {#2} {#3} {#4} }

\NewDocumentCommand \ExerciseSetExpandedProperty {mmm+m}
  { \xsim_set_property:nnnx {#1} {#2} {#3} {#4} }

\NewExpandableDocumentCommand \IfExercisePropertyExistTF {+m+m+m}
  { \xsim_if_property_exist:nTF {#1} {#2} {#3} }

\NewExpandableDocumentCommand \IfExercisePropertyExistT {+m+m}
  { \IfExercisePropertyExistTF {#1} {#2} {} }

\NewExpandableDocumentCommand \IfExercisePropertyExistF {+m+m}
  { \IfExercisePropertyExistTF {#1} {} {#2} }

\NewDocumentCommand \IfExercisePropertySetTF {m+m+m}
  { \xsim_if_property_set:xxnTF {\ExerciseType} {\ExerciseID} {#1} {#2} {#3} }

\NewDocumentCommand \IfExercisePropertySetT {m+m}
  { \IfExercisePropertySetTF {#1} {#2} {} }

\NewDocumentCommand \IfExercisePropertySetF {m+m}
  { \IfExercisePropertySetTF {#1} {} {#2} }

\NewExpandableDocumentCommand \GetExerciseProperty {m}
  { \xsim_get_property:oon {\ExerciseType} {\ExerciseID} {#1} }

\NewExpandableDocumentCommand \GetExerciseAliasProperty {m}
  {
    \xsim_get_property:oof
      {\ExerciseType}
      {\ExerciseID}
      { \xsim_property_alias:n {#1} }
  }

\NewDocumentCommand \GetExercisePropertyTF {m+m+m}
  {
    \xsim_get_property_if_set:oonTF {\ExerciseType} {\ExerciseID} {#1}
      {#2}
      {#3}
  }

\NewDocumentCommand \GetExercisePropertyT {m+m}
  { \GetExercisePropertyTF {#1} {#2} {} }
\NewDocumentCommand \GetExercisePropertyF {m+m+m}
  { \GetExercisePropertyTF {#1} {} {#2} }

\NewExpandableDocumentCommand \GetExerciseIdForProperty {mm}
  { \xsim_get_id_for_property:nn {#1} {#2} }

\NewExpandableDocumentCommand \GetExerciseTypeForProperty {mm}
  { \xsim_get_type_for_property:nn {#1} {#2} }

\NewExpandableDocumentCommand \IfExerciseBooleanPropertyTF {+m+m+m}
  {
    \xsim_if_boolean_property:oonTF {\ExerciseType} {\ExerciseID} {#1}
      {#2}
      {#3}
  }

\NewExpandableDocumentCommand \IfExerciseBooleanPropertyT {+m+m}
  { \IfExerciseBooleanPropertyTF {#1} {#2} {} }
\NewExpandableDocumentCommand \IfExerciseBooleanPropertyF {+m+m}
  { \IfExerciseBooleanPropertyTF {#1} {} {#2} }

\NewDocumentCommand \SaveExerciseProperty {mm}
  { \xsim_save_property:xxnN {\ExerciseType} {\ExerciseID} {#1} #2 }

\NewDocumentCommand \GlobalSaveExerciseProperty {mm}
  { \xsim_gsave_property:xxnN {\ExerciseType} {\ExerciseID} {#1} #2 }

% ----------------------------------------------------------------------------

\NewDocumentCommand \DeclareExerciseParameter {st!m}
   {
     \IfBooleanTF {#1} % fixed
       {
         \IfBooleanTF {#2} % mandatory
           { \xsim_declare_parameter:nnn {true} {true} {#3} }
           { \xsim_declare_parameter:nnn {true} {false} {#3} }
       }
       {
         \IfBooleanTF {#2} % mandatory
           { \xsim_declare_parameter:nnn {false} {true} {#3} }
           { \xsim_declare_parameter:nnn {false} {false} {#3} }
       }
   }

\NewExpandableDocumentCommand \GetExerciseParameter {m}
  { \xsim_get_parameter:on {\ExerciseType} {#1} }

\NewDocumentCommand \SetExerciseParameter {mmm}
  { \xsim_set_parameter:nnn {#1} {#2} {#3} }

\NewDocumentCommand \SetExerciseParameters {mm}
  { \xsim_set_parameters:nn {#1} {#2} }

\NewExpandableDocumentCommand \GetExerciseName {}
  {
    \IfInsideSolutionTF
      { \GetExerciseParameter {solution-name} }
      { \GetExerciseParameter {exercise-name} }
  }

\NewExpandableDocumentCommand \GetExerciseHeadingF {m}
  {
    \IfInsideSolutionTF
      {
        \IfExerciseParameterSetTF {solution-heading}
          { \GetExerciseParameter {solution-heading} }
          {#1}
      }
      {
        \IfExerciseParameterSetTF {exercise-heading}
          { \GetExerciseParameter {exercise-heading} }
          {#1}
      }
  }

\NewDocumentCommand \GetExerciseBody {m}
  { \xsim_input:oon { \ExerciseType } { \ExerciseID } {#1} }
  
\NewExpandableDocumentCommand \IfExerciseParameterSetTF {+m+m+m}
  { \xsim_if_parameter_set:nnTF {\ExerciseType} {#1} {#2} {#3} }

\NewExpandableDocumentCommand \IfExerciseParameterSetT {+m+m}
  { \IfExerciseParameterSetTF {#1} {#2} {} }

\NewExpandableDocumentCommand \IfExerciseParameterSetF {+m+m}
  { \IfExerciseParameterSetTF {#1} {} {#2} }

\NewExpandableDocumentCommand \ExerciseParameterIfSetTF {+m+m+m+m}
  { \xsim_if_parameter_set:nnTF {#1} {#2} {#3} {#4} }

\NewExpandableDocumentCommand \ExerciseParameterIfSetT {+m+m+m}
  { \ExerciseParameterIfSetTF {#1} {#2} {#3} {} }

\NewExpandableDocumentCommand \ExerciseParameterIfSetF {+m+m+m}
  { \ExerciseParameterIfSetTF {#1} {#2} {} {#3} }

\NewDocumentCommand \GetExerciseParameterTF {m+m+m}
  { \xsim_get_parameter_if_set:onTF {\ExerciseType} {#1} {#2} {#3} }

\NewDocumentCommand \GetExerciseParameterT {m+m}
  { \GetExerciseParameterTF {#1} {#2} {} }

\NewDocumentCommand \GetExerciseParameterF {m+m+m}
  { \GetExerciseParameterTF {#1} {} {#2} }

% ----------------------------------------------------------------------------

\NewDocumentCommand \ExercisePropertyIfSetTF {mmm+m+m}
  { \xsim_if_property_set:nnnTF {#1} {#2} {#3} {#4} {#5} }

\NewDocumentCommand \ExercisePropertyIfSetT {mmm+m}
  { \ExercisePropertyIfSetTF {#1} {#2} {#3} {#4} {} }

\NewDocumentCommand \ExercisePropertyIfSetF {mmm+m}
  { \ExercisePropertyIfSetTF {#1} {#2} {#3} {} {#4} }

\NewExpandableDocumentCommand \ExercisePropertyGet {mmm}
  { \xsim_get_property:nnn {#1} {#2} {#3} }

\NewExpandableDocumentCommand \ExercisePropertyGetAlias {mm}
  { \xsim_get_property:nnf {#1} {#2} { \xsim_property_alias:n {#1} } }

\NewDocumentCommand \ExercisePropertySave {mmmm}
  { \xsim_save_property:nnnN {#1} {#2} {#3} #4 }

\NewDocumentCommand \ExercisePropertyGlobalSave {mmmm}
  { \xsim_gsave_property:nnnN {#1} {#2} {#3} #4 }

\NewExpandableDocumentCommand \ExerciseParameterGet {mm}
  { \xsim_get_parameter:nn {#1} {#2} }

% ----------------------------------------------------------------------------

\NewExpandableDocumentCommand \XSIMtranslate {m}
  { \xsim_translate:n {#1} }

\NewDocumentCommand \XSIMexpandcode {+m}
  { \use:x {#1} }

\NewExpandableDocumentCommand \XSIMmixedcase {m}
  { \tl_mixed_case:f {#1} }

\NewDocumentCommand \XSIMputright {mm}
  { \tl_put_right:Nn #1 {#2} }

\NewExpandableDocumentCommand \XSIMifeqTF {+m+m+m+m}
  { \tl_if_eq:ffTF {#1} {#2} {#3} {#4} }

\NewExpandableDocumentCommand \XSIMifeqT {+m+m+m}
  { \XSIMifeqTF {#1} {#2} {#3} {} }

\NewExpandableDocumentCommand \XSIMifeqF {+m+m+m}
  { \XSIMifeqTF {#1} {#2} {} {#3} }

\NewExpandableDocumentCommand \XSIMifblankTF {+m+m+m}
  { \tl_if_blank:fTF {#1} {#2} {#3} }

\NewExpandableDocumentCommand \XSIMifblankT {+m+m}
  { \XSIMifblankTF {#1} {#2} {} }

\NewExpandableDocumentCommand \XSIMifblankF {+m+m}
  { \XSIMifblankTF {#1} {} {#2} {} }

% ----------------------------------------------------------------------------

\NewDocumentCommand \DeclareExerciseGoal {m}
  { \xsim_declare_exercise_goal:n {#1} }
\@onlypreamble \DeclareExerciseGoal

\NewDocumentCommand \IfExerciseGoalTF {mm+m+m}
  {
    \xsim_if_goal_value:xxnnTF
      {\ExerciseType} {\ExerciseID} {#1}
      {#2}
      {#3} {#4}
  }

\NewDocumentCommand \IfExerciseGoalT {mm+m}
  { \IfExerciseGoalTF {#1} {#2} {#3} {} }

\NewDocumentCommand \IfExerciseGoalF {mm+m}
  { \IfExerciseGoalTF {#1} {#2} {} {#3} }

\NewDocumentCommand \IfExerciseGoalSingularTF {mmm}
  { \IfExerciseGoalTF {#1} {=1} {#2} {#3} }

\NewDocumentCommand \IfExerciseGoalSingularT {mm}
  { \IfExerciseGoalT {#1} {=1} {#2} }

\NewDocumentCommand \IfExerciseGoalSingularF {mm}
  { \IfExerciseGoalF {#1} {=1} {#2} }

\NewDocumentCommand \IfExerciseTypeGoalsSumTF {mmm+m+m}
  { \xsim_if_goals_sum:nnnTF {#1} {#2} {#3} {#4} {#5} }

\NewDocumentCommand \IfExerciseTypeGoalsSumT {mmm+m}
  { \IfExerciseTypeGoalsSumTF {#1} {#2} {#3} {#4} {} }

\NewDocumentCommand \IfExerciseTypeGoalsSumF {mmm+m}
  { \IfExerciseTypeGoalsSumTF {#1} {#2} {#3} {} {#4} }

\NewDocumentCommand \IfExerciseGoalsSumTF {mm+m+m}
  { \xsim_if_total_goals_sum:nnTF {#1} {#2} {#3} {#4} }

\NewDocumentCommand \IfExerciseGoalsSumT {mm+m}
  { \IfExerciseGoalsSumTF {#1} {#2} {#3} {} }

\NewDocumentCommand \IfExerciseGoalsSumF {mm+m}
  { \IfExerciseGoalsSumTF {#1} {#2} {} {#3} }

\NewDocumentCommand \TotalExerciseTypeGoal {mmmm}
  { \xsim_print_goal_sum:nnnn {#1} {#2} {#3} {#4} }

\NewDocumentCommand \TotalExerciseTypeGoals {mmmm}
  { \xsim_print_goals_sum:nnnn {#1} {#2} {#3} {#4} }

\NewDocumentCommand \TotalExerciseGoal {mmm}
  { \xsim_print_total_goal_sum:nnn {#1} {#2} {#3} }

\NewDocumentCommand \TotalExerciseGoals {mmm}
  { \xsim_print_total_goals_sum:nnn {#1} {#2} {#3} }

\NewDocumentCommand \AddtoExerciseTypeGoal {mmmm}
  { \xsim_addto_goal:nnnn {#1} {#2} {#3} {#4} }

\NewDocumentCommand \AddtoExerciseGoal {mm}
  { \xsim_addto_goal:xxnn {\ExerciseType} {\ExerciseID} {#1} {#2} }

\NewDocumentCommand \ExerciseGoalValuePrint {mmm}
  { \xsim_print_goal:nnn {#1} {#2} {#3} }

\NewDocumentCommand \AddtoExerciseTypeGoalPrint {mmmmmm}
  {
    \xsim_addto_goal:nnnn {#1} {#2} {#3} {#4}
    \xsim_print_goal:nnn {#4} {#5} {#6}
  }

\NewDocumentCommand \AddtoExerciseGoalPrint {mmmm}
  {
    \xsim_addto_goal:xxnn {\ExerciseType} {\ExerciseID} {#1} {#2}
    \xsim_print_goal:nnn {#2} {#3} {#4}
  }

% ----------------------------------------------------------------------------
\NewDocumentCommand \DeclareGradeDistribution {m}
  { \xsim_declare_relative_grades:n {#1} }

\NewDocumentCommand \GetGradeRequirementForGoal {mmmm}
  { \xsim_get_grade_goal:nnnn {#1} {#2} {#3} {#4} }

\NewDocumentCommand \GetGradeRequirementForGoals {mmmm}
  { \xsim_get_grade_requirement:nnnn {#1} {#2} {#3} {#4} }

\NewDocumentCommand \GetGradeRequirement {mmm}
  { \xsim_get_absolute_grade_requirement:nnn {#1} {#2} {#3} }

% ----------------------------------------------------------------------------

\NewDocumentCommand \DeclareExerciseTagging {m}
  { \xsim_new_tag_type:n {#1} }
\@onlypreamble \DeclareExerciseTagging

\NewDocumentCommand \ProvideExerciseTagging {m}
  {
    \xsim_if_tag_type_exist:nTF {#1}
      { \msg_warning:nnn {xsim} {tag-exists} {#1} }
      { \xsim_new_tag_type:n {#1} }
  }

\NewDocumentCommand \ForEachExerciseTag {m+m}
  { \xsim_foreach_exercise_tag:oonn {\ExerciseType} {\ExerciseID} {#1} {#2} }

\NewDocumentCommand \ListExerciseTags {mm}
  { \xsim_exercise_tags_use:oonn {\ExerciseType} {\ExerciseID} {#1} {#2} }

\NewDocumentCommand \UseExerciseTags {mmmm}
  {
    \xsim_exercise_tags_use:oonnnn
      {\ExerciseType}
      {\ExerciseID}
      {#1}
      {#2}
      {#3}
      {#4}
  }

\NewDocumentCommand \IfExerciseTagSetTF {m+m+m}
  { \xsim_if_tags_value:nTF {#1} {#2} {#3} }
\NewDocumentCommand \IfExerciseTagSetT {m+m}
  { \xsim_if_tags_value:nT {#1} {#2} }
\NewDocumentCommand \IfExerciseTagSetF {m+m}
  { \xsim_if_tags_value:nF {#1} {#2} }

\NewDocumentCommand \IfExerciseTopicSetTF {m+m+m}
  { \xsim_if_topic_value:nTF {#1} {#2} {#3} }
\NewDocumentCommand \IfExerciseTopicSetT {m+m}
  { \xsim_if_topic_value:nT {#1} {#2} }
\NewDocumentCommand \IfExerciseTopicSetF {m+m}
  { \xsim_if_topic_value:nF {#1} {#2} }

% ----------------------------------------------------------------------------

\NewDocumentCommand \XSIMatbegindocument {+m}
  { \xsim_at_begin_document:n {#1} }

\NewDocumentCommand \XSIMatenddocument {+m}
  { \xsim_at_end_document:n {#1} }

% ----------------------------------------------------------------------------

\NewDocumentCommand \ForEachPrintedExerciseByType {+m}
  { \xsim_foreach_exercise_type_id:nn {print} {#1} }

\NewDocumentCommand \ForEachPrintedExerciseByID {+m}
  { \xsim_foreach_exercise_id_type:nn {print} {#1} }

\NewDocumentCommand \ForEachUsedExerciseByType {+m}
  { \xsim_foreach_exercise_type_id:nn {used} {#1} }

\NewDocumentCommand \ForEachUsedExerciseByID {+m}
  { \xsim_foreach_exercise_id_type:nn {used} {#1} }

% ----------------------------------------------------------------------------

\NewDocumentCommand \DeclareExerciseTranslations {mm}
  { \xsim_declare_translations:nn {#1} {#2} }
\@onlypreamble \DeclareExerciseTranslations
  
\NewDocumentCommand \DeclareExerciseTranslation {mmm}
  { \xsim_declare_translation:nnn {#1} {#2} {#3} }
\@onlypreamble \DeclareExerciseTranslation

\NewDocumentCommand \ForEachExerciseTranslation {+m}
  { \xsim_for_all_translations_do:n {#1} }

% ----------------------------------------------------------------------------

\NewDocumentCommand \DeclareExerciseCollection {m}
  { \xsim_new_collection:n {#1} }
\@onlypreamble \DeclareExerciseCollection

\NewDocumentCommand \collectexercisestype {mm}
  { \xsim_start_collection:nn {#1} {#2} }

\NewDocumentCommand \collectexercises {m}
  { \xsim_start_collection:n {#1} }

\NewDocumentCommand \collectexercisesstop {m}
  { \xsim_stop_collection:n {#1} }

\NewDocumentCommand \printcollection {O{}m}
  { \xsim_print_collection:nn {#1} {#2} }

\NewDocumentCommand \printrandomexercises {O{}m}
  {
    \group_begin:
      \keys_set:nn {xsim/random} {#1}
      \xsim_print_random_list:VnN
        \l_xsim_random_collection_tl
        {#2}
        \l_xsim_random_exclude_list_clist
    \group_end:
  }

% ----------------------------------------------------------------------------

\NewDocumentCommand \blank {som}
  {
    \group_begin:
      \IfNoValueF {#2} { \keys_set:nn {xsim/blank} {#2} }
      \mode_if_vertical:TF
        {
          \IfBooleanTF {#1}
            { \xsim_blank:n {#3} }
            {
              \bool_if:NT \l__xsim_blank_linespread_bool
                { \linespread { \l__xsim_blank_linespread_tl } \selectfont }
              \noindent \null \xsim_blank:n {#3} \par
            }
        }
        { \xsim_blank:n {#3} }
    \group_end:
  }

\NewDocumentCommand \examspace { sm }
  {
    \IfBooleanTF {#1}
      { \xsim_examspace:nn { \c_true_bool } {#2} }
      { \xsim_examspace:nn { \c_false_bool } {#2} }
  }

% ----------------------------------------------------------------------------

\NewDocumentCommand \gradingtable {O{}}
  {
    \group_begin:
      \keys_set:nn {xsim/grading-table} {#1}
      \xsim_setup_template:nVn {table} \l_xism_grading_table_template_tl
        {
          \providecommand* \ExerciseTableCode {}
          \providecommand* \ExerciseTableType [1] {}
          \providecommand* \ExerciseType {}
          \tl_set_eq:NN \ExerciseType \l_xism_grading_table_exercise_type_tl
          \renewcommand* \ExerciseTableCode {}
          \renewcommand* \ExerciseTableType [1]
            { \XSIMifblankTF { \ExerciseType } {##1} { \ExerciseType } }
        }
      \xsim_use_template:nV {table} \l_xism_grading_table_template_tl
    \group_end:
  }

% ----------------------------------------------------------------------------

\NewDocumentCommand \XSIMprint {mO{}mm}
  { \xsim_insert:nenn {#3} { \xsim_normalize_id:n {#4} } {#2} {#1} }

\NewDocumentCommand \XSIMxprint {mO{}mm}
  { \xsim_insert:xxnn {#3} { \xsim_normalize_id:e {#4} } {#2} {#1} }

\NewDocumentCommand \printexercise {O{}mm}
  {
    \clist_map_inline:nn {#3}
      { \xsim_insert:nenn {#2} { \xsim_normalize_id:n {##1} } {#1} {exercise} }
  }

\NewDocumentCommand \xprintexercise {O{}mm}
  {
    \clist_map_inline:nn {#3}
      { \xsim_insert:xxnn {#2} { \xsim_normalize_id:e {##1} } {#1} {exercise} }
  }

\NewDocumentCommand \printsolution {O{}mm}
  {
    \clist_map_inline:nn {#3}
      { \xsim_insert:nenn {#2} { \xsim_normalize_id:n {##1} } {#1} {solution} }
  }
  
\NewDocumentCommand \xprintsolution {O{}mm}
  {
    \clist_map_inline:nn {#3}
      { \xsim_insert:xxnn {#2} { \xsim_normalize_id:e {##1} } {#1} {solution} }
  }
  
% ----------------------------------------------------------------------------
  
\NewDocumentCommand \printsolutionstype {sO{}m}
  {
    \IfBooleanTF {#1}
      { \xsim_print_type_solutions:nnn { \c_true_bool } {#2} {#3} }
      { \xsim_print_type_solutions:nnn { \c_false_bool } {#2} {#3} }
  }

\NewDocumentCommand \printsolutions {sO{}}
  {
    \IfBooleanTF {#1}
      { \xsim_print_all_solutions_per_type:nn { \c_true_bool } {#2} }
      { \xsim_print_all_solutions_per_type:nn { \c_false_bool } {#2} }
  }

\NewDocumentCommand \printallsolutions {sO{}}
  {
    \IfBooleanTF {#1}
      { \xsim_print_all_solutions_per_id:nn { \c_true_bool } {#2} }
      { \xsim_print_all_solutions_per_id:nn { \c_false_bool } {#2} }
  }

% ----------------------------------------------------------------------------

\NewDocumentCommand \printforexercises {sO{}+mO{}}
  {
    \IfBooleanTF {#1}
      {
        \xsim_foreach_exercise_type:n
          { \xsim_print_type_code:nnnnn { \c_true_bool } {#2} {#4} {##1} {#3} }
      }
      {
        \xsim_foreach_exercise_type:n
          { \xsim_print_type_code:nnnnn { \c_false_bool } {#2} {#4} {##1} {#3} }
      }
  }

% ----------------------------------------------------------------------------

\NewDocumentCommand \xsimsetup {+m}
  { \xsim_setup:n {#1} }

% ----------------------------------------------------------------------------
\NewExpandableDocumentCommand \XSIMifchapterTF {+m+m}
  { \xsim_if_chapter:TF {#1} {#2} }

\NewExpandableDocumentCommand \XSIMifchapterT {+m}
  { \xsim_if_chapter:T {#1} }

\NewExpandableDocumentCommand \XSIMifchapterF {+m}
  { \xsim_if_chapter:F {#1} }

% ----------------------------------------------------------------------------
\file_input_stop:
