% Copyright 2026 Open-Guji (https://github.com/open-guji)
%
% Licensed under the Apache License, Version 2.0 (the "License");
% you may not use this file except in compliance with the License.
% You may obtain a copy of the License at
%
%     http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS,
% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
% See the License for the specific language governing permissions and
% limitations under the License.

% luatex-cn-guji-yinzhang.sty
% YinZhang (印章/Seal Stamp) overlay functionality for ancient Chinese books
%
\RequirePackage{expl3}
\ProvidesExplPackage {guji/luatex-cn-guji-yinzhang} {2026/08/07} {0.4.1} {Seal stamp overlay for Chinese books}

\RequirePackage{tikz}
\RequirePackage{graphicx}

% ============================================================================
% YinZhang (印章) Command - Add seal/stamp overlay on specified page
% ============================================================================

% Local variables for YinZhang key parsing
\int_new:N \l_luatexcn_yinzhang_page_int
\tl_new:N \l_luatexcn_yinzhang_opacity_tl
\tl_new:N \l_luatexcn_yinzhang_xshift_tl
\tl_new:N \l_luatexcn_yinzhang_yshift_tl
\tl_new:N \l_luatexcn_yinzhang_width_tl
\tl_new:N \l_luatexcn_yinzhang_color_tl
% Temporary tl for computed target page
\tl_new:N \l__luatexcn_yinzhang_target_page_tl

\keys_define:nn { luatexcn / yinzhang }
  {
    opacity .tl_set:N = \l_luatexcn_yinzhang_opacity_tl,
    opacity .initial:n = {1},

    xshift .tl_set:N = \l_luatexcn_yinzhang_xshift_tl,
    xshift .initial:n = {0cm},

    yshift .tl_set:N = \l_luatexcn_yinzhang_yshift_tl,
    yshift .initial:n = {0cm},

    width .tl_set:N = \l_luatexcn_yinzhang_width_tl,
    width .initial:n = {10cm},

    page .int_set:N = \l_luatexcn_yinzhang_page_int,
    page .initial:n = {1},

    color .tl_set:N = \l_luatexcn_yinzhang_color_tl,
    color .initial:n = {},
    % Forward unknown keys: try settings first, then style
    unknown .code:n =
      {
        \exp_args:Nnx \keys_if_exist:nnTF { luatexcn / settings } { \l_keys_key_str }
          { \keys_set:nx { luatexcn / settings } { \l_keys_key_str = { \exp_not:n {#1} } } }
          {
            \exp_args:Nnx \keys_if_exist:nnTF { luatexcn / style } { \l_keys_key_str }
              { \keys_set:nx { luatexcn / style } { \l_keys_key_str = { \exp_not:n {#1} } } }
              { }
          }
      },
  }

\NewDocumentCommand{\yinzhangSetup}{ m }
  {
    \keys_set:nn { luatexcn / yinzhang } { #1 }
  }

\NewDocumentCommand{\YinZhang}{ O{} m }
  {
    \group_begin:
    % Parse options (overrides Setup defaults within this group)
    \keys_set:nn { luatexcn / yinzhang } { #1 }

    % Compute target TeX page number
    % In split mode: map big page to TeX page (right half-page only)
    %   big_page N -> TeX page 2*N-1 (right_first) or 2*N (left_first)
    % In normal mode: target_page = user's page value directly
    \tl_set:Nx \l__luatexcn_yinzhang_target_page_tl {
      \lua_now:e {
        local~big_page~=~\int_use:N \l_luatexcn_yinzhang_page_int ;~
        if~_G.page~and~_G.page.split~and~_G.page.split.enabled~then~
          if~_G.page.split.right_first~then~
            tex.sprint(2~*~big_page~-~1)~
          else~
            tex.sprint(2~*~big_page)~
          end;~
        else~
          tex.sprint(big_page)~
        end
      }
    }

    % Add hook with all parameters expanded inline as literal values.
    % Each \印章 call captures its own snapshot, so multiple seals don't
    % overwrite each other's parameters (fix #80).
    \use:x {
      \exp_not:N \AddToHook{shipout/background}{
        \exp_not:N \int_compare:nNnT
          { \exp_not:N \value{page} } = { \l__luatexcn_yinzhang_target_page_tl }
          {
            \exp_not:N \begin{tikzpicture}[overlay]
              \exp_not:N \node[
                anchor=north~east,
                opacity=\l_luatexcn_yinzhang_opacity_tl,
                inner~sep=0pt,
                xshift=-\l_luatexcn_yinzhang_xshift_tl,
                yshift=-\l_luatexcn_yinzhang_yshift_tl
              ]~at~( \exp_not:N \paperwidth,~0)~{
                \exp_not:N \includegraphics
                  [width=\l_luatexcn_yinzhang_width_tl]
                  {#2}
              };
            \exp_not:N \end{tikzpicture}
          }
      }
    }
    \group_end:
  }

% ============================================================================
% CJK Key Aliases (中文键值别名)
% ============================================================================
\keys_define:nn { luatexcn / yinzhang }
  {
    不透明度 .tl_set:N = \l_luatexcn_yinzhang_opacity_tl,
    横移 .tl_set:N = \l_luatexcn_yinzhang_xshift_tl,
    橫移 .tl_set:N = \l_luatexcn_yinzhang_xshift_tl,
    纵移 .tl_set:N = \l_luatexcn_yinzhang_yshift_tl,
    縱移 .tl_set:N = \l_luatexcn_yinzhang_yshift_tl,
    宽度 .tl_set:N = \l_luatexcn_yinzhang_width_tl,
    寬度 .tl_set:N = \l_luatexcn_yinzhang_width_tl,
    页 .int_set:N = \l_luatexcn_yinzhang_page_int,
    頁 .int_set:N = \l_luatexcn_yinzhang_page_int,
    颜色 .tl_set:N = \l_luatexcn_yinzhang_color_tl,
    顏色 .tl_set:N = \l_luatexcn_yinzhang_color_tl,
  }

% ============================================================================
% CJK Aliases (中文别名)
% ============================================================================
% Simplified Chinese / 简体
\NewCommandCopy{\印章}{\YinZhang}
\NewCommandCopy{\印章设置}{\yinzhangSetup}
% Traditional Chinese / 繁体 (印章简繁同形)
\NewCommandCopy{\印章設置}{\yinzhangSetup}

\endinput
