% Babelbidi: Bidi extensions for Babel.
%
% Copyright (C) 2026 Amer Amikhteh
%
% This file is part of the Babelbidi package.
%
% This work is free software: you may redistribute it and/or modify
% it under the terms of the LaTeX Project Public License as published
% by the LaTeX Project, either version 1.3c of the License, or
% (at your option) any later version.
%
% This work is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
%
% This work is "maintained" by Amer Amikhteh.

\NeedsTeXFormat{LaTeX2e}

\ProvidesPackage{babelbidi-lang}
[2026/10/09 v0.1.0 Babel language metadata, selection, and bidi utilities]


\makeatletter


% --------------------------------------------------------------------------
% Manual language options
% --------------------------------------------------------------------------

\def\bbd@option@code{}
\def\bbd@option@latin{}
\def\bbd@option@ltr{}
\def\bbd@option@rtl{}

\DeclareKeys[babelbidi-lang]{%
    code  .store = \bbd@option@code,
    latin .store = \bbd@option@latin,
    ltr   .store = \bbd@option@ltr,
    rtl   .store = \bbd@option@rtl
}

\ProcessKeyOptions[babelbidi-lang]


% --------------------------------------------------------------------------
% Constants
% --------------------------------------------------------------------------

\def\bbd@name@english{english}
\def\bbd@name@null{null}
\def\bbd@name@nil{nil}
\def\bbd@script@latin{Latin}
\def\bbd@direction@ltr{LTR}
\def\bbd@direction@rtl{RTL}


% --------------------------------------------------------------------------
% Babel language metadata
% --------------------------------------------------------------------------

\def\bbd@script#1{%
    \ifcsname bbl@sname@#1\endcsname
        \csname bbl@sname@#1\endcsname
    \else
        null%
    \fi
}

\def\bbd@dir#1{%
    \def\bbd@dirresult{null}%
    \ifcsname bbl@sname@#1\endcsname
        \ifcsname bbl@provide@dirs\endcsname
            \bbl@provide@dirs{#1}%
        \fi
        \ifcsname bbl@wdir@#1\endcsname
            \edef\bbd@wdir{%
                \csname bbl@wdir@#1\endcsname
            }%
            \ifx\bbd@wdir\@empty
                \def\bbd@dirresult{null}%
            \else
                \ifnum\bbd@wdir=0
                    \def\bbd@dirresult{LTR}%
                \else
                    \def\bbd@dirresult{RTL}%
                \fi
            \fi
        \fi
    \fi
}

