src/qrkit@internal@standard.erl

-module(qrkit@internal@standard).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/qrkit/internal/standard.gleam").
-export([version/1, width/1, height/1, rows/1, mask/1, encode_prefixed/7, encode/5]).
-export_type([encoded/0]).

-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.

?MODULEDOC(false).

-opaque encoded() :: {encoded,
        integer(),
        integer(),
        integer(),
        integer(),
        list(list(boolean()))}.

-file("src/qrkit/internal/standard.gleam", 123).
?DOC(false).
-spec version(encoded()) -> integer().
version(Encoded) ->
    {encoded, Version, _, _, _, _} = Encoded,
    Version.

-file("src/qrkit/internal/standard.gleam", 103).
?DOC(false).
-spec best_version_in_range(
    integer(),
    qrkit@types:error_correction(),
    integer(),
    integer()
) -> {ok, integer()} | {error, qrkit@error:encode_error()}.
best_version_in_range(Bits_needed, Ecc, Min_version, Max_version) ->
    case {qrkit@internal@version:best_version_for_bits(
            Bits_needed,
            Ecc,
            Min_version
        ),
        qrkit@internal@version:data_capacity_bits(Max_version, Ecc)} of
        {{ok, Chosen}, {ok, Max_bits}} ->
            case Chosen > Max_version of
                true ->
                    {error, {data_exceeds_capacity, Bits_needed, Max_bits}};

                false ->
                    {ok, Chosen}
            end;

        {{error, Error}, _} ->
            {error, Error};

        {_, {error, Error@1}} ->
            {error, Error@1}
    end.

-file("src/qrkit/internal/standard.gleam", 128).
?DOC(false).
-spec width(encoded()) -> integer().
width(Encoded) ->
    {encoded, _, Width, _, _, _} = Encoded,
    Width.

-file("src/qrkit/internal/standard.gleam", 133).
?DOC(false).
-spec height(encoded()) -> integer().
height(Encoded) ->
    {encoded, _, _, Height, _, _} = Encoded,
    Height.

-file("src/qrkit/internal/standard.gleam", 138).
?DOC(false).
-spec rows(encoded()) -> list(list(boolean())).
rows(Encoded) ->
    {encoded, _, _, _, _, Rows} = Encoded,
    Rows.

-file("src/qrkit/internal/standard.gleam", 143).
?DOC(false).
-spec mask(encoded()) -> integer().
mask(Encoded) ->
    {encoded, _, _, _, Mask, _} = Encoded,
    Mask.

-file("src/qrkit/internal/standard.gleam", 199).
?DOC(false).
-spec add_terminator(qrkit@internal@bitstream:bit_stream(), integer()) -> qrkit@internal@bitstream:bit_stream().
add_terminator(Stream, Capacity_bits) ->
    Remaining = Capacity_bits - qrkit@internal@bitstream:length_bits(Stream),
    Terminator_bits = case Remaining >= 4 of
        true ->
            4;

        false ->
            Remaining
    end,
    qrkit@internal@bitstream:append_bits(Stream, 0, Terminator_bits).

-file("src/qrkit/internal/standard.gleam", 222).
?DOC(false).
-spec do_add_pad_bytes(
    qrkit@internal@bitstream:bit_stream(),
    integer(),
    integer()
) -> qrkit@internal@bitstream:bit_stream().
do_add_pad_bytes(Stream, Remaining, Index) ->
    gleam@bool:guard(
        Remaining =< 0,
        Stream,
        fun() ->
            Byte = case (Index rem 2) =:= 0 of
                true ->
                    16#EC;

                false ->
                    16#11
            end,
            do_add_pad_bytes(
                qrkit@internal@bitstream:append_byte(Stream, Byte),
                Remaining - 1,
                Index + 1
            )
        end
    ).

-file("src/qrkit/internal/standard.gleam", 211).
?DOC(false).
-spec add_pad_bytes(qrkit@internal@bitstream:bit_stream(), integer()) -> qrkit@internal@bitstream:bit_stream().
add_pad_bytes(Stream, Data_codewords) ->
    do_add_pad_bytes(
        Stream,
        Data_codewords - erlang:length(
            qrkit@internal@bitstream:to_byte_list(Stream)
        ),
        0
    ).

