% memoir-footnote-saver.sty
% Forces ALL footnotes to use main footnote numbering and paragraph formatting
% Complete rewrite based on footnotehyper but adapted for memoir paragraph footnotes

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{memoir-footnote-saver}[2024/01/01 v3.0 Memoir paragraph footnote fix with full hyperref]

% Use etoolbox for robust patching
\RequirePackage{etoolbox}

% Debug mode with extensive logging
\newif\ifMFS@debug
\MFS@debugfalse % Disable debug for production
\def\MFS@debug#1{\ifMFS@debug\typeout{[MFS] #1}\fi}
\def\MFS@debugmark#1{\ifMFS@debug\typeout{[MFS-MARK] #1}\fi}
\def\MFS@debugtext#1{\ifMFS@debug\typeout{[MFS-TEXT] #1}\fi}
\def\MFS@debughref#1{\ifMFS@debug\typeout{[MFS-HREF] #1}\fi}

% Only works with memoir
\@ifclassloaded{memoir}{}{%
  \PackageError{memoir-footnote-saver}{This package requires the memoir class}{}%
}

% Storage for saved footnotes
\newbox\MFS@notes
\newdimen\MFS@width
\newif\ifMFS@savingnotes
\newif\ifMFS@globalmode % New flag for global save mode

% Track column width  
\let\MFS@colwidth\columnwidth

% Storage for footnote counter state
\newcount\MFS@footnote@count
\newcount\MFS@mpfootnote@count

% Track hyperref state
\newif\ifMFS@hyperref
\newif\ifMFS@hyperfootnotes

\AtBeginDocument{%
    \MFS@debug{=== MFS Setup Starting ===}%
    
    % Save original commands BEFORE any modifications
    \let\MFS@latex@footnote\footnote
    \let\MFS@latex@footnotetext\footnotetext
    \let\MFS@H@@footnotetext\@footnotetext
    \let\MFS@H@@mpfootnotetext\@mpfootnotetext
    
    % Save memoir's paragraph footnote command
    \let\MFS@memoir@@parafootnotetext\@parafootnotetext
    
    % Check for hyperref
    \@ifpackageloaded{hyperref}{%
        \MFS@hyperreftrue
        \MFS@debug{Hyperref detected}%
        \ifHy@hyperfootnotes
            \MFS@hyperfootnotestrue
            \MFS@debug{Hyperref footnotes enabled}%
            % Save hyperref's versions if they exist
            \@ifundefined{H@@footnotetext}{}{%
                \let\MFS@H@@footnotetext\H@@footnotetext
                \let\MFS@H@@mpfootnotetext\H@@mpfootnotetext
            }%
        \else
            \MFS@debug{Hyperref footnotes disabled}%
        \fi
    }{%
        \MFS@debug{No hyperref}%
    }%
    
    % CRITICAL: Enable global save mode to process ALL footnotes
    % This ensures hyperref links work for all footnotes
    \MFS@globalmodetrue
    \MFS@begin@global@mode
    
    \MFS@debug{=== MFS Setup Complete ===}%
}

% ============================================================================
% Global mode - process ALL footnotes through save/restore
% ============================================================================

\def\MFS@begin@global@mode{%
    \MFS@debug{Enabling global footnote processing mode}%
    % Replace the main footnote commands
    \let\footnote\MFS@footnote
    \let\footnotetext\MFS@footnotetext
    % Replace low-level commands
    \let\@footnotetext\MFS@hyper@fntext
    \let\@mpfootnotetext\MFS@hyper@fntext
}

% ============================================================================
% Core save/restore mechanism (based on footnotehyper)
% ============================================================================

% Main wrapper to check amsmath measuring
\def\MFS@fntext#1{%
    \ifx\ifmeasuring@\@undefined
        \expandafter\@secondoftwo
    \else
        \expandafter\@firstofone
    \fi
    {\ifmeasuring@\expandafter\@gobbletwo\fi}#1%
}

