\ProvidesExplPackage {tagpdf-mc-code-generic} {2019/07/02} {0.61}
 {part of tagpdf - code related to marking chunks - generic mode}

% for the label system
% tagmcid is the id which should be also in the pdf
% it will be (hopefully) reset by page

\int_new:N \g__uftag_MCID_tmp_bypage_int
\zref@newprop {tagmcid}   [0] { \int_use:N \g__uftag_MCID_tmp_bypage_int }
\zref@addprop {uftagzrl}  {tagmcid}

% will hold the current maximum on a page
% it will contain key-value of type "abspagenum=max mcid on this page"
\__uftag_prop_new:N \g__uftag_MCID_byabspage_prop

%to test nesting mc:
\bool_new:N \g__uftag_in_mc_bool

\prg_new_conditional:Nnn \__uftag_mc_if_in: {p,T,F,TF}
 {
  \bool_if:NTF \g__uftag_in_mc_bool
   { \prg_return_true:  }
   { \prg_return_false: }
 }

\prg_new_eq_conditional:NNn \uftag_mc_if_in: \__uftag_mc_if_in: {p,T,F,TF}


% this are the low level mc command.
% they insert literals and so a are specific to generic mode
% checking if the type is defined will done somewhere else
% #1 is the type/tag
% change 04.08.2018: I don't try to escape the name, but assume that it is valid.
% Checks/conversions should perhaps be done on a higher level
\cs_new:Nn \__uftag_mc_bmc:n
 {
  \__uftag_pdfliteral_page:n
   {
    /#1\c_space_tl BMC
   }
 }

\cs_new:Nn \__uftag_mc_emc:
 {
  \__uftag_pdfliteral_page:n
   {
    EMC
   }
 }

% #1 tag, #2 properties
% change 04.08.2018: I don't escape the name. Also the dictionary content
% must imho be done at a higher level
\cs_new:Nn \__uftag_mc_bdc:nn
 {
  \__uftag_pdfliteral_page:n
   {
    /#1\c_space_tl<<#2>>~BDC
   }
 }


% bdc with /MCID + more properties
% we need a ref-label system to ensure that the cnt restarts at 0 on a new page

\tl_new:N \l__uftag_mc_ref_abspage_tl %will store the abspage value of label
\tl_new:N \l__uftag_mc_tmp_tl