-file("src/qrkit/internal/standard.gleam", 184).
?DOC(false).
-spec finish_data_stream(
    qrkit@internal@bitstream:bit_stream(),
    integer(),
    qrkit@types:error_correction(),
    integer()
) -> {ok, list(integer())} | {error, qrkit@error:encode_error()}.
finish_data_stream(Stream, Chosen_version, Ecc, Capacity_bits) ->
    Terminated = add_terminator(Stream, Capacity_bits),
    Padded = qrkit@internal@bitstream:pad_to_byte_boundary(Terminated),
    case qrkit@internal@version:data_codewords(Chosen_version, Ecc) of
        {error, Error} ->
            {error, Error};

        {ok, Data_codewords} ->
            {ok,
                begin
                    _pipe = add_pad_bytes(Padded, Data_codewords),
                    qrkit@internal@bitstream:to_byte_list(_pipe)
                end}
    end.

-file("src/qrkit/internal/standard.gleam", 314).
?DOC(false).
-spec take(list(integer()), integer(), list(integer())) -> {list(integer()),
    list(integer())}.
take(Values, Count, Acc) ->
    case {Values, Count} of
        {Rest, 0} ->
            {lists:reverse(Acc), Rest};

        {[Value | Rest@1], _} ->
            take(Rest@1, Count - 1, [Value | Acc]);

        {[], _} ->
            {lists:reverse(Acc), []}
    end.

-file("src/qrkit/internal/standard.gleam", 276).
?DOC(false).
-spec split_into_blocks(
    list(integer()),
    integer(),
    integer(),
    integer(),
    integer(),
    list(list(integer()))
) -> {list(list(integer())), list(integer())}.
split_into_blocks(
    Bytes,
    Group1_count,
    Group1_size,
    Group2_count,
    Group2_size,
    Acc
) ->
    case Group1_count > 0 of
        true ->
            {Head, Tail} = take(Bytes, Group1_size, []),
            split_into_blocks(
                Tail,
                Group1_count - 1,
                Group1_size,
                Group2_count,
                Group2_size,
                [Head | Acc]
            );

        false ->
            case Group2_count > 0 of
                true ->
                    {Head@1, Tail@1} = take(Bytes, Group2_size, []),
                    split_into_blocks(
                        Tail@1,
                        Group1_count,
                        Group1_size,
                        Group2_count - 1,
                        Group2_size,
                        [Head@1 | Acc]
                    );

                false ->
                    {lists:reverse(Acc), Bytes}
            end
    end.

-file("src/qrkit/internal/standard.gleam", 351).
?DOC(false).
-spec prepend_column(list(list(integer())), integer(), list(integer())) -> list(integer()).
prepend_column(Blocks, Index, Acc) ->
    case Blocks of
        [] ->
            Acc;

        [Block | Rest] ->
            case qrkit@internal@util:at(Block, Index) of
                {ok, Value} ->
                    prepend_column(Rest, Index, [Value | Acc]);

                {error, _} ->
                    prepend_column(Rest, Index, Acc)
            end
    end.

-file("src/qrkit/internal/standard.gleam", 333).
?DOC(false).
-spec do_interleave_lists(
    list(list(integer())),
    integer(),
    integer(),
    list(integer())
) -> list(integer()).
do_interleave_lists(Blocks, Index, Width, Acc) ->
    case Index >= Width of
        true ->
            lists:reverse(Acc);

        false ->
            do_interleave_lists(
                Blocks,
                Index + 1,
                Width,
                prepend_column(Blocks, Index, Acc)
            )
    end.

-file("src/qrkit/internal/standard.gleam", 366).
?DOC(false).
-spec max_length(list(list(integer())), integer()) -> integer().
max_length(Blocks, Current) ->
    case Blocks of
        [] ->
            Current;

        [Block | Rest] ->
            case erlang:length(Block) > Current of
                true ->
                    max_length(Rest, erlang:length(Block));

                false ->
                    max_length(Rest, Current)
            end
    end.

