% babelbidi-lang.sty
%
% 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/14 v0.3.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}%
    \edef\bbd@dir@language{#1}%
    \ifx\bbd@dir@language\bbd@name@nil
        % nil is a placeholder, not a candidate auxiliary language.
    \else
        \ifcsname bbl@sname@#1\endcsname
            \ifcsname bbl@provide@dirs\endcsname
                % Babel also writes Lua locale properties for localeid.
                % Assign the inspected language's id in a local context.
                \begingroup
                \edef\languagename{#1}%
                \bbl@id@assign
                \bbl@provide@dirs{#1}%
                \endgroup
            \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
    \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
% --------------------------------------------------------------------------

\newif\ifbbd@latin
\newif\ifbbd@direction

\def\bbd@if@latin#1{%
    \bbd@latinfalse
    \edef\bbd@tmp{#1}%
    \ifx\bbd@tmp\bbd@name@nil
        \let\bbd@tmp\bbd@name@null
    \else
        \edef\bbd@tmp{\bbd@script{#1}}%
    \fi
    \ifx\bbd@tmp\bbd@script@latin
        \bbd@latintrue
    \fi
}

\def\bbd@if@direction#1#2{%
    \bbd@directionfalse
    \bbd@dir{#1}%
    \edef\bbd@wanted{#2}%
    \ifx\bbd@dirresult\bbd@wanted
        \bbd@directiontrue
    \fi
}


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

\def\bbd@first@latin{%
    \def\bbd@result{null}%
    \def\bbd@found{0}%
    \bbl@foreach{\bbl@ini@loaded}{%
        \ifnum\bbd@found=0
            \bbd@if@latin{##1}%
            \ifbbd@latin
                \edef\bbd@result{##1}%
                \def\bbd@found{1}%
            \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}%
            \ifbbd@direction
                \edef\bbd@result{##1}%
                \def\bbd@found{1}%
            \fi
        \fi
    }%
}



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

\def\bbd@select@code{%
    \edef\bbd@main{\bbl@main@language}%
    \bbd@if@latin{\bbd@main}%
    \ifbbd@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@if@direction{\bbd@main}{\bbd@direction@ltr}%
                \ifbbd@direction
                    \edef\bbd@result{\bbd@main}%
                \else
                    \bbd@first@direction{\bbd@direction@ltr}%
                    \ifx\bbd@result\bbd@name@null
                        \ifx\bbd@main\bbd@name@nil
                            \def\bbd@result{english}%
                        \else
                            \edef\bbd@result{\bbd@main}%
                        \fi
                    \fi
                \fi
            \fi
        \fi
    \fi
}


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

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

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


% --------------------------------------------------------------------------
% Select the four aliases at package load and after each babelprovide
% --------------------------------------------------------------------------

\def\bbd@update@langs{%
    \begingroup
    \ifx\bbd@option@code\@empty
        \bbd@select@code
        \xdef\bbd@main@code{\bbd@result}%
    \else
        \xdef\bbd@main@code{\bbd@option@code}%
    \fi

    \ifx\bbd@option@latin\@empty
        \bbd@select@latin
        \xdef\bbd@main@latin{\bbd@result}%
    \else
        \xdef\bbd@main@latin{\bbd@option@latin}%
    \fi

    \ifx\bbd@option@ltr\@empty
        \bbd@select@ltr
        \xdef\bbd@main@ltr{\bbd@result}%
    \else
        \xdef\bbd@main@ltr{\bbd@option@ltr}%
    \fi

    \ifx\bbd@option@rtl\@empty
        \bbd@select@rtl
        \xdef\bbd@main@rtl{\bbd@result}%
    \else
        \xdef\bbd@main@rtl{\bbd@option@rtl}%
    \fi
    \endgroup
}

\bbd@update@langs

% Preserve Babel's optional-argument parser and update immediately in the
% preamble as well as in the document, after Babel has finished its work.
\NewCommandCopy\bbd@babelprovide\babelprovide
\RenewDocumentCommand\babelprovide{O{} m}{%
    \bbd@babelprovide[#1]{#2}%
    \bbd@update@langs
}


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

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


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

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


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

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

\makeatother

\endinput
