% File: hawkdraw-arrows.code.tex
% Copyright 2026 Jasper Habicht (mail(at)jasperhabicht.de).
%
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License version 1.3c,
% available at http://www.latex-project.org/lppl/.
%
% This file is part of the `hawkdraw' package (The Work in LPPL)
% and all files in that bundle must be distributed together.
%
% This work has the LPPL maintenance status `maintained'.
%
% BOF

% v0.0.8 2026-05-30

\msg_new:nnn { hawkdraw } { arrow-unknown } {
    Arrow ~ tip ~ `#1` ~ unknown.
}

\prop_new:N \g_hawkdraw_arrow_default_keys_prop
\clist_new:N \l_hawkdraw_arrow_start_keys_clist
\clist_new:N \l_hawkdraw_arrow_end_keys_clist

\keys_define:nn { hawkdraw / path } {
    arrow ~ start           .code:n         = {
        \tl_put_right:Nn \l_hawkdraw_path_postactions_tl {
            \fp_if_nan:nF { \g_hawkdraw_path_first_slope_fp } {
                \hawkdraw_arrow_put:nVnV {#1}
                    \g_hawkdraw_path_first_point_fp
                    { \g_hawkdraw_path_first_slope_fp - 90 }
                    \l_hawkdraw_arrow_start_keys_clist
            }
        }
    } ,
    arrow ~ start           .default:n      = { default } ,
    arrow ~ end             .code:n         = {
        \tl_put_right:Nn \l_hawkdraw_path_postactions_tl {
            \fp_if_nan:nF { \g_hawkdraw_path_last_slope_fp } {
                \hawkdraw_arrow_put:nVnV {#1}
                    \g_hawkdraw_path_last_point_fp
                    { \g_hawkdraw_path_last_slope_fp + 90 }
                    \l_hawkdraw_arrow_end_keys_clist
            }
        }
    } ,
    arrow ~ end             .default:n      = { default } ,
    arrow ~ start ~ style ~ set
                            .clist_set:N    = \l_hawkdraw_arrow_start_keys_clist ,
    arrow ~ end ~ style ~ set
                            .clist_set:N    = \l_hawkdraw_arrow_end_keys_clist ,
    arrow ~ start ~ style ~ add
                            .code:n         = {
        \clist_put_right:Nn \l_hawkdraw_arrow_start_keys_clist {#1}
    } ,
    arrow ~ end ~ style ~ add
                            .code:n         = {
        \clist_put_right:Nn \l_hawkdraw_arrow_end_keys_clist {#1}
    } ,
    arrow ~ style ~ set     .code:n         = {
        \clist_set:Nn \l_hawkdraw_arrow_start_keys_clist {#1}
        \clist_set:Nn \l_hawkdraw_arrow_end_keys_clist {#1}
    } ,
    arrow ~ style ~ add     .code:n         = {
        \clist_put_right:Nn \l_hawkdraw_arrow_start_keys_clist {#1}
        \clist_put_right:Nn \l_hawkdraw_arrow_end_keys_clist {#1}
    } ,
}

\cs_new_protected:Npn \hawkdraw_arrow_put:nnnn #1#2#3#4 {
    \draw_scope_begin:
        \draw_transform_shift:n {#2}
        \draw_transform_rotate:n {#3}
        \clist_clear:N \l_hawkdraw_path_use_clist
        \keys_set:ne { hawkdraw / path } {
            \prop_item:Nn \g_hawkdraw_arrow_default_keys_prop {#1}
        }
        \keys_set:nn { hawkdraw / path } {#4}
        \hawkdraw_path_set_options:
        \cs_if_exist_use:cF { hawkdraw_arrow_tip_ #1 : } {
            \msg_warning:nnn { hawkdraw } { arrow-unknown } {#1}
        }
        \draw_path_use_clear:e { \clist_use:N \l_hawkdraw_path_use_clist }
    \draw_scope_end:
}
\cs_generate_variant:Nn \hawkdraw_arrow_put:nnnn { nVVV , nVnV }

\cs_new_protected:Npn \hawkdraw_arrow_create:nnn #1#2#3 {
    \prop_gput:Nnn \g_hawkdraw_arrow_default_keys_prop {#1} {#2}
    \cs_new_protected:cpn { hawkdraw_arrow_tip_ #1 : } {
        #3
    }
}

% ===

\cs_new_protected:Npn \hawkdraw_arrow_put_single:nnn #1#2#3 {
    \exp_args:NNe
    \tl_put_right:Nn \l_hawkdraw_path_postactions_tl {
        \exp_not:N
        \hawkdraw_arrow_put:nnnn {#3}
            {
                \use:c { __hawkdraw_point_part_ \l__hawkdraw_path_type_tl :V }
                    \l_hawkdraw_tip_at_part_fp
            }
            {
                \use:c { __hawkdraw_point_part_slope_ \l__hawkdraw_path_type_tl :V }
                    \l_hawkdraw_tip_at_part_fp 
                \bool_if:NTF \l_hawkdraw_tip_flipped_bool {
                    + 90
                } {
                    - 90
                }
            }
            {#1}
    }
}
\cs_generate_variant:Nn \hawkdraw_arrow_put_single:nnn { nV , eV }

\cs_new_protected:cpn { __hawkdraw_path_process_ t :w } tip #1#2 \s__hawkdraw_stop {
    \__hawkdraw_cs_if_exist_use_secure:nnTF {#1} {
        __hawkdraw_path_process_tip_ \tl_head:n {#1} :w
    } {
        #1#2 \s__hawkdraw_stop
    } {
        \hawkdraw_arrow_put_single:nVn { }
            \l_hawkdraw_tip_at_part_fp {#1}
        \tl_trim_spaces_apply:nN {#2} \__hawkdraw_path_continue:n
    }
}

\fp_new:N \l_hawkdraw_tip_at_part_fp
\bool_new:N \l_hawkdraw_tip_flipped_bool

\keys_define:nn { hawkdraw / path / tip } {
    at ~ part               .fp_set:N       = \l_hawkdraw_tip_at_part_fp ,
    at ~ part               .initial:n      = { 1 } ,
    flipped                 .bool_set:N     = \l_hawkdraw_tip_flipped_bool ,
    flipped                 .default:n      = { true } ,
}

\cs_new_protected:cpn { __hawkdraw_path_process_tip_ [ :w } [ #1 ] #2#3 \s__hawkdraw_stop {
    \clist_clear:N \l__hawkdraw_keys_unprocessed_clist
    \keys_set_known:nnN { hawkdraw / path / tip } {#1}
        \l__hawkdraw_keys_unprocessed_clist
    \hawkdraw_arrow_put_single:eVn { \clist_use:N \l__hawkdraw_keys_unprocessed_clist }
        \l_hawkdraw_tip_at_part_fp {#2}
    \tl_trim_spaces_apply:nN {#3} \__hawkdraw_path_continue:n
}

% ===

\hawkdraw_arrow_create:nnn { none } { } { }

\hawkdraw_arrow_create:nnn { default } {
    fill
} {
    \draw_path_moveto:n { -2.5 , -5 }
    \draw_path_curveto:nn { -1 , -3 } { 0 , 0 }
    \draw_path_curveto:nn { 1 , -3 } { 2.5 , -5 }
    \draw_path_close:
}

\hawkdraw_arrow_create:nnn { stealth } {
    fill
} {
    \draw_path_moveto:n { 0 , 0 }
    \draw_path_lineto:n { -2.5 , -5 }
    \draw_path_lineto:n { 0 , -3.5 }
    \draw_path_lineto:n { 2.5 , -5 }
    \draw_path_close:
}

\hawkdraw_arrow_create:nnn { triangle } {
    fill
} {
    \draw_path_moveto:n { 0 , 0 }
    \draw_path_lineto:n { -2.5 , -5 }
    \draw_path_lineto:n { 2.5 , -5 }
    \draw_path_close:
}

\hawkdraw_arrow_create:nnn { circle } {
    fill
} {
    \draw_path_circle:nn { 0 , -2.5 } { 2.5 }
}

\hawkdraw_arrow_create:nnn { simple } {
    stroke ,
    line ~ cap = { round } ,
    line ~ join = { round }
} {
    \draw_path_moveto:n { -3 , -3 }
    \draw_path_curveto:nn { -0.5 , -1.25 } { 0 , 0 }
    \draw_path_curveto:nn { 0.5 , -1.25 } { 3 , -3 }
}

\hawkdraw_arrow_create:nnn { straight } {
    stroke
} {
    \draw_path_moveto:n { -3 , -3 }
    \draw_path_lineto:n { 0 , 0 }
    \draw_path_lineto:n { 3 , -3 }
}

\hawkdraw_arrow_create:nnn { bar } {
    stroke
} {
    \draw_path_moveto:n { -3 , 0 }
    \draw_path_lineto:n { 3 , 0 }
}

% EOF
