#ifndef WAVEHANDLER_HPP_INCLUDED
#define WAVEHANDLER_HPP_INCLUDED
#include <glad/glad.h>
#include <shader.hpp>
#include <string>
#include <vector>
#include <toolbox.hpp>

class WaveHandler {
public:
	/*C'tors and D'tors*/
	WaveHandler(Toolbox& tb);
	WaveHandler() = delete;
	WaveHandler(const WaveHandler&) = delete;

	/*Public Member Functions*/
	bool initialize(const std::string damping_file="", const std::string palette_file=""); //damping_file is the name of the damping that should be loaded, without file extension
	void update(Toolbox& tb);
	void prepare_step();
	bool step(Toolbox& tb, const int num_dsteps);
	bool render();
	GLuint get_damping_tex() const;
	unsigned get_width() const;
	unsigned get_height() const;

	void generate_and_transfer_textures(Toolbox& tb) const;

private:
	/*Private Member Functions*/
	bool initialize_2D_data_();
	bool initialize_3D_data_();
	bool initialize_comp_data_(const std::string);
	bool initialize_render_data_(const std::string);
	bool initialize_shaders_();
	bool load_damping_(const std::string);
	bool load_palette_(const std::string);

	/*Private Data Members*/
	const int width_, height_; /*Window dimensions*/
	const int texwidth_, texheight_; /*Texture dimensions*/
	const int texoffset_left_, texoffset_right_, texoffset_bottom_, texoffset_top_;
	const std::string shader_path_;
	GLuint tex_3d_checkerboard_;
	GLuint vbo_3d_, vao_3d_, ebo_3d_, num_elements_3d_;
	GLuint vbo_2d_, vao_2d_, ebo_2d_, num_elements_2d_;
	GLuint vbo_render_, vao_render_, ebo_render_, num_elements_render_;
	GLuint fb_comp_0_, fb_comp_1_, fb_comp_damp_;
	GLuint tex_comp_wave_0_, tex_comp_wave_1_;
	GLuint tex_comp_damp_;
	GLuint tex_comp_damp_dynamic_, tex_comp_damp_static_;
	std::vector<float> palette_;
	GLuint tex_palette_;
	Shader shdr_step_, shdr_3d_, shdr_3d_dbg_, shdr_2d_, shdr_2d_dbg_, shdr_damp_;
	//Hang on to data for resets
	std::vector<float> tex_wave_data_, tex_damp_data_;
};

#endif