-file("src/qrkit/internal/standard.gleam", 326).
?DOC(false).
-spec interleave_lists(list(list(integer()))) -> list(integer()).
interleave_lists(Blocks) ->
    case max_length(Blocks, 0) of
        0 ->
            [];

        Width ->
            do_interleave_lists(Blocks, 0, Width, [])
    end.

-file("src/qrkit/internal/standard.gleam", 239).
?DOC(false).
-spec interleave_blocks(
    list(integer()),
    integer(),
    qrkit@types:error_correction()
) -> {ok, list(integer())} | {error, qrkit@error:encode_error()}.
interleave_blocks(Bytes, Chosen_version, Ecc) ->
    case {qrkit@internal@version:total_codewords(Chosen_version),
        qrkit@internal@version:ec_total_codewords(Chosen_version, Ecc),
        qrkit@internal@version:ec_blocks(Chosen_version, Ecc)} of
        {{ok, Total_codewords}, {ok, Ec_total_codewords}, {ok, Ec_total_blocks}} ->
            Data_total_codewords = Total_codewords - Ec_total_codewords,
            Blocks_in_group2 = case Ec_total_blocks of
                0 -> 0;
                Gleam@denominator -> Total_codewords rem Gleam@denominator
            end,
            Blocks_in_group1 = Ec_total_blocks - Blocks_in_group2,
            Total_codewords_in_group1 = case Ec_total_blocks of
                0 -> 0;
                Gleam@denominator@1 -> Total_codewords div Gleam@denominator@1
            end,
            Data_codewords_in_group1 = case Ec_total_blocks of
                0 -> 0;
                Gleam@denominator@2 -> Data_total_codewords div Gleam@denominator@2
            end,
            Data_codewords_in_group2 = Data_codewords_in_group1 + 1,
            Ec_count = Total_codewords_in_group1 - Data_codewords_in_group1,
            {Data_blocks, _} = split_into_blocks(
                Bytes,
                Blocks_in_group1,
                Data_codewords_in_group1,
                Blocks_in_group2,
                Data_codewords_in_group2,
                []
            ),
            Ec_blocks = gleam@list:map(
                Data_blocks,
                fun(Block) ->
                    qrkit@internal@reed_solomon:encode(Block, Ec_count)
                end
            ),
            {ok,
                lists:append(
                    interleave_lists(Data_blocks),
                    interleave_lists(Ec_blocks)
                )};

        {{error, Error}, _, _} ->
            {error, Error};

        {_, {error, Error@1}, _} ->
            {error, Error@1};

        {_, _, {error, Error@2}} ->
            {error, Error@2}
    end.

-file("src/qrkit/internal/standard.gleam", 148).
?DOC(false).
-spec create_codewords_prefixed(
    integer(),
    qrkit@types:error_correction(),
    list(qrkit@internal@segment:segment()),
    gleam@option:option(integer()),
    bitstring()
) -> {ok, list(integer())} | {error, qrkit@error:encode_error()}.
create_codewords_prefixed(Chosen_version, Ecc, Segments, Eci, Prefix_bits) ->
    case qrkit@internal@version:data_capacity_bits(Chosen_version, Ecc) of
        {error, Error} ->
            {error, Error};

        {ok, Capacity_bits} ->
            Prefixed_stream = begin
                _pipe = qrkit@internal@bitstream:new(),
                qrkit@internal@bitstream:append_bytes(_pipe, Prefix_bits)
            end,
            case qrkit@internal@segment:append_to_stream(
                Prefixed_stream,
                Segments,
                Chosen_version,
                Eci
            ) of
                {error, Error@1} ->
                    {error, Error@1};

                {ok, Stream} ->
                    case qrkit@internal@bitstream:length_bits(Stream) > Capacity_bits of
                        true ->
                            {error,
                                {data_exceeds_capacity,
                                    qrkit@internal@bitstream:length_bits(Stream),
                                    Capacity_bits}};

                        false ->
                            case finish_data_stream(
                                Stream,
                                Chosen_version,
                                Ecc,
                                Capacity_bits
                            ) of
                                {error, Error@2} ->
                                    {error, Error@2};

                                {ok, Bytes} ->
                                    interleave_blocks(
                                        Bytes,
                                        Chosen_version,
                                        Ecc
                                    )
                            end
                    end
            end
    end.