% Main processing function with hyperref
\def\MFS@hyper@fntext{\MFS@fntext\MFS@hyper@fntext@impl}
\def\MFS@nohyp@fntext{\MFS@fntext\MFS@nohyp@fntext@impl}

% Store with hyperref support - format as memoir paragraph footnote
\long\def\MFS@hyper@fntext@impl#1{%
    \MFS@debughref{Processing footnote \@thefnmark, href=\Hy@footnote@currentHref}%
    % Directly insert formatted paragraph footnote
    \insert\footinsv@r{%
        \def\baselinestretch{\m@m@footnote@spacing}%
        \reset@font\foottextfont
        \@preamfntext
        \protected@edef\@currentlabel{%
            \csname p@footnote\endcsname\@thefnmark}%
        \setbox0=\vbox{\hsize=\maxdimen
            \color@begingroup
            \noindent\@parafootfmt{%
                \ifMFS@hyperfootnotes
                    \ifHy@nesting
                        \expandafter\ltx@firstoftwo
                    \else
                        \expandafter\ltx@secondoftwo
                    \fi
                    {\expandafter\hyper@@anchor\expandafter{\Hy@footnote@currentHref}{#1}}%
                    {\Hy@raisedlink{%
                        \expandafter\hyper@@anchor\expandafter{\Hy@footnote@currentHref}{\relax}%
                    }%
                    \let\@currentHref\Hy@footnote@currentHref
                    \let\@currentlabelname\@empty
                    #1}%
                \else
                    #1%
                \fi
            }%
            \color@endgroup
        }%
        \m@mungebox
    }%
    \m@mmf@prepare
}

% Store without hyperref - format as memoir paragraph footnote
\long\def\MFS@nohyp@fntext@impl#1{%
    \MFS@debugtext{Processing footnote without hyperref}%
    \insert\footinsv@r{%
        \def\baselinestretch{\m@m@footnote@spacing}%
        \reset@font\foottextfont
        \@preamfntext
        \protected@edef\@currentlabel{%
            \csname p@footnote\endcsname\@thefnmark}%
        \setbox0=\vbox{\hsize=\maxdimen
            \color@begingroup
            \noindent\@parafootfmt{#1}%
            \color@endgroup
        }%
        \m@mungebox
    }%
    \m@mmf@prepare
}

% Main footnote command that works everywhere
\def\MFS@footnote{%
    \@ifnextchar[%
        {\MFS@footnote@opt}%
        {\MFS@footnote@noopt}%
}

\def\MFS@footnote@opt[#1]{%
    \MFS@debugmark{footnote[#1] called, savingnotes=\ifMFS@savingnotes true\else false\fi}%
    \ifMFS@savingnotes
        % In save mode: store for later
        \footnotemark[#1]%
        \MFS@store@footnote@opt[#1]%
    \else
        % Normal mode but still process through our system
        \MFS@latex@footnote[#1]%
    \fi
}

\def\MFS@footnote@noopt#1{%
    \MFS@debugmark{footnote{...} called, savingnotes=\ifMFS@savingnotes true\else false\fi}%
    \ifMFS@savingnotes
        % In save mode: store for later
        \footnotemark
        \MFS@store@footnote@noopt{#1}%
    \else
        % Normal mode but still process through our system
        \MFS@latex@footnote{#1}%
    \fi
}

% Main footnotetext command
\def\MFS@footnotetext{%
    \@ifnextchar[%
        {\MFS@footnotetext@opt}%
        {\MFS@footnotetext@noopt}%
}

\def\MFS@footnotetext@opt[#1]{%
    \MFS@debugtext{footnotetext[#1] called}%
    \ifMFS@savingnotes
        \MFS@store@footnote@opt[#1]%
    \else
        \MFS@latex@footnotetext[#1]%
    \fi
}

\def\MFS@footnotetext@noopt#1{%
    \MFS@debugtext{footnotetext{...} called}%
    \ifMFS@savingnotes
        \MFS@store@footnote@noopt{#1}%
    \else
        \MFS@latex@footnotetext{#1}%
    \fi
}

% Store footnote for later (save mode)
\def\MFS@store@footnote@opt[#1]#2{%
    \begingroup
    \csname c@\@mpfn\endcsname #1\relax
    \unrestored@protected@xdef\@thefnmark{\thempfn}%
    \endgroup
    \MFS@store@footnote@impl{#2}%
}

\def\MFS@store@footnote@noopt#1{%
    \MFS@store@footnote@impl{#1}%
}

\long\def\MFS@store@footnote@impl#1{%
    \MFS@debugtext{Storing footnote \@thefnmark for later}%
    % Build the formatted footnote exactly as memoir would
    \global\setbox\MFS@notes\vbox{%
        \unvbox\MFS@notes
        % Start a new footnote
        \setbox0=\vbox{\hsize=\maxdimen
            \color@begingroup
            \noindent\@parafootfmt{%
                \ifMFS@hyperfootnotes
                    \ifHy@nesting
                        \expandafter\ltx@firstoftwo
                    \else
                        \expandafter\ltx@secondoftwo
                    \fi
                    {\expandafter\hyper@@anchor\expandafter{\Hy@footnote@currentHref}{#1}}%
                    {\Hy@raisedlink{%
                        \expandafter\hyper@@anchor\expandafter{\Hy@footnote@currentHref}{\relax}%
                    }%
                    \let\@currentHref\Hy@footnote@currentHref
                    \let\@currentlabelname\@empty
                    #1}%
                \else
                    #1%
                \fi
            }%
            \color@endgroup
        }%
        % Convert to hbox for paragraph format
        \setbox0=\hbox{\m@munvxh0}%
        \dp0=\z@
        \ht0=\footfudgefactor\wd0
        \box0
        \penalty0
    }%
}

% Save notes mode (for tcolorbox)
\def\MFS@savenotes{%
    \MFS@debug{>>> SAVENOTES called}%
    \ifMFS@savingnotes
        \MFS@debug{Already in save mode}%
    \else
        \global\MFS@savingnotestrue
        
        % Save counter values
        \MFS@footnote@count=\c@footnote
        \MFS@mpfootnote@count=\c@mpfootnote
        
        % Initialize storage
        \MFS@width\columnwidth
        \let\MFS@colwidth\MFS@width
        \global\setbox\MFS@notes\box\voidb@x
        
        % Save minipage state
        \let\MFS@thempfn\thempfn
        \let\MFS@mpfn\@mpfn
        
        % Force main footnote counter
        \def\@mpfn{footnote}%
        \let\thempfn\thefootnote
        
        \MFS@debug{Save mode activated}%
    \fi
}

% Restore notes mode (for tcolorbox)
\def\MFS@restorenotes{%
    \MFS@debug{<<< RESTORENOTES called}%
    \ifMFS@savingnotes
        \global\MFS@savingnotesfalse
        
        % Restore minipage state  
        \let\thempfn\MFS@thempfn
        \let\@mpfn\MFS@mpfn
        
        % Restore counters
        \c@footnote=\MFS@footnote@count
        \c@mpfootnote=\MFS@mpfootnote@count
        
        \MFS@debug{Save mode deactivated}%
    \fi
    
    % Output saved notes
    \ifvoid\MFS@notes
        \MFS@debug{No notes to output}%
    \else
        \MFS@debug{Outputting saved notes to footinsv@r}%
        \insert\footinsv@r{\unvbox\MFS@notes}%
    \fi
}

% ============================================================================
% Hook into tcolorbox
% ============================================================================

\AtBeginDocument{%
    \@ifpackageloaded{tcolorbox}{%
        \MFS@debug{Configuring tcolorbox integration}%
        \tcbset{%
            before upper={\MFS@savenotes},
            after={\MFS@restorenotes}
        }%
        \MFS@debug{tcolorbox configured}%
    }{%
        \MFS@debug{tcolorbox not loaded}%
    }%
}

\endinput