#pragma once

class WVideo {
public:
	int frame_cnt = 0;
	int frame = 0;
	bool interlace = false;

	float speed = 1.0;
	
	Buffer* buff_cols;
	Buffer* buff_indices;

	int width;
	int height;
	int buff_idx;

	Texture* tex;
	Framebuffer* fb;

	double time = 0.0;
	int fps = 15;

	libvlc_instance_t*  m_vlc = nullptr;
	libvlc_media_player_t* m_mp = nullptr;
	libvlc_media_t* m_media = nullptr;

	
	//FBO data
	unsigned m_width = 0;
	unsigned m_height = 0;
	std::mutex m_text_lock;
	GLuint m_tex[3];
	GLuint m_fbo[3];
	size_t m_idx_render = 0;
	size_t m_idx_swap = 1;
	size_t m_idx_display = 2;
	bool m_updated = false;

	
	//SDL context
	// SDL_Window* m_win;
	HGLRC m_ctx;
	HDC m_win;

	
	void stop();

	/// return the texture to be displayed
	GLuint getVideoFrame(bool* out_updated);

	/// this callback will create the surfaces and FBO used by VLC to perform its rendering
	static bool resize(void* data, const libvlc_video_render_cfg_t *cfg,
										 libvlc_video_output_cfg_t *render_cfg);

	// This callback is called during initialisation.
	static bool setup(void** data, const libvlc_video_setup_device_cfg_t *cfg,
										libvlc_video_setup_device_info_t *out);

	// This callback is called to release the texture and FBO created in resize
	static void cleanup(void* data);

	//This callback is called after VLC performs drawing calls
	static void swap(void* data);


	// This callback is called to set the OpenGL context
	static bool make_current(void* data, bool current);

	// This callback is called by VLC to get OpenGL functions.
	static void* get_proc_address(void* /*data*/, const char* current);


	WVideo(std::string_view path);
	static void videoDisplayCallback(void *object, void *picture) {}

	
	std::vector<uint8_t> vid_data;

	void update();

	void pause() {
		if(!this->paused) {
			libvlc_media_player_pause(m_mp);
		}
		this->paused = true;
	}
	
	void play() {
		this->paused = false;
		libvlc_media_player_play(m_mp);
	}

	static void *begin_vlc_rendering(void *data, void **p_pixels);

	static void end_vlc_rendering(void *data, void *id, void *const *p_pixels);

	int         x,y;        // Position
		uint32_t    texW,texH;  // Frame width & height
		uint32_t    w,h;        // Render width & height
		float       scale;      // Render scale;

		std::mutex      mutex;      // Mutex to begin_vlc_rendering texture on drawing
		std::atomic_bool  finished_loading;      // Mutex to begin_vlc_rendering texture on drawing
		std::mutex  finished_loading_mtx;      // Mutex to begin_vlc_rendering texture on drawing
		std::condition_variable  finished_loading_cv;      // Mutex to begin_vlc_rendering texture on drawing
		// Texture2D   texture;    // Here we draw the pixel from vlc
		uint8_t*    buffer;     // Pixel received from vlc
		bool        needUpdate; // Texture is changed, we need to reload
	
	bool paused = false;
};
