#pragma once
#include "node.h"
#include "node_stroke_preview.h"
#include "node_slider.h"
#include "brush.h"
#include "node_checkbox.h"
#include "node_combobox.h"
#include "node_image_texture.h"
#include "node_button.h"
#include "shape.h"
#include "image.h"

#define NANORT_USE_CPP11_FEATURE
#define NANORT_ENABLE_PARALLEL_BUILD
#include "nanort.h"
#include "node_button_custom.h"

class NodeHeightmapOverlay : public NodeBorder
{
    NodeBorder* m_picker{ nullptr };
    bool dragging = false;
public:
    glm::vec2 m_value{ 0.5f, 0.5f };
    glm::vec2 m_old_value{ 0.f };
    std::function<void(Node* target, glm::vec2 value)> on_value_changed;
    virtual Node* clone_instantiate() const override;
    virtual void clone_finalize(Node* dest) const override;
    virtual void init() override;
    void set_value(float x, float y);
    virtual kEventResult handle_event(Event* e) override;
    virtual void draw() override;
    virtual void handle_resize(glm::vec2 old_size, glm::vec2 new_size, float zoom) override;
};

class NodePanelGrid : public Node
{
public:
    enum class ShadeMode : uint8_t { Transparent, Flat, Solid, Textured };

    std::function<void(Node* target)> on_popup_close;

    NodeSliderH* m_groud_opacity;
    NodeSliderH* m_groud_value;
    NodeComboBox* m_groud_resolution;
    NodeSliderH* m_groud_offset;
    NodeImageTexture* m_hm_preview;
    NodeButton* m_hm_load;
    NodeButton* m_hm_clear;
    NodeButton* m_hm_reload;
    NodeComboBox* m_hm_shading;
    NodeSliderH* m_hm_height;
    NodeSliderH* m_hm_wireframe;
    NodeSliderH* m_hm_thickness;
    NodeSliderH* m_hm_lyaw;
    NodeSliderH* m_hm_lpitch;
    NodeSliderH* m_hm_ambient;
    NodeSliderH* m_hm_radius;
    NodeComboBox* m_hm_texres;
    NodeComboBox* m_hm_samples;
    NodeButton* m_render;
    NodeButton* m_commit;
    HeightmapPlane m_hm_plane;
    NodeHeightmapOverlay* m_hm_preview_nav;
    Plane m_plane;
    Image m_hm_image;
    Texture2D m_texture;
    Sampler m_sampler_mipmap;
    Sampler m_sampler_linear;
    std::string m_file_path;
    nanort::BVHAccel<float> m_rt_accel;
    bool m_rt_dirty = true;
    ShadeMode m_shade_mode{ ShadeMode::Transparent };
    GLfloat m_line_range[2];
    GLfloat m_line_granularity;

    virtual Node* clone_instantiate() const override;
    virtual void clone_finalize(Node* dest) const override;
    virtual void init() override;
    virtual kEventResult handle_event(Event* e) override;
    void init_controls();
    int get_samples() const;
    int get_texres() const;
    float get_radius() const;
    float get_ambient() const;
    float get_thickness() const;
    float get_resolution() const;
    float get_height() const;
    float get_offset() const;
    bool load_heightmap_file(const std::string& path, bool raise_ground_opacity);
    void draw_heightmap(const glm::mat4& proj, const glm::mat4& camera, bool commit) const;
    void bake_uvs();
};
