% unipersian-listings-fallback.def
%
% UniPersian: Persian language support for LaTeX.
%
% Copyright (C) 2026 Amer Amikhteh
%
% This file is part of the UniPersian-listings 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.
%
% The full license text is available at:
% https://www.latex-project.org/lppl/
%
% This work is "maintained" by Amer Amikhteh.
%
% The current maintainer of this work is Amer Amikhteh.

\ProvidesFile{unipersian-listings-fallback.def}
[2026/09/08 v0.1.0 Persian monospaced font fallback for xepersian]

% This file only tries to find a suitable Persian monospaced font when the user has not set \setpersianmonofont.
% The file does not change any fonts when loaded and only applies a fallback at BeginDocument
% if needed.

\ExplSyntaxOn

\bool_new:N \g_xpmf_setup_done_bool
\bool_new:N \l_xpmf_found_bool

\seq_new:N \g_xpmf_fallback_fonts_seq

\seq_gset_from_clist:Nn \g_xpmf_fallback_fonts_seq
{
    Vazir~Code,
    DejaVu~Sans~Mono,
    Vazirmatn,
    Tahoma,
    Segoe~UI
}

\cs_new_protected:Nn \xpmf_set_fallback_fonts:n
{
    \seq_gset_from_clist:Nn \g_xpmf_fallback_fonts_seq {#1}
}

\prg_new_conditional:Npnn \xpmf_if_api_available: {T,F,TF}
{
    \cs_if_exist:NTF \setpersianmonofont
    {
        \cs_if_exist:NTF \persianttdefault
        { \prg_return_true: }
        { \prg_return_false: }
    }
    { \prg_return_false: }
}

\prg_new_conditional:Npnn \xpmf_if_persian_mono_defined: {T,F,TF}
{
    \cs_if_exist:NTF \persianttdefault
    {
        \tl_if_blank:oTF {\persianttdefault}
        { \prg_return_false: }
        { \prg_return_true: }
    }
    { \prg_return_false: }
}

\prg_new_conditional:Npnn \xpmf_if_font_has_persian:n #1 {T,F,TF}
{
    \cs_if_exist:NTF \fontspec
    {
        \group_begin:
        \fontspec{#1}
        \iffontchar\font"0627
            \group_end:
            \prg_return_true:
        \else
            \group_end:
            \prg_return_false:
        \fi
    }
    { \prg_return_false: }
}

\cs_new_protected:Nn \xpmf_try_from_family:nn
{
    \xpmf_if_persian_mono_defined:F
    {
        \tl_set:Nx \l_tmpa_tl {#2}

        \tl_if_blank:VF \l_tmpa_tl
        {
            \prop_if_exist:cT { g__fontspec_fontinfo_\l_tmpa_tl _prop }
            {
                \prop_get:cnNT
                { g__fontspec_fontinfo_\l_tmpa_tl _prop }
                { fontname }
                \l_tmpb_tl
                {
                    \xpmf_if_font_has_persian:nT {\l_tmpb_tl}
                    {
                        \setpersianmonofont{\l_tmpb_tl}
                    }
                }
            }
        }
    }
}

\cs_new_protected:Nn \xpmf_try_ttdefault:
{
    \xpmf_if_persian_mono_defined:F
    {
        \cs_if_exist:NT \ttdefault
        {
            \tl_set:Nx \l_tmpa_tl {\ttdefault}

            \tl_if_blank:VF \l_tmpa_tl
            {
                \str_if_eq:VnF \l_tmpa_tl {lmtt}
                {
                    \xpmf_try_from_family:nn
                    {ttdefault}
                    {\ttdefault}
                }
            }
        }
    }
}

\cs_new_protected:Nn \xpmf_try_rmdefault:
{
    \xpmf_if_persian_mono_defined:F
    {
        \cs_if_exist:NT \rmdefault
        {
            \xpmf_try_from_family:nn
            {rmdefault}
            {\rmdefault}
        }
    }
}

\cs_new_protected:Nn \xpmf_try_fallback_list:
{
    \xpmf_if_persian_mono_defined:F
    {
        \cs_if_exist:NT \IfFontExistsTF
        {
            \bool_set_false:N \l_xpmf_found_bool

            \seq_map_inline:Nn \g_xpmf_fallback_fonts_seq
            {
                \bool_if:NF \l_xpmf_found_bool
                {
                    \IfFontExistsTF{##1}
                    {
                        \xpmf_if_font_has_persian:nT {##1}
                        {
                            \setpersianmonofont{##1}
                            \bool_set_true:N \l_xpmf_found_bool
                            \seq_map_break:
                        }
                    }
                    {}
                }
            }
        }
    }
}

\cs_new_protected:Nn \xpmf_setup:
{
    \bool_if:NF \g_xpmf_setup_done_bool
    {
        \xpmf_if_api_available:T
        {
            \xpmf_try_ttdefault:
            \xpmf_try_rmdefault:
            \xpmf_try_fallback_list:
        }

        \bool_gset_true:N \g_xpmf_setup_done_bool
    }
}

\NewDocumentCommand{\XepersianMonoFallbackSetup}{}
{
    \xpmf_setup:
}


\ExplSyntaxOff

\AtBeginDocument
{
    \XepersianMonoFallbackSetup
}

\endinput