-file("src/qrkit/internal/standard.gleam", 489).
?DOC(false).
-spec setup_timing_pattern(qrkit@internal@matrix:matrix()) -> qrkit@internal@matrix:matrix().
setup_timing_pattern(Target) ->
    _pipe = qrkit@internal@util:range(
        8,
        qrkit@internal@matrix:width(Target) - 9
    ),
    gleam@list:fold(
        _pipe,
        Target,
        fun(Acc, Index) ->
            Dark = (Index rem 2) =:= 0,
            _pipe@1 = Acc,
            _pipe@2 = qrkit@internal@matrix:set(_pipe@1, Index, 6, Dark, true),
            qrkit@internal@matrix:set(_pipe@2, 6, Index, Dark, true)
        end
    ).

-file("src/qrkit/internal/standard.gleam", 510).
?DOC(false).
-spec draw_alignment_pattern(
    qrkit@internal@matrix:matrix(),
    integer(),
    integer()
) -> qrkit@internal@matrix:matrix().
draw_alignment_pattern(Target, Row, Col) ->
    _pipe = qrkit@internal@util:range(-2, 2),
    gleam@list:fold(
        _pipe,
        Target,
        fun(Acc, Row_offset) -> _pipe@1 = qrkit@internal@util:range(-2, 2),
            gleam@list:fold(
                _pipe@1,
                Acc,
                fun(Acc2, Col_offset) ->
                    Dark = ((((Row_offset =:= -2) orelse (Row_offset =:= 2))
                    orelse (Col_offset =:= -2))
                    orelse (Col_offset =:= 2))
                    orelse ((Row_offset =:= 0) andalso (Col_offset =:= 0)),
                    qrkit@internal@matrix:set(
                        Acc2,
                        Row + Row_offset,
                        Col + Col_offset,
                        Dark,
                        true
                    )
                end
            ) end
    ).

-file("src/qrkit/internal/standard.gleam", 648).
?DOC(false).
-spec reserve_if_data(
    qrkit@internal@matrix:matrix(),
    integer(),
    integer(),
    list({integer(), integer()})
) -> list({integer(), integer()}).
reserve_if_data(Target, Row, Col, Acc) ->
    case qrkit@internal@matrix:is_reserved(Target, Row, Col) of
        true ->
            Acc;

        false ->
            [{Row, Col} | Acc]
    end.

-file("src/qrkit/internal/standard.gleam", 632).
?DOC(false).
-spec scan_column_pair(
    qrkit@internal@matrix:matrix(),
    integer(),
    integer(),
    integer(),
    list({integer(), integer()})
) -> {list({integer(), integer()}), integer(), integer()}.
scan_column_pair(Target, Col, Row, Inc, Acc) ->
    With_right = reserve_if_data(Target, Row, Col, Acc),
    With_both = reserve_if_data(Target, Row, Col - 1, With_right),
    Next_row = Row + Inc,
    case (Next_row < 0) orelse (Next_row >= qrkit@internal@matrix:height(Target)) of
        true ->
            {With_both, Row, 0 - Inc};

        false ->
            scan_column_pair(Target, Col, Next_row, Inc, With_both)
    end.

-file("src/qrkit/internal/standard.gleam", 611).
?DOC(false).
-spec data_positions(
    qrkit@internal@matrix:matrix(),
    integer(),
    integer(),
    integer(),
    list({integer(), integer()})
) -> list({integer(), integer()}).
data_positions(Target, Col, Row, Inc, Acc) ->
    case Col =< 0 of
        true ->
            lists:reverse(Acc);

        false ->
            Actual_col = case Col =:= 6 of
                true ->
                    5;

                false ->
                    Col
            end,
            {Next_acc, Next_row, Next_inc} = scan_column_pair(
                Target,
                Actual_col,
                Row,
                Inc,
                Acc
            ),
            data_positions(Target, Actual_col - 2, Next_row, Next_inc, Next_acc)
    end.

