#include "IntermediateFrequencyWidget.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QPainter>
#include <QDebug>
#include "../component/FrequentShower.h"
#include "../component/ProgressBar.h"
#include "../component/ConsoleWidget.h"
#include "../component/ShowTime.h"
#include "../Global.h"
#include "../BaseWidget.h"
#include "../menu/BaseWidgetMenu.h"
#include "../BackEnd/MainWidget.h"
#include "../../../third_party/Renderive/Demo_Gallery/base/Tool.h"
static renderive::Range frequent_range = {-12000, 12000};
static double max = 160;
QWidget* Intermediate_Frequency_Widget::create_spectrogram_power_plot() {
    class Spectrum_Plot : public renderive::Latency_Eager_Plot {
    public:
        std::shared_ptr<renderive::Frequency_Axis> x_axis{};
        std::shared_ptr<renderive::Axis> y_axis{};
        std::shared_ptr<renderive::Multi_Select_Rect> msr{};
        std::shared_ptr<renderive::Spectrum> sp{};
        QMenu* menu{};
        void init() override {
            Latency_Eager_Plot::init();
            object_name = "Spectrum_Plot";
            auto data = create_renderable_node(get_root_renderable(), "Data_Renderable");
            auto frequency_axis_cache = create_renderable_node(get_root_renderable(), "Frequency_Axis_Cache");
            auto power_axis_cache = create_renderable_node(get_root_renderable(), "Power_Axis_Cache");
            auto overlay = create_renderable_node(get_root_renderable(), "Overlay_Renderable");
            frequency_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
            power_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
            x_axis = renderive::Frequency_Axis::Builder(frequency_axis_cache, Qt::Horizontal)
                    .set_tick_length(-10)
                    .set_coord_range(frequent_range)
                    .set_tick_length(-10)
                    .set_sub_tick_length(-5)
                    .build();
            y_axis = renderive::Axis::Builder(power_axis_cache, Qt::Vertical)
                    .set_coord_range({160, 0})
                    .set_unit_text("功率")
                    .build();
            sp = renderive::Spectrum::Builder(data, x_axis, y_axis)
                 .set_frequency_range(frequent_range)
                 .set_use_sweep_frequency_rect(true)
                 .set_frequency_point_size(1024)
                 .build();
            msr = renderive::Multi_Select_Rect::Builder(overlay, x_axis, y_axis).build();
        }
    protected:
        void resizeEvent(QResizeEvent* event) override {
            x_axis->set_x(0);
            x_axis->set_y(height() - 1);
            x_axis->set_pixel_size(width());
            y_axis->set_x(0);
            y_axis->set_y(0);
            y_axis->set_pixel_size(height());
        }
        void contextMenuEvent(QContextMenuEvent* event) override {
            if (!menu) {
                auto ws = concat_widgets(
                bw(cw(sp.get(), -1), "频谱图"),
                bw(cw(x_axis.get()), "频率x轴"),
                bw(cw(y_axis.get()), "功率y轴"),
                bw(cw(msr.get()), "多选框"));
                menu = create_menu(this, ws);
            }
            menu->exec(event->globalPos());
        }
    };
    auto w = new Spectrum_Plot;
    w->init();
    spectrogram_line = w->sp;
    progress_bar1->set_value = [this]() {
        double middle_frequent = this->spectrogram_line->frequency_range().middle();
        bool ok = false;
        double power = spectrogram_line->get_power(middle_frequent, ok, renderive::SRC::Render);
        if (ok)
            this->progress_bar1->value = power;
    };
    return w;
}
QWidget* Intermediate_Frequency_Widget::create_Afterglow_Plot() {
    class Afterglow_Plot : public renderive::Latency_Eager_Plot {
    public:
        std::shared_ptr<renderive::Frequency_Axis> x_axis{};
        std::shared_ptr<renderive::Axis> y_axis{};
        std::shared_ptr<renderive::Afterglow> ag{};
        std::shared_ptr<renderive::Multi_Select_Rect> msr{};
        QMenu* menu{};
        void init() override {
            Latency_Eager_Plot::init();
            object_name = "Afterglow_Plot";
            auto data = create_renderable_node(get_root_renderable(), "Data_Renderable");
            auto frequency_axis_cache = create_renderable_node(get_root_renderable(), "Frequency_Axis_Cache");
            auto power_axis_cache = create_renderable_node(get_root_renderable(), "Power_Axis_Cache");
            auto overlay = create_renderable_node(get_root_renderable(), "Overlay_Renderable");
            frequency_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
            power_axis_cache->set_cache_mode(renderive::Renderable_Cache_Mode::Local_Pixel);
            x_axis = renderive::Frequency_Axis::Builder(frequency_axis_cache, Qt::Horizontal)
                    .set_coord_range(frequent_range)
                    .set_tick_length(-10)
                    .set_sub_tick_length(-5)
                    .set_use_drag(true)
                    .build();
            y_axis = renderive::Axis::Builder(power_axis_cache, Qt::Vertical)
                    .set_coord_range({160, 0})
                    .set_use_drag(true)
                    .build();
            ag = renderive::Afterglow::Builder(data, x_axis, y_axis)
                 .set_frequency_range(frequent_range)
                 .set_power_range({0, 160})
                 .set_frequency_point_size(1024)
                 .build();
            msr = renderive::Multi_Select_Rect::Builder(overlay, x_axis, y_axis).build();
        }
    protected:
        void resizeEvent(QResizeEvent* event) override {
            x_axis->set_x(0);
            x_axis->set_y(height() - 1);
            x_axis->set_pixel_size(width());
            y_axis->set_x(0);
            y_axis->set_y(0);
            y_axis->set_pixel_size(height());
            ag->set_power_point_size(ag->power_axis()->get_pixel_point_size());
        }
        void contextMenuEvent(QContextMenuEvent* event) override {
            if (!menu) {
                auto ws = concat_widgets(
                bw(cw(ag.get(), -1), "余辉图"),
                bw(cw(x_axis.get()), "频率轴"),
                bw(cw(y_axis.get()), "功率概率轴"),
                bw(cw(msr.get()), "多选框"));
                menu = create_menu(this, ws);
            }
            menu->exec(event->globalPos());
        }
    };
    auto w = new Afterglow_Plot;
    w->init();
    afterglow = w->ag;
    return w;
}
//am, atu, vsql, nb, nr, dnf, pre, att, spl, fil1, agc_a
Intermediate_Frequency_Widget::Intermediate_Frequency_Widget(QWidget* parent) : Base_Widget(parent) {
    setObjectName("发射界面");
    int font_size = 20;
    m1 = create_normal("RF Gain\n62", font_size);
    m2 = create_normal("FFT SPAN\n100K", font_size);
    m3 = create_normal("频率表\n（12）89.6MHZ", font_size);
    m4 = create_normal("MODEM\nRTTY", font_size);
    m5 = create_normal("FIL1\n20K", font_size);
    m6 = create_normal("MSG1\n", font_size);
    frequent_shower = new Frequent_Shower(this);
    QColor orange(255, 165, 0);
    progress_bar1 = new Progress_Bar({
                                        Tick("S", Qt::black),
                                        {"3", Qt::black},
                                        {"6", Qt::black},
                                        {"9", Qt::black},
                                        {"20", Qt::black},
                                        {"+40", orange},
                                        {"+60", orange},
                                        {"+80", orange},
                                        {"+100", Qt::red},
                                    }, this);
    progress_bar2 = new Progress_Bar({
                                        {"1", Qt::black},
                                        {"2", Qt::yellow},
                                        {"3", Qt::red},
                                        {">5", Qt::red},
                                    }, this);
    auto main = create_vbox_layout({}, this);
    main->addStretch(1);
    {
        auto center = create_hbox_layout();
        main->addLayout(center, 7);
        auto front = create_vbox_layout();
        center->addLayout(front, 1);
        front->addWidget(m1, 3);
        front->addStretch(1);
        front->addWidget(m2, 3);
        center->addSpacing(4);
        auto middle = create_vbox_layout();
        center->addLayout(middle, 9);
        middle->addStretch(1);
        middle->addWidget(frequent_shower, 4);
        auto middle_h = create_hbox_layout();
        middle->addLayout(middle_h, 2);
        middle_h->addWidget(progress_bar1, 5);
        middle_h->addStretch(1);
        middle_h->addWidget(progress_bar2, 3);
        center->addStretch(4);
        auto back1 = create_vbox_layout();
        center->addLayout(back1, 1);
        back1->addWidget(m3, 3);
        back1->addStretch(1);
        back1->addWidget(m4, 3);
        center->addSpacing(4);
        auto back2 = create_vbox_layout();
        center->addLayout(back2, 1);
        back2->addWidget(m5, 3);
        back2->addStretch(1);
        back2->addWidget(m6, 3);
    }
    main->addStretch(1);
    main->addSpacing(8);
    auto a_h = create_hbox_layout();
    main->addLayout(a_h, 12);
    a_h->addWidget(create_spectrogram_power_plot(), 12);
    a_h->addSpacing(8);
    main->addWidget(create_Afterglow_Plot(), 12);
    init_menu();
}
Intermediate_Frequency_Widget::~Intermediate_Frequency_Widget() {}
void Intermediate_Frequency_Widget::focusInEvent(QFocusEvent* event) {
    QWidget::focusInEvent(event);
    frequent_shower->setFocus();
}
void Intermediate_Frequency_Widget::init_menu() {
    int font_size = 30;
    auto btn1 = new Double_Text_Menu_Button("设置最大值标记", "取消最大值标记", font_size, [&](bool is_first) {
        spectrogram_line->set_use_max_marker(is_first);
        base_widget_menu->hide();
        Main_Widget::instance()->get_current_base_widget()->setFocus();
    });
    auto btn2 = new Double_Text_Menu_Button("设置最小值标记", "取消最小值标记", font_size, [&](bool is_first) {
        spectrogram_line->set_use_min_marker(is_first);
        base_widget_menu->hide();
        Main_Widget::instance()->get_current_base_widget()->setFocus();
    });
    auto btn3 = new Menu_Button("设置自定义标记", font_size, [&]() {
        base_widget_menu->hide();
        Main_Widget::instance()->get_current_base_widget()->setFocus();
    });
    auto frequent_step2 = new Value_Menu_Button("频率步进:%1", font_size, [this](Value_Menu_Button* that, bool add) {
        int new_frequent = (int)that->value + (add ? 1 : -1);
        that->setValue(new_frequent);
        spectrogram_line->set_current_marker_frequency(new_frequent);
    }, qMax(0.0, spectrogram_line->frequency_range().length() / 50.0));
    auto btn_middle_frequent = new Value_Menu_Button("中频：%1 Hz", font_size, nullptr, spectrogram_line->middle_sweep_frequency());
    auto btn_frequent_width = new Value_Menu_Button("频宽：%1 Hz", font_size, [this, frequent_step2](Value_Menu_Button* that, bool add) {
        that->setValue(that->value + (double)(add ? frequent_step2->value : -frequent_step2->value));
        double middle_sweep_frequent = spectrogram_line->middle_sweep_frequency();
        spectrogram_line->set_sweep_frequency_range({middle_sweep_frequent - that->value, middle_sweep_frequent + that->value});
    }, qAbs(spectrogram_line->sweep_frequency_range().length() / 2));
    btn_middle_frequent->value_changed = [this, btn_frequent_width, frequent_step2](Value_Menu_Button* that, bool add) {
        that->setValue(that->value + (double)(add ? frequent_step2->value : -frequent_step2->value));
        spectrogram_line->set_middle_sweep_frequency(that->value);
        spectrogram_line->set_sweep_frequency_range({that->value - btn_frequent_width->value, that->value + btn_frequent_width->value});
    };
    auto btn2_2 = new Value_Menu_Button("参考增益：%1", font_size, [&](Value_Menu_Button* that, bool add) {
        that->setValue(that->value + (double)(add ? 1 : -1));
    }, 0);
    base_widget_menu->add_menu_button_on_layout1({btn1, btn2, btn3, btn2_2,});
    base_widget_menu->add_menu_button_on_layout2({frequent_step2, btn_middle_frequent, btn_frequent_width,});
    Base_Widget_Menu* sub1 = base_widget_menu->create_sub_widget_menu(btn3);
    auto frequent_step = new Value_Menu_Button("频率步进:%1", font_size, [this](Value_Menu_Button* that, bool add) {
        int new_frequent = (int)that->value + (add ? 1 : -1);
        that->setValue(new_frequent);
        spectrogram_line->set_current_marker_frequency(new_frequent);
    }, qMax(0.0, spectrogram_line->frequency_range().length() / 50.0));
    auto mark_frequent = new Value_Menu_Button("更改标记频率:%1", font_size, [frequent_step, this](Value_Menu_Button* that, bool add) {
        int new_frequent = (int)that->value + (add ? frequent_step->value : -frequent_step->value);
        that->setValue(new_frequent);
        spectrogram_line->set_current_marker_frequency(new_frequent);
    }, -1);
    auto add_init_frequent = new Value_Menu_Button("添加初始频率:%1", font_size, [frequent_step,this](Value_Menu_Button* that, bool add) {
        int new_frequent = (int)that->value + (add ? frequent_step->value : -frequent_step->value);
        that->setValue(new_frequent);
    }, spectrogram_line->frequency_range().origin);
    auto btn1_1 = new Value_Menu_Button("当前标记:%1", font_size, [&, mark_frequent](Value_Menu_Button* that, bool add) {
        int index = ((int)that->value + (add ? 1 : -1)) % spectrogram_line->select_line_marker_size();
        that->setValue(index);
        spectrogram_line->set_selected_line_marker(index);
        mark_frequent->setValue(spectrogram_line->get_mark_frequency(index));
    }, -1);
    auto btn1_2 = new Menu_Button("添加标记", font_size, [&, add_init_frequent]() {
        spectrogram_line->add_custom_line_marker(add_init_frequent->value);
    });
    auto btn1_3 = new Menu_Button("删除标记", font_size, [&]() {
        spectrogram_line->remove_current_marker();
        int size = spectrogram_line->select_line_marker_size();
        if (size == 0) {
            spectrogram_line->set_selected_line_marker(-1);
        }
        else {
            spectrogram_line->set_selected_line_marker(0);
        }
    });
    connect(sub1, &Base_Widget_Menu::show_that, [&, mark_frequent]() {
        spectrogram_line->set_selected_line_marker(0);
        mark_frequent->setValue(spectrogram_line->get_mark_frequency(0));
    });
    connect(sub1, &Base_Widget_Menu::hide_that, [&]() {
        spectrogram_line->un_select_marker();
    });
    sub1->add_menu_button_on_layout1({btn1_1, btn1_2, btn1_3}, 2);
    sub1->add_menu_button_on_layout2({frequent_step, mark_frequent, add_init_frequent}, 2);
}
