#pragma once

#include "../view.hpp"

#include <ftl/utility/gltexture.hpp>

#include "../widgets/window.hpp"
#include "../widgets/soundctrl.hpp"
#include "../widgets/imageview.hpp"
#include "../widgets/popupbutton.hpp"
#include "../modules/camera_tools.hpp"

namespace ftl {
namespace gui2 {

class Camera;
class MediaPanel;
class CameraView;


class ToolPanel : public FixedWindow {
public:
	ToolPanel(nanogui::Widget *parent, Camera* ctrl, CameraView* view);
	virtual ~ToolPanel();

	void setAvailable(const std::unordered_set<ftl::gui2::CameraTools> &);
	void setEnabled(const std::unordered_set<ftl::gui2::CameraTools> &);
	void enable(const std::unordered_set<ftl::gui2::CameraTools> &);
	void disable(const std::unordered_set<ftl::gui2::CameraTools> &);

	void draw(NVGcontext *ctx) override;

	/** add button to position. */
	nanogui::Button* addButton(int position = -1);

	inline ftl::gui2::CameraTools activeTool() const { return active_; }
	void setTool(ftl::gui2::CameraTools tool);

	inline void addCallback(const std::function<bool(ftl::gui2::CameraTools)> &cb) { callbacks_.push_back(cb); }

private:
	Camera* ctrl_;
	CameraView* view_;
	nanogui::Widget *container_;
	std::unordered_map<ftl::gui2::CameraTools, nanogui::Button*> buttons_;
	ftl::gui2::CameraTools active_ = ftl::gui2::CameraTools::NONE;

	std::list<std::function<bool(ftl::gui2::CameraTools)>> callbacks_;

	void _addButton(ftl::gui2::CameraTools, int icon, const std::string &tooltip);
	void _addButton(ftl::gui2::PopupButton *parent, ftl::gui2::CameraTools, const std::string &label);
	ftl::gui2::PopupButton *_addButton(std::unordered_set<ftl::gui2::CameraTools> tools, int icon, const std::string &tooltip);

public:
	EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};

class CameraView : public View {
public:
	CameraView(Screen* parent, Camera* ctrl);
	virtual ~CameraView();

	virtual void draw(NVGcontext* ctx) override;
	virtual void performLayout(NVGcontext* ctx) override;
	virtual bool mouseButtonEvent(const Eigen::Vector2i &p, int button, bool down, int modifiers) override;
	virtual bool mouseMotionEvent(const Eigen::Vector2i &p, const Eigen::Vector2i &rel, int button, int modifiers) override;

	void refresh();
	void setZoom(bool enable);
	void setPan(bool enable);

	void setStereo(bool v);

protected:
	bool enable_zoom_;
	bool enable_pan_;
	Camera* ctrl_;
	MediaPanel* panel_;
	ToolPanel* tools_;
	FTLImageView* imview_;
	nanogui::Window *context_menu_;

private:
	StereoImageView* stereoim_;

public:
	EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};

}
}