-file("src/qrkit/internal/standard.gleam", 660).
?DOC(false).
-spec place_bits(
    qrkit@internal@matrix:matrix(),
    list({integer(), integer()}),
    list(boolean())
) -> qrkit@internal@matrix:matrix().
place_bits(Target, Positions, Bits) ->
    case {Positions, Bits} of
        {[{Row, Col} | Rest_positions], [Bit | Rest_bits]} ->
            place_bits(
                qrkit@internal@matrix:set(Target, Row, Col, Bit, false),
                Rest_positions,
                Rest_bits
            );

        {[{Row@1, Col@1} | Rest_positions@1], []} ->
            place_bits(
                qrkit@internal@matrix:set(Target, Row@1, Col@1, false, false),
                Rest_positions@1,
                []
            );

        {[], _} ->
            Target
    end.

-file("src/qrkit/internal/standard.gleam", 702).
?DOC(false).
-spec alignment_row_col_coords(integer(), integer(), integer(), list(integer())) -> list(integer()).
alignment_row_col_coords(Size, Count, Step, Acc) ->
    case erlang:length(Acc) >= Count of
        true ->
            Acc;

        false ->
            Value = (Size - 7) - ((erlang:length(Acc) - 1) * Step),
            alignment_row_col_coords(
                Size,
                Count,
                Step,
                lists:append(Acc, [Value])
            )
    end.

-file("src/qrkit/internal/standard.gleam", 751).
?DOC(false).
-spec finder_overlap(integer(), integer(), integer()) -> boolean().
finder_overlap(Row, Col, Size) ->
    Corner = Size - 7,
    (((Row =:= 6) andalso (Col =:= 6)) orelse ((Row =:= 6) andalso (Col =:= Corner)))
    orelse ((Row =:= Corner) andalso (Col =:= 6)).

-file("src/qrkit/internal/standard.gleam", 735).
?DOC(false).
-spec expand_alignment_row(
    integer(),
    list(integer()),
    integer(),
    list({integer(), integer()})
) -> list({integer(), integer()}).
expand_alignment_row(Row, Cols, Size, Acc) ->
    case Cols of
        [] ->
            Acc;

        [Col | Rest] ->
            case finder_overlap(Row, Col, Size) of
                true ->
                    expand_alignment_row(Row, Rest, Size, Acc);

                false ->
                    expand_alignment_row(Row, Rest, Size, [{Row, Col} | Acc])
            end
    end.

-file("src/qrkit/internal/standard.gleam", 717).
?DOC(false).
-spec expand_alignment_coords(
    list(integer()),
    list(integer()),
    integer(),
    list({integer(), integer()})
) -> list({integer(), integer()}).
expand_alignment_coords(Rows, Cols, Size, Acc) ->
    case Rows of
        [] ->
            Acc;

        [Row | Rest] ->
            expand_alignment_coords(
                Rest,
                Cols,
                Size,
                expand_alignment_row(Row, Cols, Size, Acc)
            )
    end.

-file("src/qrkit/internal/standard.gleam", 760).
?DOC(false).
-spec ceil_div(integer(), integer()) -> integer().
ceil_div(Numerator, Denominator) ->
    case Denominator of
        0 -> 0;
        Gleam@denominator -> ((Numerator + Denominator) - 1) div Gleam@denominator
    end.

-file("src/qrkit/internal/standard.gleam", 682).
?DOC(false).
-spec alignment_positions(integer()) -> list({integer(), integer()}).
alignment_positions(Chosen_version) ->
    case Chosen_version =:= 1 of
        true ->
            [];

        false ->
            case qrkit@internal@version:symbol_size(Chosen_version) of
                {ok, Size} ->
                    Count = (Chosen_version div 7) + 2,
                    Step = case Size =:= 145 of
                        true ->
                            26;

                        false ->
                            ceil_div(Size - 13, (2 * Count) - 2) * 2
                    end,
                    Coords = alignment_row_col_coords(Size, Count, Step, [6]),
                    expand_alignment_coords(Coords, Coords, Size, []);

                {error, _} ->
                    []
            end
    end.