\cs_new:Nn \__uftag_mc_bdc_mcid:nn
 {
  \int_gincr:N \c@g__uftag_MCID_abs_int
  \tl_set:Nx \l__uftag_mc_ref_abspage_tl
   {
    \zref@extractdefault %3 args
    {
     mcid-\int_use:N \c@g__uftag_MCID_abs_int
    }
    {tagabspage}
    {-1}
   }
  \prop_get:NoNTF
   \g__uftag_MCID_byabspage_prop
   {
    \l__uftag_mc_ref_abspage_tl
   }
   \l__uftag_mc_tmp_tl
   {
    %key already present, use value for MCID and add 1 for the next
    \int_gset:Nn \g__uftag_MCID_tmp_bypage_int { \l__uftag_mc_tmp_tl }
    \__uftag_prop_gput:Nxx
     \g__uftag_MCID_byabspage_prop
     { \l__uftag_mc_ref_abspage_tl }
     { \int_eval:n {\l__uftag_mc_tmp_tl +1} }
   }
   {
    %key not present, set MCID to 0 and insert 1
    \int_gzero:N \g__uftag_MCID_tmp_bypage_int
    \__uftag_prop_gput:Nxx
     \g__uftag_MCID_byabspage_prop
     { \l__uftag_mc_ref_abspage_tl }
     {1}
   }
  \zref@labelbylist
   {
    mcid-\int_use:N \c@g__uftag_MCID_abs_int
   }
   {uftagzrl}
  \__uftag_mc_bdc:nn
   {#1}
   { /MCID~\int_eval:n { \g__uftag_MCID_tmp_bypage_int }~#2 }
 }

% only /MCID
\cs_new:Nn \__uftag_mc_bdc_mcid:n
 {
  \__uftag_mc_bdc_mcid:nn {#1} {}
 }

%artifact without type
\cs_new:Nn  \__uftag_mc_bmc_artifact:
 {
  \__uftag_mc_bmc:n {Artifact}
 }

%artifact with a type:
\cs_new:Nn \__uftag_mc_bmc_artifact:n
 {
  \__uftag_mc_bdc:nn {Artifact}{/Type\c_space_tl/#1}
 }

% perhaps later: more properties for artifacts


% keyval definitions for the user commands:

\tl_new:N \l__uftag_mc_key_tag_tl
\tl_new:N \g__uftag_mc_key_tag_tl %for "outside" queries
\tl_new:N \l__uftag_mc_key_properties_tl
%Attention! definitions are different in luamode.
% tag and raw are expanded as \directlua in lua does it too.
\keys_define:nn { uftag / mc }
 {
  tag .code:n = % the name (H,P,Span etc
   {
    %%????????? \pdfescapename??
    \tl_set:Nx  \l__uftag_mc_key_tag_tl { #1 }
    \tl_gset:Nx  \g__uftag_mc_key_tag_tl { #1 }
   },
  raw  .code:n =
   {
    \tl_put_right:Nx \l__uftag_mc_key_properties_tl { #1 }
   }
    ,
  alttext .code:n      = % Alt property
   {
    \str_set_convert:Nnon
     \l__uftag_tmpa_str
     { #1 }
     { \g__uftag_inputencoding_tl }
     { utf16/hex }
    \tl_put_right:Nn \l__uftag_mc_key_properties_tl { /Alt~< }
    \tl_put_right:No \l__uftag_mc_key_properties_tl { \l__uftag_tmpa_str>~ }
   },
   alttext-o .code:n      = % Alt property
   {
    \str_set_convert:Noon
     \l__uftag_tmpa_str
     { #1 }
     { \g__uftag_inputencoding_tl }
     { utf16/hex }
    \tl_put_right:Nn \l__uftag_mc_key_properties_tl { /Alt~< }
    \tl_put_right:No \l__uftag_mc_key_properties_tl { \l__uftag_tmpa_str>~ }
   },
   actualtext .code:n      = % ActualText property
   {
    \str_set_convert:Nnon
     \l__uftag_tmpa_str
     { #1 }
     { \g__uftag_inputencoding_tl }
     { utf16/hex }
    \tl_put_right:Nn \l__uftag_mc_key_properties_tl { /ActualText~< }
    \tl_put_right:No \l__uftag_mc_key_properties_tl { \l__uftag_tmpa_str>~ }
   },
   actualtext-o .code:n      = % ActualText property
   {
    \str_set_convert:Noon
     \l__uftag_tmpa_str
     { #1 }
     { \g__uftag_inputencoding_tl }
     { utf16/hex }
    \tl_put_right:Nn \l__uftag_mc_key_properties_tl { /ActualText~< }
    \tl_put_right:No \l__uftag_mc_key_properties_tl { \l__uftag_tmpa_str>~ }
   },
  label .tl_set:N        = \l__uftag_mc_key_label_tl,
  artifact .code:n       = { \exp_args:Nnx \keys_set:nn { uftag / mc } { artifact-bool, artifact-type=#1 } },
  artifact .default:n    = {notype}
 }

\cs_new:Nn \__uftag_mc_handle_artifact:N %#1 contains the artifact type
 {
  \tl_if_empty:NTF #1
   { \__uftag_mc_bmc_artifact: }
   { \exp_args:No\__uftag_mc_bmc_artifact:n {#1} }
 }

\cs_new:Nn \__uftag_mc_handle_mcid:nn %#1 tag, #2 properties
 {
  \__uftag_mc_bdc_mcid:nn {#1} {#2}
 }


% puts the absolute number of an mcid in the current structure
\cs_new:Nn \__uftag_mc_handle_stash:n %1 mcidnum
 {
  \__uftag_check_mc_used:n {#1}
  \__uftag_struct_kid_mc_gput_right:nn
   { \g__uftag_struct_stack_current_tl }
   {#1}
  \prop_gput:Nxx \g__uftag_mc_parenttree_prop
   {#1}
   { \g__uftag_struct_stack_current_tl }
 }

\cs_new_protected:Nn \uftag_mc_begin:n
 {
  \group_begin:
   \__uftag_check_mc_if_nested:
   \bool_gset_true:N \g__uftag_in_mc_bool
   \keys_set:nn { uftag / mc } {#1}
   \bool_if:NTF \l__uftag_mc_artifact_bool
    { %handle artifact
     \__uftag_mc_handle_artifact:N \l__uftag_mc_artifact_type_tl
    }
    { %handle mcid type
     \__uftag_check_mc_tag:N  \l__uftag_mc_key_tag_tl
     \__uftag_mc_handle_mcid:nn { \l__uftag_mc_key_tag_tl }{\l__uftag_mc_key_properties_tl}
     \tl_if_empty:NF {\l__uftag_mc_key_label_tl}
      {
       \__uftag_mc_handle_mc_label:n { \l__uftag_mc_key_label_tl }
      }
     \bool_if:NF \l__uftag_mc_key_stash_bool
     {
      \__uftag_mc_handle_stash:n { \int_use:N \c@g__uftag_MCID_abs_int }
     }
    }
  \group_end:
 }

\cs_new_protected:Nn \uftag_mc_end:
 {
  \__uftag_check_mc_if_open:
  \bool_gset_false:N \g__uftag_in_mc_bool
  \tl_gset:Nn  \g__uftag_mc_key_tag_tl { }
  \__uftag_mc_emc:
 }

\cs_new_protected:Nn \uftag_mc_use:n %#1: label name
 {
  \tl_set:Nx  \l_tmpa_tl { \zref@extractdefault{tagpdf-#1}{tagmcabs}{} }
  \tl_if_empty:NTF\l_tmpa_tl
   {
    \msg_warning:nnn {uftag} {mc-label-unknown} {#1}
   }
   {
    \prop_gput:Nxx
     \g__uftag_mc_parenttree_prop
     {
      \zref@extractdefault {tagpdf-#1} {tagmcabs} {}
     }
     {
      \g__uftag_struct_stack_current_tl
     }
    \__uftag_struct_kid_mc_gput_right:nn
     {
      \g__uftag_struct_stack_current_tl
     }
     {
      \zref@extractdefault {tagpdf-#1} {tagmcabs} {}
     }
   }
 }

\cs_new:Nn \__uftag_get_data_mc_tag: { \g__uftag_mc_key_tag_tl }

\endinput
