// Copyright (C) 2026 - zsliu98
// This file is part of ZLEqualizer
//
// ZLEqualizer is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 as published by the Free Software Foundation.
//
// ZLEqualizer 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. See the GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License along with ZLEqualizer. If not, see <https://www.gnu.org/licenses/>.

#pragma once

#include "../../../PluginProcessor.hpp"
#include "../../../gui/gui.hpp"
#include "../../helper/helper.hpp"
#include "../../multilingual/tooltip_helper.hpp"

namespace zlpanel {
    class SinglePanel final : public juce::Component {
    public:
        explicit SinglePanel(PluginProcessor& p, zlgui::UIBase& base,
                             std::vector<size_t>& not_off_indices);

        void paintSameStereo(juce::Graphics& g);

        void paintDifferentStereo(juce::Graphics& g);

        void resized() override;

        void updateDrawingParas(size_t band,
                                zlp::FilterStatus filter_status,
                                bool is_dynamic_on,
                                bool is_same_stereo);

        void run(size_t band,
                 zlp::FilterStatus filter_status,
                 bool to_update_base, bool to_update_target,
                 std::span<float> xs, float k, float b,
                 zldsp::vector::aligned_vector<float>& base_mag, zldsp::vector::aligned_vector<float>& target_mag,
                 float center_x, float center_mag, float button_mag,
                 float base_left_x, float base_right_x,
                 bool to_update_side,
                 float left_x, float right_x,
                 bool is_all_pass = false,
                 bool is_first_order = false);

    private:
        static constexpr size_t kNumPoints = 400;
        static constexpr float kFillingAlpha = .125f;
        static constexpr float kDynamicFillingAlpha = .33333f;
        static constexpr float kNotSelectedAlphaMultiplier = .75f;
        static constexpr float kBypassAlphaMultiplier = .75f;
        static constexpr float kDiffStereoAlphaMultiplier = .33333f;
        static constexpr float kNoBandSelectedAlphaMultiplier = .75f;
        static constexpr float kThickMultiplier = 1.15f;

        PluginProcessor& p_ref_;
        zlgui::UIBase& base_;
        std::vector<size_t>& not_off_indices_;

        std::atomic<float> center_y_{0.f};
        float side_y_{0.f};

        std::array<TriBuffer<juce::Path>, zlp::kBandNum> base_paths_{};

        std::array<TriBuffer<juce::Path>, zlp::kBandNum> base_fills_{};

        std::array<TriBuffer<juce::Path>, zlp::kBandNum> target_fills_{};

        std::array<TriBuffer<juce::Line<float>>, zlp::kBandNum> button_lines_{};

        std::array<TriBuffer<juce::Line<float>>, zlp::kBandNum> side_lines_{};

        std::array<TriBuffer<juce::Line<float>>, zlp::kBandNum> all_pass_lines_{};

        std::array<float, zlp::kBandNum> base_stroke_alpha_{};
        std::array<float, zlp::kBandNum> base_fill_alpha_{};
        std::array<float, zlp::kBandNum> target_fill_alpha_{};
        std::array<juce::Colour, zlp::kBandNum> base_stroke_colour_{};
        std::array<bool, zlp::kBandNum> is_same_stereo_{};

        float curve_thickness_{0.f};

        zldsp::vector::aligned_vector<float> temp_db_{};

        template <bool thick = false>
        void drawBand(juce::Graphics& g, size_t band);

        void lookAndFeelChanged() override;
    };
}