-file("src/qrkit/internal/standard.gleam", 499).
?DOC(false).
-spec setup_alignment_patterns(qrkit@internal@matrix:matrix(), integer()) -> qrkit@internal@matrix:matrix().
setup_alignment_patterns(Target, Chosen_version) ->
    _pipe = alignment_positions(Chosen_version),
    gleam@list:fold(
        _pipe,
        Target,
        fun(Acc, Position) ->
            {Row, Col} = Position,
            draw_alignment_pattern(Acc, Row, Col)
        end
    ).

-file("src/qrkit/internal/standard.gleam", 768).
?DOC(false).
-spec power_of_two(integer()) -> integer().
power_of_two(Index) ->
    case Index =< 0 of
        true ->
            1;

        false ->
            2 * power_of_two(Index - 1)
    end.

-file("src/qrkit/internal/standard.gleam", 764).
?DOC(false).
-spec bit_at(integer(), integer()) -> boolean().
bit_at(Value, Index) ->
    ((case power_of_two(Index) of
        0 -> 0;
        Gleam@denominator -> Value div Gleam@denominator
    end) rem 2) =:= 1.

-file("src/qrkit/internal/standard.gleam", 530).
?DOC(false).
-spec setup_version_info(qrkit@internal@matrix:matrix(), integer()) -> qrkit@internal@matrix:matrix().
setup_version_info(Target, Chosen_version) ->
    Bits = qrkit@internal@format_info:version_bits(Chosen_version),
    _pipe = qrkit@internal@util:range(0, 17),
    gleam@list:fold(
        _pipe,
        Target,
        fun(Acc, Index) ->
            Row = Index div 3,
            Col = ((Index rem 3) + qrkit@internal@matrix:width(Acc)) - 11,
            Dark = bit_at(Bits, Index),
            _pipe@1 = Acc,
            _pipe@2 = qrkit@internal@matrix:set(_pipe@1, Row, Col, Dark, true),
            qrkit@internal@matrix:set(_pipe@2, Col, Row, Dark, true)
        end
    ).

-file("src/qrkit/internal/standard.gleam", 546).
?DOC(false).
-spec setup_format_info(
    qrkit@internal@matrix:matrix(),
    qrkit@types:error_correction(),
    integer()
) -> qrkit@internal@matrix:matrix().
setup_format_info(Target, Ecc, Current_mask) ->
    Size = qrkit@internal@matrix:width(Target),
    Bits = qrkit@internal@format_info:format_bits(Ecc, Current_mask),
    With_info = begin
        _pipe = qrkit@internal@util:range(0, 14),
        gleam@list:fold(
            _pipe,
            Target,
            fun(Acc, Index) ->
                Dark = bit_at(Bits, Index),
                Vertical_row = case Index < 6 of
                    true ->
                        Index;

                    false ->
                        case Index < 8 of
                            true ->
                                Index + 1;

                            false ->
                                (Size - 15) + Index
                        end
                end,
                Horizontal_col = case Index < 8 of
                    true ->
                        (Size - Index) - 1;

                    false ->
                        case Index < 9 of
                            true ->
                                15 - Index;

                            false ->
                                14 - Index
                        end
                end,
                _pipe@1 = Acc,
                _pipe@2 = qrkit@internal@matrix:set(
                    _pipe@1,
                    Vertical_row,
                    8,
                    Dark,
                    true
                ),
                qrkit@internal@matrix:set(
                    _pipe@2,
                    8,
                    Horizontal_col,
                    Dark,
                    true
                )
            end
        )
    end,
    qrkit@internal@matrix:set(With_info, Size - 8, 8, true, true).

-file("src/qrkit/internal/standard.gleam", 409).
?DOC(false).
-spec choose_best_mask_loop(
    qrkit@internal@matrix:matrix(),
    qrkit@types:error_correction(),
    integer(),
    {integer(), qrkit@internal@matrix:matrix()},
    integer()
) -> {integer(), qrkit@internal@matrix:matrix()}.
choose_best_mask_loop(Target, Ecc, Candidate, Best, Best_penalty) ->
    case Candidate > 7 of
        true ->
            Best;

        false ->
            Masked = begin
                _pipe = qrkit@internal@mask:apply(Candidate, Target),
                setup_format_info(_pipe, Ecc, Candidate)
            end,
            Penalty = qrkit@internal@mask:penalty_total(Masked),
            case (Candidate =:= 0) orelse (Penalty < Best_penalty) of
                true ->
                    choose_best_mask_loop(
                        Target,
                        Ecc,
                        Candidate + 1,
                        {Candidate, Masked},
                        Penalty
                    );

                false ->
                    choose_best_mask_loop(
                        Target,
                        Ecc,
                        Candidate + 1,
                        Best,
                        Best_penalty
                    )
            end
    end.

