// SPDX-FileCopyrightText: 2024 vivi developers <vivi-ui@tuta.io>
// SPDX-License-Identifier: MIT

import { TextInputBaste, HorizontalLayoutBase } from "../foundation.slint";
import { StateLayer } from "./state_layer.slint";
import { MagicIcon } from "./magic_icon.slint";
import { MagicText } from "./magic_text.slint";
import {
    MagicPalette,
    MagicBorderSettings,
    MagicSizeSettings,
    MagicLayoutSettings,
    MagicFontSettings,
    MagicIconSettings
} from "./styling.slint";

export component TextField inherits TextInputBaste {
    out property <bool> has_focus: input.has_focus;
    in property <image> prefix_icon;
    in property <InputType> input_type <=> input.input_type;
    in property <bool> read_only <=> input.read-only;
    in property <TextHorizontalAlignment> horizontal_alignment <=> input.horizontal_alignment;

    min_width: max(MagicSizeSettings.min_text_field_width, content_layer.min_width);
    min_height: max(MagicSizeSettings.control_height, content_layer.min_height);
    style: {
        layout_style: MagicLayoutSettings.text_input_style,
        selection_background: MagicPalette.selection_background,
        selection_foreground: MagicPalette.foreground,
        icon_style: {
            icon_size: MagicIconSettings.body.icon_size,
            foreground: MagicPalette.foreground,
        },
        text_style: MagicFontSettings.body,
        placeholder_style: {
            font_size: MagicFontSettings.body.font_size,
            font_weight: MagicFontSettings.body.font_weight,
            foreground: MagicPalette.placeholder_foreground,
        },
        border_style: {
            border_width: MagicBorderSettings.control_border_width,
            border_radius: MagicBorderSettings.box_border_radius,
            border_brush: MagicPalette.border,
            background: MagicPalette.background
        }
    };

    accessible_role: text_input;
    accessible_value <=> root.text;
    accessible_placeholder_text: root.text == "" ? root.placeholder_text : "";
    accessible_action_set_value(v) => { root.text = v; root.edited(v); }
    forward_focus: input;

    StateLayer {
        width: 100%;
        height: 100%;
        border_radius: root.style.border_style.border_radius;
        has_focus: root.enabled && root.has_focus;
        has_error: root.enabled && root.has_error;
    }

    content_layer := HorizontalLayoutBase {
        style: root.style.layout_style;

        if root.prefix_icon.width > 0 && root.prefix_icon.height > 0 : MagicIcon {
            icon: root.prefix_icon;
            style: root.style.icon_style;
            horizontal_stretch: 0;
        }

        Rectangle {
            clip: true;

            if root.text == "" && root.placeholder_text != "" : MagicText {
                x: 0;
                text: root.placeholder_text;
                style: root.style.placeholder_style;
                vertical_alignment: center;
                horizontal-alignment: left;
            }

            input := TextInput {
                property <length> computed_x;

                x: min(0px, max(parent.width - self.width - self.text_cursor_width, self.computed_x));
                width: max(parent.width - self.text_cursor_width, self.preferred_width);
                enabled: root.enabled;
                text <=> root.text;
                font_size: root.style.text_style.font_size;
                font_weight: root.style.text_style.font_weight;
                vertical_alignment: center;
                color: root.style.text_style.foreground;
                selection_background_color: root.style.selection_background;
                selection_foreground_color: root.style.selection_foreground;
                single_line: true;

                cursor-position-changed(cpos) => {
                    if cpos.x + self.computed_x < 0 {
                        self.computed_x = - cpos.x;
                    } else if cpos.x + self.computed_x > parent.width - self.text_cursor_width {
                        self.computed_x = parent.width - cpos.x - self.text_cursor_width;
                    }
                }

                accepted => {
                    root.accepted(self.text);
                }
                edited => {
                    root.edited(self.text);
                }
            }
        }

        @children
    }

    public function set_selection_offsets(start: int, end: int) {
        input.set_selection_offsets(start, end);
    }

    public function select_all() {
        input.select_all();
    }

    public function clear_selection() {
        input.clear_selection();
    }

    public function cut() {
        input.cut();
    }

    public function copy() {
        input.copy();
    }

    public function paste() {
        input.paste();
    }

    states [
        disabled when !root.enabled : {
            root.opacity: 0.5;
        }
    ]
}