%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ocgx2.sty
%
% Copyright 2015--\today, Alexander Grahn
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% The intent of this package is to be a drop-in replacement for the already
% existing CTAN package `ocgx' by Paul Gaborit.
%
% It re-implements the functionality of the ocg, ocgx and ocg-p packages
% and adds support for all known engines and backends including
% latex+dvips+ps2pdf, xelatex, latex+dvipdfm, lualatex.
%
% Adds some minor improvements, such as package options, remembering option
% settings of reopened ocgs, correct behaviour of ocg switching links that were
% themselves placed on layers, compatibility with the animate and media9
% packages.
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% 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://mirrors.ctan.org/help/Catalogue/licenses.lppl.html
% 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 A. Grahn.

\RequirePackage{xparse}
\RequirePackage{atenddvi}
\RequirePackage{ifpdf}
\RequirePackage{l3keys2e}

\AtBeginDocument{
  \@ifpackageloaded{media9}{}{\RequirePackage{media9}}
  \@ifpackagelater{media9}{2015/01/21}{}{
    \PackageError{ocgx2}{%
      Requires package `media9' v0.49 [2015/01/21] or\MessageBreak
      newer, but only v\g@mix@version@tl\space[\g@mix@date@tl] is available
    }{}%
  }
}

\ProvidesExplPackage{ocgx2}{2015/09/11}{0.8}
{ports `ocgx' functionality to dvips+ps2pdf, xelatex and dvipdfmx}

%re-implement ocg-p's `ocg' environment
\DeclareDocumentEnvironment{ocg}{O{}mmm}{
  \bool_if:NT\g_ocgxii_nestedB_bool{\tl_gput_right:Nx\@ocgbase@ocgorder{~[}}
  \bool_gset_true:N\g_ocgxii_nestedB_bool
  \bool_gset_false:N\g_ocgxii_nestedE_bool
  \group_begin:
    \ocgxii_reset_cmd_opts:  % ... to the user-set package options
    \tl_if_exist:cTF{ocgxii@#3}{ %re-open existing layer
      \tl_set:Nx\l_tempa_tl{\tl_use:c{ocgxii@#3.opts},#1}
      \keys_set:nV{ocgxii/user}\l_tempa_tl
      \int_compare:nT{\l_ocgxii_listno_tl=\c_zero}{
        \tl_gput_right:Nx\@ocgbase@ocgorder{~\tl_use:c{ocgxii@#3}}
      }
    }{
      \tl_gset:cn{ocgxii@#3.opts}{#1}
      \keys_set:nn{ocgxii/user}{#1}
      \mix_pdfobj:nnn{}{dict}{
        /Type/OCG/Name~(#2)/Usage<<
          \l_ocgxii_view_tl\l_ocgxii_print_tl\l_ocgxii_export_tl>>
      }
      \tl_gput_right:Nx\@ocgbase@ocgs{\space\g_mix_pdflastobj_tl}
      \int_compare:nT{#4==\c_zero}{
        \tl_gput_right:Nx\@ocgbase@offocgs{\space\g_mix_pdflastobj_tl}
      }
      \tl_gset:cx{ocgxii@#3}{\g_mix_pdflastobj_tl}
      \int_compare:nF{\l_ocgxii_listno_tl=\c_one}{
        \tl_gput_right:Nx\@ocgbase@ocgorder{~\g_mix_pdflastobj_tl}
      }
      \iow_now:Nx\@auxout{
        \token_to_str:N\expandafter\xdef\token_to_str:N\csname
        \space OCGpdfobj#3\endcsname{\g_mix_pdflastobj_tl}
      }
    }
    \bool_if:nT{
%      !\cs_if_exist_p:c{OCGpdfobj#3} ||  %lazy evaluation may cease to work
%      !\str_if_eq_x_p:nn{\use:c{OCGpdfobj#3}}{\tl_use:c{ocgxii@#3}}
      !\cs_if_exist:cTF{OCGpdfobj#3}{
        \str_if_eq_x_p:nn{\tl_use:c{OCGpdfobj#3}}{\tl_use:c{ocgxii@#3}}
      }{
        \c_false_bool
      }
    }{
      \cs_if_exist:NF\g_ocgxii_rerunwarned_tl{
        \tl_new:N\g_ocgxii_rerunwarned_tl
        \AtEndDocument{\msg_warning:nn{ocgx2}{rerun}}
      }
    }
    \tl_gset:cx{OCGpdfobj#3}{\tl_use:c{ocgxii@#3}}
    \seq_gput_left:Nx\g_fixocg_ocgstack_seq{\tl_use:c{ocgxii@#3}}
  \group_end:
  \mix_pdfbdc:nn{/OC}{\tl_use:c{ocgxii@#3}}
  \ignorespaces
}{
  \unskip
  \mix_pdfemc:
  \seq_gpop_left:NN\g_fixocg_ocgstack_seq\l_tempa_tl
  \bool_if:NT\g_ocgxii_nestedE_bool{\tl_gput_right:Nx\@ocgbase@ocgorder{~]}}
  \bool_gset_true:N\g_ocgxii_nestedE_bool
  \bool_gset_false:N\g_ocgxii_nestedB_bool
}
\bool_new:N\g_ocgxii_nestedB_bool % nested OCG begin
\bool_new:N\g_ocgxii_nestedE_bool % nested OCG end

%stack of PDF obj references of currently open OCGs
\seq_new:N\g_fixocg_ocgstack_seq

%macro that inserts /OC <<OCMD with currently open OCGs>> entry;
%for use within annotation dicts
\tl_set:Nn\ocgxii@insert@OC{
  \seq_if_empty:NF\g_fixocg_ocgstack_seq{
    /OC~<</Type/OCMD/OCGs~[\seq_use:Nn\g_fixocg_ocgstack_seq{~}]/P/AllOn>>
  }
}

\cs_set:Nn\ocgxii_ocglist_reset:{
  \tl_clear_new:N\l_ocgxii_u_list_tl
  \tl_clear_new:N\l_ocgxii_d_list_tl
  \tl_clear_new:N\l_ocgxii_e_list_tl
  \tl_clear_new:N\l_ocgxii_x_list_tl
}

\cs_set:Nn\ocgxii_ocglist_build:Nn{
  \tl_set:Nx\l_ocglistarg_tl{#2}\tl_trim_spaces:N\l_ocglistarg_tl
  \seq_set_split:NnV\l_ocgxii_ocglistarg_seq{~}\l_ocglistarg_tl
  \seq_map_variable:NNn\l_ocgxii_ocglistarg_seq\l_tempa_tl{
    \ocgxii_process_ocgref:NN#1\l_tempa_tl
  }
}

\cs_new:Nn\ocgxii_commalist_process:n{
  \seq_set_split:Nnn\l_tmpa_seq{,}{#1}
  \ocgxii_ocglist_build:Nn\l_ocgxii_e_list_tl{\seq_item:Nn\l_tmpa_seq{1}}
  \ocgxii_ocglist_build:Nn\l_ocgxii_x_list_tl{\seq_item:Nn\l_tmpa_seq{2}}
  \ocgxii_ocglist_build:Nn\l_ocgxii_d_list_tl{\seq_item:Nn\l_tmpa_seq{3}}
  \ocgxii_ocglist_build:Nn\l_ocgxii_u_list_tl{\seq_item:Nn\l_tmpa_seq{4}}
}

\cs_set:Nn\ocgxii_ocglist_process_idlist:nn{
  \ocgxii_ocglist_reset:
  \tl_set:Nx\l_ocgxii_opt_tl{#1}\tl_remove_all:Nn\l_ocgxii_opt_tl{~}
  \str_case_x:nnF{\l_ocgxii_opt_tl}{
    {triggerocg=onmouseup}{
      \ocgxii_ocglist_build:Nn\l_ocgxii_u_list_tl{#2}
    }
    {triggerocg=onmousedown}{
      \ocgxii_ocglist_build:Nn\l_ocgxii_d_list_tl{#2}
    }
    {triggerocg=onmouseenter}{
      \ocgxii_ocglist_build:Nn\l_ocgxii_e_list_tl{#2}
    }
    {triggerocg=onmouseexit}{
      \ocgxii_ocglist_build:Nn\l_ocgxii_x_list_tl{#2}
    }
    {triggerocg=allactions}{
      \ocgxii_commalist_process:n{#2}
    }
  }{
    \msg_error:nnx{ocgx2}{unknown~option}{\l_ocgxii_opt_tl}
  }
}

\int_new:N\g_ocgxii_widcount_int% widget counter

%re-implement commands from ocg-p.sty / ocgx.sty (all engines including ps2pdf [gs>=9.15])
\DeclareDocumentCommand\switchocg{o m +m}{
  \leavevmode
  \IfNoValueTF{#1}{
    \ocgxii_ocglist_process_idlist:nn{triggerocg=onmouseup}{#2}
    \ocgxii_pdflink:nn{
      /Subtype/Link\ocgxii@insert@OC
      /A <</S/SetOCGState/State [
        \str_if_eq:VnF\l_ocgxii_u_list_tl{}{/Toggle~\l_ocgxii_u_list_tl}]>>
      /Border [0~0~0]
    }{#3}
  }{
    \ocgxii_ocglist_process_idlist:nn{#1}{#2}
    \ocgxii_pdflink:nn{
      /Subtype/Widget/Ff~65536/FT/Btn/H/I
      /T~(ocgx2@\int_use:N\g_ocgxii_widcount_int)
      \ocgxii@insert@OC
      /AA <<
        \str_if_eq:VnF\l_ocgxii_u_list_tl{}{
          /U <</S/SetOCGState/State [/Toggle~\l_ocgxii_u_list_tl]>>
        }
        \str_if_eq:VnF\l_ocgxii_d_list_tl{}{
          /D <</S/SetOCGState/State [/Toggle~\l_ocgxii_d_list_tl]>>
        }
        \str_if_eq:VnF\l_ocgxii_e_list_tl{}{
          /E <</S/SetOCGState/State [/Toggle~\l_ocgxii_e_list_tl]>>
        }
        \str_if_eq:VnF\l_ocgxii_x_list_tl{}{
          /X <</S/SetOCGState/State [/Toggle~\l_ocgxii_x_list_tl]>>
        }
      >>
    }{\mbox{#3}} %Widget annots should not be broken across lines
    \int_gincr:N\g_ocgxii_widcount_int
  }
}

\DeclareDocumentCommand\showocg{o m +m}{
  \leavevmode
  \IfNoValueTF{#1}{
    \ocgxii_ocglist_process_idlist:nn{triggerocg=onmouseup}{#2}
    \ocgxii_pdflink:nn{
      /Subtype/Link\ocgxii@insert@OC
      /A <</S/SetOCGState/State [
        \str_if_eq:VnF\l_ocgxii_u_list_tl{}{/ON~\l_ocgxii_u_list_tl}]>>
      /Border [0~0~0]
    }{#3}
  }{
    \ocgxii_ocglist_process_idlist:nn{#1}{#2}
    \ocgxii_pdflink:nn{
      /Subtype/Widget/Ff~65536/FT/Btn/H/I
      /T~(ocgx2@\int_use:N\g_ocgxii_widcount_int)
      \ocgxii@insert@OC
      /AA <<
        \str_if_eq:VnF\l_ocgxii_u_list_tl{}{
          /U <</S/SetOCGState/State [/ON~\l_ocgxii_u_list_tl]>>
        }
        \str_if_eq:VnF\l_ocgxii_d_list_tl{}{
          /D <</S/SetOCGState/State [/ON~\l_ocgxii_d_list_tl]>>
        }
        \str_if_eq:VnF\l_ocgxii_e_list_tl{}{
          /E <</S/SetOCGState/State [/ON~\l_ocgxii_e_list_tl]>>
        }
        \str_if_eq:VnF\l_ocgxii_x_list_tl{}{
          /X <</S/SetOCGState/State [/ON~\l_ocgxii_x_list_tl]>>
        }
      >>
    }{\mbox{#3}} %Widget annots should not be broken across lines
    \int_gincr:N\g_ocgxii_widcount_int
  }
}

\DeclareDocumentCommand\hideocg{o m +m}{
  \leavevmode
  \IfNoValueTF{#1}{
    \ocgxii_ocglist_process_idlist:nn{triggerocg=onmouseup}{#2}
    \ocgxii_pdflink:nn{
      /Subtype/Link\ocgxii@insert@OC
      /A <</S/SetOCGState/State [
        \str_if_eq:VnF\l_ocgxii_u_list_tl{}{/OFF~\l_ocgxii_u_list_tl}]>>
      /Border [0~0~0]
    }{#3}
  }{
    \ocgxii_ocglist_process_idlist:nn{#1}{#2}
    \ocgxii_pdflink:nn{
      /Subtype/Widget/Ff~65536/FT/Btn/H/I
      /T~(ocgx2@\int_use:N\g_ocgxii_widcount_int)
      \ocgxii@insert@OC
      /AA <<
        \str_if_eq:VnF\l_ocgxii_u_list_tl{}{
          /U <</S/SetOCGState/State [/OFF~\l_ocgxii_u_list_tl]>>
        }
        \str_if_eq:VnF\l_ocgxii_d_list_tl{}{
          /D <</S/SetOCGState/State [/OFF~\l_ocgxii_d_list_tl]>>
        }
        \str_if_eq:VnF\l_ocgxii_e_list_tl{}{
          /E <</S/SetOCGState/State [/OFF~\l_ocgxii_e_list_tl]>>
        }
        \str_if_eq:VnF\l_ocgxii_x_list_tl{}{
          /X <</S/SetOCGState/State [/OFF~\l_ocgxii_x_list_tl]>>
        }
      >>
    }{\mbox{#3}} %Widget annots should not be broken across lines
    \int_gincr:N\g_ocgxii_widcount_int
  }
}

\DeclareDocumentCommand\actionsocg{o m m m +m}{
  \leavevmode
  \IfNoValueTF{#1}{
    \ocgxii_ocglist_process_idlist:nn{triggerocg=onmouseup}{#2}
    \tl_set_eq:NN\l_ocgxii_toswitch_u_tl\l_ocgxii_u_list_tl
    \ocgxii_ocglist_process_idlist:nn{triggerocg=onmouseup}{#3}
    \tl_set_eq:NN\l_ocgxii_toshow_u_tl\l_ocgxii_u_list_tl
    \ocgxii_ocglist_process_idlist:nn{triggerocg=onmouseup}{#4}
    \tl_set_eq:NN\l_ocgxii_tohide_u_tl\l_ocgxii_u_list_tl
    \ocgxii_pdflink:nn{
      /Subtype/Link\ocgxii@insert@OC
      /A <</S/SetOCGState
        /State [
          \str_if_eq:VnF{\l_ocgxii_toswitch_u_tl}{}{/Toggle~\l_ocgxii_toswitch_tl}~
          \str_if_eq:VnF{\l_ocgxii_toshow_u_tl}{}{/ON~\l_ocgxii_toshow_tl}~
          \str_if_eq:VnF{\l_ocgxii_tohide_u_tl}{}{/OFF~\l_ocgxii_tohide_tl}
        ]
      >>
      /Border [0~0~0]
    }{#5}
  }{
    \ocgxii_ocglist_process_idlist:nn{#1}{#2}
    \tl_set_eq:NN\l_ocgxii_toswitch_e_tl\l_ocgxii_e_list_tl
    \tl_set_eq:NN\l_ocgxii_toswitch_x_tl\l_ocgxii_x_list_tl
    \tl_set_eq:NN\l_ocgxii_toswitch_d_tl\l_ocgxii_d_list_tl
    \tl_set_eq:NN\l_ocgxii_toswitch_u_tl\l_ocgxii_u_list_tl
    \ocgxii_ocglist_process_idlist:nn{#1}{#3}
    \tl_set_eq:NN\l_ocgxii_toshow_e_tl\l_ocgxii_e_list_tl
    \tl_set_eq:NN\l_ocgxii_toshow_x_tl\l_ocgxii_x_list_tl
    \tl_set_eq:NN\l_ocgxii_toshow_d_tl\l_ocgxii_d_list_tl
    \tl_set_eq:NN\l_ocgxii_toshow_u_tl\l_ocgxii_u_list_tl
    \ocgxii_ocglist_process_idlist:nn{#1}{#4}
    \tl_set_eq:NN\l_ocgxii_tohide_e_tl\l_ocgxii_e_list_tl
    \tl_set_eq:NN\l_ocgxii_tohide_x_tl\l_ocgxii_x_list_tl
    \tl_set_eq:NN\l_ocgxii_tohide_d_tl\l_ocgxii_d_list_tl
    \tl_set_eq:NN\l_ocgxii_tohide_u_tl\l_ocgxii_u_list_tl
    \ocgxii_pdflink:nn{
      /Subtype/Widget/Ff~65536/FT/Btn/H/I
      /T~(ocgx2@\int_use:N\g_ocgxii_widcount_int)
      \ocgxii@insert@OC
      /AA <<
        \str_if_eq_x:nnF{}{
          \l_ocgxii_toswitch_u_tl\l_ocgxii_toshow_u_tl\l_ocgxii_tohide_u_tl
        }{
          /U <</S/SetOCGState/State [
            \str_if_eq:VnF\l_ocgxii_toswitch_u_tl{}{
              /Toggle~\l_ocgxii_toswitch_u_tl
            }
            \str_if_eq:VnF\l_ocgxii_toshow_u_tl{}{
              /ON~\l_ocgxii_toshow_u_tl
            }
            \str_if_eq:VnF\l_ocgxii_tohide_u_tl{}{
              /OFF~\l_ocgxii_tohide_u_tl
            }
          ]>>
        }
        \str_if_eq_x:nnF{}{
          \l_ocgxii_toswitch_d_tl\l_ocgxii_toshow_d_tl\l_ocgxii_tohide_d_tl
        }{
          /D <</S/SetOCGState/State [
            \str_if_eq:VnF\l_ocgxii_toswitch_d_tl{}{
              /Toggle~\l_ocgxii_toswitch_d_tl
            }
            \str_if_eq:VnF\l_ocgxii_toshow_d_tl{}{
              /ON~\l_ocgxii_toshow_d_tl
            }
            \str_if_eq:VnF\l_ocgxii_tohide_d_tl{}{
              /OFF~\l_ocgxii_tohide_d_tl
            }
          ]>>
        }
        \str_if_eq_x:nnF{}{
          \l_ocgxii_toswitch_e_tl\l_ocgxii_toshow_e_tl\l_ocgxii_tohide_e_tl
        }{
          /E <</S/SetOCGState/State [
            \str_if_eq:VnF\l_ocgxii_toswitch_e_tl{}{
              /Toggle~\l_ocgxii_toswitch_e_tl
            }
            \str_if_eq:VnF\l_ocgxii_toshow_e_tl{}{
              /ON~\l_ocgxii_toshow_e_tl
            }
            \str_if_eq:VnF\l_ocgxii_tohide_e_tl{}{
              /OFF~\l_ocgxii_tohide_e_tl
            }
          ]>>
        }
        \str_if_eq_x:nnF{}{
          \l_ocgxii_toswitch_x_tl\l_ocgxii_toshow_x_tl\l_ocgxii_tohide_x_tl
        }{
          /X <</S/SetOCGState/State [
            \str_if_eq:VnF\l_ocgxii_toswitch_x_tl{}{
              /Toggle~\l_ocgxii_toswitch_x_tl
            }
            \str_if_eq:VnF\l_ocgxii_toshow_x_tl{}{
              /ON~\l_ocgxii_toshow_x_tl
            }
            \str_if_eq:VnF\l_ocgxii_tohide_x_tl{}{
              /OFF~\l_ocgxii_tohide_x_tl
            }
          ]>>
        }
      >>
    }{\mbox{#5}} %Widget annots should not be broken across lines
    \int_gincr:N\g_ocgxii_widcount_int
  }
}

% mimic commands from ocg-p
\let\toggleocgs\switchocg
\let\showocgs\showocg
\let\hideocgs\hideocg
\let\setocgs\actionsocg

\cs_new:Nn\ocgxii_process_ocgref:NN{
  \str_if_eq_x:nnF{#2}{}{
    \tl_if_exist:cTF{OCGpdfobj#2}{\tl_put_right:Nx#1{~\tl_use:c{OCGpdfobj#2}}}{
      \msg_warning:nnx{ocgx2}{undefined~OCG}{#2}
      \cs_if_exist:NF\g_ocgxii_refundefwarned_tl{
        \tl_new:N\g_ocgxii_refundefwarned_tl
        \AtEndDocument{\msg_warning:nn{ocgx2}{undefined~OCGs}}
      }
    }
  }
}

%package opts
\keys_define:nn{ocgxii}{
  viewocg .choice:,
  viewocg / always .code:n={
    \tl_gset:Nn\g_ocgxii_view_tl{/View<</ViewState/ON>>}},
  viewocg / never .code:n={
    \tl_gset:Nn\g_ocgxii_view_tl{/View<</ViewState/OFF>>}},
  viewocg / ifvisible .code:n={\tl_gclear_new:N\g_ocgxii_view_tl},
  viewocg .default:n={ifvisible},

  printocg .choice:,
  printocg / always .code:n={
    \tl_gset:Nn\g_ocgxii_print_tl{/Print<</PrintState/ON>>}},
  printocg / never .code:n={
    \tl_gset:Nn\g_ocgxii_print_tl{/Print<</PrintState/OFF>>}},
  printocg / ifvisible .code:n={\tl_gclear_new:N\g_ocgxii_print_tl},
  printocg .default:n={ifvisible},

  exportocg .choice:,
  exportocg / always .code:n={
    \tl_gset:Nn\g_ocgxii_export_tl{/Export<</ExportState/ON>>}},
  exportocg / never .code:n={
    \tl_gset:Nn\g_ocgxii_export_tl{/Export<</ExportState/OFF>>}},
  exportocg / ifvisible .code:n={\tl_gclear_new:N\g_ocgxii_export_tl},
  exportocg .default:n={ifvisible},

  listintoolbar .choices:nn = {always,never,iffirstuse}{
    \tl_gset:Nx\g_ocgxii_listno_tl{\int_eval:n{\l_keys_choice_int-\c_one}}
  },
  listintoolbar .default:n={iffirstuse},

  tikz .bool_set:N = \l_ocgxii_tikz_bool,
  tikz .default:n = true
}

%package options preset
\keys_set:nn{ocgxii}{viewocg,printocg,exportocg,listintoolbar,tikz=false}
\ProcessKeysOptions{ocgxii} %process package options

%command opts
\keys_define:nn{ocgxii/user}{
  viewocg .choice:,
  viewocg / always .code:n={
    \tl_set:Nn\l_ocgxii_view_tl{/View<</ViewState/ON>>}},
  viewocg / never .code:n={
    \tl_set:Nn\l_ocgxii_view_tl{/View<</ViewState/OFF>>}},
  viewocg / ifvisible .code:n={
    \tl_clear:N\l_ocgxii_view_tl},
  viewocg .default:n={ifvisible},

  printocg .choice:,
  printocg / always .code:n={
    \tl_set:Nn\l_ocgxii_print_tl{/Print<</PrintState/ON>>}},
  printocg / never .code:n={
    \tl_set:Nn\l_ocgxii_print_tl{/Print<</PrintState/OFF>>}},
  printocg / ifvisible .code:n={
    \tl_clear:N\l_ocgxii_print_tl},
  printocg .default:n={ifvisible},

  exportocg .choice:,
  exportocg / always .code:n={
    \tl_set:Nn\l_ocgxii_export_tl{/Export<</ExportState/ON>>}},
  exportocg / never .code:n={
    \tl_set:Nn\l_ocgxii_export_tl{/Export<</ExportState/OFF>>}},
  exportocg / ifvisible .code:n={\tl_clear:N\l_ocgxii_export_tl},
  exportocg .default:n={ifvisible},

  listintoolbar .choices:nn = {always,never,iffirstuse}{
    \tl_set:Nx\l_ocgxii_listno_tl{\int_eval:n{\l_keys_choice_int-\c_one}}
  },
  listintoolbar .default:n={iffirstuse}
}

\cs_new:Nn\ocgxii_reset_cmd_opts:{
  \tl_set_eq:NN\l_ocgxii_view_tl\g_ocgxii_view_tl
  \tl_set_eq:NN\l_ocgxii_print_tl\g_ocgxii_print_tl
  \tl_set_eq:NN\l_ocgxii_export_tl\g_ocgxii_export_tl
  \tl_set_eq:NN\l_ocgxii_listno_tl\g_ocgxii_listno_tl
}

\group_begin:
\char_set_catcode_active:N\+\let+\space
\tl_gset:Nx\g_ocgxii_gsoldwarning_tl{
  {product~(Ghostscript)~search~{pop~pop~pop~true}{pop~false}ifelse~
   revision~915~lt~and~{
  (\token_to_str:N\n
  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\token_to_str:N\n
  @@++++++++++++Warning:+Ghostscript+too+old!++++++++++++++@@\token_to_str:N\n
  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\token_to_str:N\n
  @@+++++++++++++++++++++++++++++++++++++++++++++++++++++++@@\token_to_str:N\n
  @@+Package+`ocgx2'+requires+Ghostscript+version+>=+9.15.+@@\token_to_str:N\n
  @@+Otherwise,+PDF+layers+will+not+work.++++++++++++++++++@@\token_to_str:N\n
  @@+++++++++++++++++++++++++++++++++++++++++++++++++++++++@@\token_to_str:N\n
  @@+Get+current+version+from++++++++++++++++++++++++++++++@@\token_to_str:N\n
  @@+http://www.ghostscript.com/download+++++++++++++++++++@@\token_to_str:N\n
  @@+++++++++++++++++++++++++++++++++++++++++++++++++++++++@@\token_to_str:N\n
  @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\token_to_str:N\n)
  print}~if}~?pdfmark
}
\group_end:

\AtBeginDocument{
  \ifpdf\else
    \bool_if:NF\g_mix_dvipdfmx_bool{
      \AtEndDvi{\special{ps::[nobreak]\g_ocgxii_gsoldwarning_tl}}
    }
  \fi
}

\msg_set:nnn{ocgx2}{rerun}{Rerun~to~get~OCG~references~right!}
\msg_set:nnn{ocgx2}{undefined~OCG}{
  Line~\msg_line_number: :~OCG~`#1'~is~not~defined.
}
\msg_set:nnn{ocgx2}{undefined~OCGs}{There~were~undefined~OCGs!}
\msg_set:nnn{ocgx2}{unknown~option}{
  Line~\msg_line_number: :~unknown~option~`#1'.
}

% dvipdfmx and xelatex workaround for ocg buttons within `tikzpicture' context
\cs_set:Nn\ocgxii_pdflink:nn{
  \bool_if:nTF{
    \g_mix_dvipdfmx_bool && \cs_if_exist_p:N\pgfpictureid
  }{
    \hbox_set:Nn\l_tmpa_box{#2}
    \mix_pdfannot:nnnn{
      \dim_use:N\box_wd:N\l_tmpa_box}{
      \dim_use:N\box_ht:N\l_tmpa_box}{
      \dim_use:N\box_dp:N\l_tmpa_box
    }{#1}
    \box_use_clear:N\l_tmpa_box
  }{
    \mix_pdflink:nn{#1}{#2}
  }
}

% tikz related code follows (enabled with package option `tikz')

\bool_if:NF\l_ocgxii_tikz_bool{\endinput}
\ExplSyntaxOff
\RequirePackage{tikz}
\usetikzlibrary{calc}

% Copyright notice: The code that follows until the end of the file was
% copied from Paul Gaborit's `tikzlibraryocgx.code.tex' without modification
\tikzset{
  ocg/.style={ocg/.cd,#1,/tikz/.cd},
  ocg={
    % parameters
    name/.store in=\ocgx@name,
    visibity/.store in=\ocgx@visibility,
    status/.is choice,
    status/visible/.style={visibity=1},
    status/invisible/.style={visibity=0},
    % default values
    name=,
    status=visible,
    % ref
    ref/.style={
      /tikz/execute at begin scope={\ocg{\ocgx@name}{#1}{\ocgx@visibility}},
      /tikz/execute at end scope={\endocg},
    },
  },
  switch ocg/.style={
    postaction={
      path picture={
        \path let
        \p1 = (path picture bounding box.south west),
        \p2 = (path picture bounding box.north east),
        \p3 = (\x2-\x1,\y2-\y1)
        in
        (path picture bounding box.center)
        node[inner sep=0pt,anchor=center,outer sep=0pt]
        {\switchocg{#1}{\phantom{\rule{\x3}{\y3}}}};
      }
    },
  },
  switch ocg with mark on/.style 2 args={
    postaction={
      path picture={
        \begin{ocg}{#1}{#1}{1}
          \draw
          (path picture bounding box.south west)
          --
          (path picture bounding box.north east)
          (path picture bounding box.south east)
          --
          (path picture bounding box.north west)
          ;
        \end{ocg}
      },
      switch ocg={#1 #2},
    }
  },
  switch ocg with mark off/.style 2 args={
    postaction={
      path picture={
        \begin{ocg}{#1}{#1}{0}
          \draw
          (path picture bounding box.south west)
          --
          (path picture bounding box.north east)
          (path picture bounding box.south east)
          --
          (path picture bounding box.north west)
          ;
        \end{ocg}
      },
      switch ocg={#1 #2},
    }
  },
  show ocg/.style={
    postaction={
      path picture={
        \path let
        \p1 = (path picture bounding box.south west),
        \p2 = (path picture bounding box.north east),
        \p3 = (\x2-\x1,\y2-\y1)
        in
        (path picture bounding box.center)
        node[inner sep=0pt,anchor=center]
        {\showocg{#1}{\phantom{\rule{\x3}{\y3}}}};
      },
    },
  },
  hide ocg/.style={
    postaction={
      path picture={
        \path let
        \p1 = (path picture bounding box.south west),
        \p2 = (path picture bounding box.north east),
        \p3 = (\x2-\x1,\y2-\y1)
        in
        (path picture bounding box.center)
        node[inner sep=0pt,anchor=center]
        {\hideocg{#1}{\phantom{\rule{\x3}{\y3}}}};
      },
    },
  },
  actions ocg/.style n args={3}{
    postaction={
      path picture={
        \path let
        \p1 = (path picture bounding box.south west),
        \p2 = (path picture bounding box.north east),
        \p3 = (\x2-\x1,\y2-\y1)
        in
        (path picture bounding box.center)
        node[inner sep=0pt,anchor=center]
        {\actionsocg{#1}{#2}{#3}{\phantom{\rule{\x3}{\y3}}}};
      },
    },
  },
}