-file("src/qrkit/internal/standard.gleam", 402).
?DOC(false).
-spec choose_best_mask(
    qrkit@internal@matrix:matrix(),
    qrkit@types:error_correction()
) -> {integer(), qrkit@internal@matrix:matrix()}.
choose_best_mask(Target, Ecc) ->
    choose_best_mask_loop(Target, Ecc, 0, {0, Target}, 0).

-file("src/qrkit/internal/standard.gleam", 593).
?DOC(false).
-spec codewords_to_bits(list(integer()), list(boolean())) -> list(boolean()).
codewords_to_bits(Codewords, Acc) ->
    case Codewords of
        [] ->
            lists:reverse(Acc);

        [Byte | Rest] ->
            codewords_to_bits(
                Rest,
                [bit_at(Byte, 0),
                    bit_at(Byte, 1),
                    bit_at(Byte, 2),
                    bit_at(Byte, 3),
                    bit_at(Byte, 4),
                    bit_at(Byte, 5),
                    bit_at(Byte, 6),
                    bit_at(Byte, 7) |
                    Acc]
            )
    end.

-file("src/qrkit/internal/standard.gleam", 580).
?DOC(false).
-spec setup_data(qrkit@internal@matrix:matrix(), list(integer())) -> qrkit@internal@matrix:matrix().
setup_data(Target, Codewords) ->
    Bits = codewords_to_bits(Codewords, []),
    Positions = data_positions(
        Target,
        qrkit@internal@matrix:width(Target) - 1,
        qrkit@internal@matrix:width(Target) - 1,
        -1,
        []
    ),
    place_bits(Target, Positions, Bits).

-file("src/qrkit/internal/standard.gleam", 775).
?DOC(false).
-spec inside(qrkit@internal@matrix:matrix(), integer(), integer()) -> boolean().
inside(Target, Row, Col) ->
    (((Row >= 0) andalso (Row < qrkit@internal@matrix:height(Target))) andalso (Col
    >= 0))
    andalso (Col < qrkit@internal@matrix:width(Target)).

-file("src/qrkit/internal/standard.gleam", 451).
?DOC(false).
-spec draw_finder_pattern(qrkit@internal@matrix:matrix(), integer(), integer()) -> qrkit@internal@matrix:matrix().
draw_finder_pattern(Target, Top, Left) ->
    _pipe = qrkit@internal@util:range(-1, 7),
    gleam@list:fold(
        _pipe,
        Target,
        fun(Acc, Row_offset) -> _pipe@1 = qrkit@internal@util:range(-1, 7),
            gleam@list:fold(
                _pipe@1,
                Acc,
                fun(Acc2, Col_offset) ->
                    Row = Top + Row_offset,
                    Col = Left + Col_offset,
                    case inside(Acc2, Row, Col) of
                        false ->
                            Acc2;

                        true ->
                            Dark = ((((Row_offset >= 0) andalso (Row_offset =< 6))
                            andalso (Col_offset >= 0))
                            andalso (Col_offset =< 6))
                            andalso (((((Row_offset =:= 0) orelse (Row_offset
                            =:= 6))
                            orelse (Col_offset =:= 0))
                            orelse (Col_offset =:= 6))
                            orelse ((((Row_offset >= 2) andalso (Row_offset =< 4))
                            andalso (Col_offset >= 2))
                            andalso (Col_offset =< 4))),
                            qrkit@internal@matrix:set(
                                Acc2,
                                Row,
                                Col,
                                Dark,
                                true
                            )
                    end
                end
            ) end
    ).