\def\bbd@english{%
    \def\bbd@result{null}%
    \def\bbd@found{0}%
    \bbl@foreach{\bbl@ini@loaded}{%
        \ifnum\bbd@found=0
            \edef\bbd@tmp{##1}%
            \ifx\bbd@tmp\bbd@name@english
                \def\bbd@result{english}%
                \def\bbd@found{1}%
            \fi
        \fi
    }%
}


% --------------------------------------------------------------------------
% Metadata tests
% --------------------------------------------------------------------------

\def\bbd@if@latin#1{%
    \edef\bbd@tmp{\bbd@script{#1}}%
    \ifx\bbd@tmp\bbd@script@latin
        \expandafter\@firstoftwo
    \else
        \expandafter\@secondoftwo
    \fi
}

\def\bbd@if@direction#1#2{%
    \bbd@dir{#1}%
    \edef\bbd@wanted{#2}%
    \ifx\bbd@dirresult\bbd@wanted
        \expandafter\@firstoftwo
    \else
        \expandafter\@secondoftwo
    \fi
}


% --------------------------------------------------------------------------
% Search functions
% --------------------------------------------------------------------------

\def\bbd@first@latin{%
    \def\bbd@result{null}%
    \def\bbd@found{0}%
    \bbl@foreach{\bbl@ini@loaded}{%
        \ifnum\bbd@found=0
            \edef\bbd@tmp{##1}%
            \ifx\bbd@tmp\bbd@name@nil
                % Ignore Babel's synthetic nil language.
            \else
                \edef\bbd@tmp{\bbd@script{##1}}%
                \ifx\bbd@tmp\bbd@script@latin
                    \edef\bbd@result{##1}%
                    \def\bbd@found{1}%
                \fi
            \fi
        \fi
    }%
}

\def\bbd@first@direction#1{%
    \def\bbd@result{null}%
    \def\bbd@found{0}%
    \bbl@foreach{\bbl@ini@loaded}{%
        \ifnum\bbd@found=0
            \bbd@if@direction{##1}{#1}{%
                \edef\bbd@result{##1}%
                \def\bbd@found{1}%
            }{}%
        \fi
    }%
}



% --------------------------------------------------------------------------
% Language selectors
% --------------------------------------------------------------------------

\def\bbd@select@code{%
    \edef\bbd@main{\bbl@main@language}%
    \edef\bbd@script@result{\bbd@script{\bbd@main}}%
    \ifx\bbd@script@result\bbd@script@latin
        \edef\bbd@result{\bbd@main}%
    \else
        \bbd@english
        \ifx\bbd@result\bbd@name@null
            \bbd@first@latin
            \ifx\bbd@result\bbd@name@null
                \bbd@dir{\bbd@main}%
                \ifx\bbd@dirresult\bbd@direction@ltr
                    \edef\bbd@result{\bbd@main}%
                \else
                    \bbd@first@direction{\bbd@direction@ltr}%
                    \ifx\bbd@result\bbd@name@null
                        \edef\bbd@result{\bbd@main}%
                    \fi
                \fi
            \fi
        \fi
    \fi
}


\def\bbd@select@latin{%
    \edef\bbd@main{\bbl@main@language}%
    \bbd@if@latin{\bbd@main}{%
        \edef\bbd@result{\bbd@main}%
    }{%
        \bbd@first@latin
        \ifx\bbd@result\bbd@name@null
            \def\bbd@result{english}%
        \fi
    }%
}

\def\bbd@select@ltr{%
    \edef\bbd@main{\bbl@main@language}%
    \bbd@if@direction{\bbd@main}{\bbd@direction@ltr}{%
        \edef\bbd@result{\bbd@main}%
    }{%
        \bbd@first@direction{\bbd@direction@ltr}%
        \ifx\bbd@result\bbd@name@null
            \def\bbd@result{english}%
        \fi
    }%
}

\def\bbd@select@rtl{%
    \edef\bbd@main{\bbl@main@language}%
    \bbd@if@direction{\bbd@main}{\bbd@direction@rtl}{%
        \edef\bbd@result{\bbd@main}%
    }{%
        \bbd@first@direction{\bbd@direction@rtl}%
        \ifx\bbd@result\bbd@name@null
            \def\bbd@result{arabic}%
        \fi
    }%
}


% --------------------------------------------------------------------------
% Resolve and cache all language selections
% --------------------------------------------------------------------------

\AddToHook{begindocument/before}[babelbidi-lang]{%
    \ifx\bbd@option@code\@empty
        \bbd@select@code
        \edef\bbd@lang@code{\bbd@result}%
    \else
        \edef\bbd@lang@code{\bbd@option@code}%
    \fi

    \ifx\bbd@option@latin\@empty
        \bbd@select@latin
        \edef\bbd@lang@latin{\bbd@result}%
    \else
        \edef\bbd@lang@latin{\bbd@option@latin}%
    \fi

    \ifx\bbd@option@ltr\@empty
        \bbd@select@ltr
        \edef\bbd@lang@ltr{\bbd@result}%
    \else
        \edef\bbd@lang@ltr{\bbd@option@ltr}%
    \fi

    \ifx\bbd@option@rtl\@empty
        \bbd@select@rtl
        \edef\bbd@lang@rtl{\bbd@result}%
    \else
        \edef\bbd@lang@rtl{\bbd@option@rtl}%
    \fi
}


% --------------------------------------------------------------------------
% Inline language commands
% --------------------------------------------------------------------------

\NewDocumentCommand\lr{m}{\foreignlanguage[captions]{\bbd@lang@ltr}{#1}}
\NewDocumentCommand\rl{m}{\foreignlanguage[captions]{\bbd@lang@rtl}{#1}}


% --------------------------------------------------------------------------
% Latin environment
% --------------------------------------------------------------------------

\NewDocumentEnvironment{latin}{}%
{%
    \par
    \begin{otherlanguage}{\bbd@lang@latin}%
}%
{%
    \end{otherlanguage}%
    \par
}%


% ------------------------------------------
% Date helpers
% ------------------------------------------

\DeclareRobustCommand{\latintoday}{%
    \foreignlanguage[date]{\bbd@lang@latin}{\today}%
}

\makeatother

\endinput