-file("src/qrkit/internal/standard.gleam", 439).
?DOC(false).
-spec setup_finder_patterns(qrkit@internal@matrix:matrix(), integer()) -> qrkit@internal@matrix:matrix().
setup_finder_patterns(Target, _) ->
    Size = qrkit@internal@matrix:width(Target),
    Positions = [{0, 0}, {0, Size - 7}, {Size - 7, 0}],
    gleam@list:fold(
        Positions,
        Target,
        fun(Acc, Position) ->
            {Row, Col} = Position,
            draw_finder_pattern(Acc, Row, Col)
        end
    ).

-file("src/qrkit/internal/standard.gleam", 377).
?DOC(false).
-spec build_matrix(integer(), qrkit@types:error_correction(), list(integer())) -> {ok,
        {integer(), qrkit@internal@matrix:matrix()}} |
    {error, qrkit@error:encode_error()}.
build_matrix(Chosen_version, Ecc, Codewords) ->
    case qrkit@internal@version:symbol_size(Chosen_version) of
        {error, Error} ->
            {error, Error};

        {ok, Size} ->
            Base = begin
                _pipe = qrkit@internal@matrix:new(Size, Size),
                _pipe@1 = setup_finder_patterns(_pipe, Chosen_version),
                _pipe@2 = setup_timing_pattern(_pipe@1),
                _pipe@3 = setup_alignment_patterns(_pipe@2, Chosen_version),
                setup_format_info(_pipe@3, Ecc, 0)
            end,
            With_version = case Chosen_version >= 7 of
                true ->
                    setup_version_info(Base, Chosen_version);

                false ->
                    Base
            end,
            Placed = setup_data(With_version, Codewords),
            {Best_mask, Masked} = choose_best_mask(Placed, Ecc),
            {ok, {Best_mask, setup_format_info(Masked, Ecc, Best_mask)}}
    end.

-file("src/qrkit/internal/standard.gleam", 52).
?DOC(false).
-spec encode_prefixed(
    binary(),
    qrkit@types:error_correction(),
    integer(),
    integer(),
    gleam@option:option(integer()),
    qrkit@types:mode_preference(),
    bitstring()
) -> {ok, encoded()} | {error, qrkit@error:encode_error()}.
encode_prefixed(
    Text,
    Ecc,
    Min_version,
    Max_version,
    Eci,
    Preference,
    Prefix_bits
) ->
    case qrkit@internal@segment:optimise(Text, Min_version, Preference) of
        {error, Error} ->
            {error, Error};

        {ok, Segments} ->
            Prefix_length = erlang:bit_size(Prefix_bits),
            case best_version_in_range(
                Prefix_length + qrkit@internal@segment:encoded_bits(
                    Segments,
                    Min_version,
                    Eci
                ),
                Ecc,
                Min_version,
                Max_version
            ) of
                {error, Error@1} ->
                    {error, Error@1};

                {ok, Chosen_version} ->
                    case create_codewords_prefixed(
                        Chosen_version,
                        Ecc,
                        Segments,
                        Eci,
                        Prefix_bits
                    ) of
                        {error, Error@2} ->
                            {error, Error@2};

                        {ok, Codewords} ->
                            case build_matrix(Chosen_version, Ecc, Codewords) of
                                {ok, {Best_mask, Final_matrix}} ->
                                    {ok,
                                        {encoded,
                                            Chosen_version,
                                            qrkit@internal@matrix:width(
                                                Final_matrix
                                            ),
                                            qrkit@internal@matrix:height(
                                                Final_matrix
                                            ),
                                            Best_mask,
                                            qrkit@internal@matrix:rows(
                                                Final_matrix
                                            )}};

                                {error, Error@3} ->
                                    {error, Error@3}
                            end
                    end
            end
    end.

-file("src/qrkit/internal/standard.gleam", 36).
?DOC(false).
-spec encode(
    binary(),
    qrkit@types:error_correction(),
    gleam@option:option(integer()),
    gleam@option:option(integer()),
    qrkit@types:mode_preference()
) -> {ok, encoded()} | {error, qrkit@error:encode_error()}.
encode(Text, Ecc, Min_version, Eci, Preference) ->
    {Lo, Hi} = case Min_version of
        none ->
            {1, 40};

        {some, N} ->
            {N, N}
    end,
    encode_prefixed(Text, Ecc, Lo, Hi, Eci, Preference, <<>>).