#pragma once
#include "ui-mousectrl.hh"


/*= UI UTILITIES =============================================================*/

namespace ImGui {

	// Disable next ImGui controls
	void PushDisabled( ) noexcept;
	// Re-enable ImGui buttons
	void PopDisabled( ) noexcept;

	/*--------------------------------------------------------------------*/

	// Display a menu item with a checkbox
	bool MenuItemCheckbox(
			char const* name ,
			bool* checked ) noexcept;

	/*--------------------------------------------------------------------*/

	// Display a separator for the toolbar
	void ToolbarSeparator( ) noexcept;

	// Display a toolbar button
	bool ToolbarButton(
			char const* const string ,
			ImVec2 const& size ,
			char const* const tooltip = nullptr ,
			bool enabled = true ) noexcept;

	/*--------------------------------------------------------------------*/

	uint32_t ColorHSVAToU32(
			float hue ,
			float saturation ,
			float value ,
			float alpha ) noexcept;

	/*--------------------------------------------------------------------*/

	/* "User" scrollbar
	 *
	 * Code ripped from ImGui and modified so it can be used in other
	 * circumstances.
	 *
	 * Parameters:
	 *	horizontal	Horizontal bar if true, vertical bar if false
	 *	total		Total size of the scrolled area
	 *	display		Size of the displayed area
	 *	pos		Pointer to the position, will be updated when
	 *			scrolled
	 *	topLeft		Top-left corner of the scroll bar
	 *	length		Width of the scrollbar (if horizontal)
	 *			Height of the scrollbar (if vertical)
	 *	name		Name of the widget; if NULL, #UserScrollX will
	 *			be used by default for horizontal scrollbars,
	 *			or #UserScrollY for vertical scrollbars
	 */
	bool UserScrollbar(
			bool horizontal ,
			float total ,
			float display ,
			float* pos ,
			ImVec2 topLeft ,
			float length ,
			char const* name = nullptr ) noexcept;

} // namespace ImGui

/*----------------------------------------------------------------------------*/

#define GL_CHECK( FAIL ) \
	do { \
		auto err_( glGetError( ) ); \
		if ( err_ != GL_NO_ERROR ) FAIL; \
	} while ( 0 )

#define GL_ASSERT( ) \
	GL_CHECK({ \
		fprintf( stderr , "GL error %x in %s:%d\n" , \
				err_ , __FILE__ , __LINE__ ); \
		abort( ); \
	})


/*= CAMERA ===================================================================*/

struct T_Camera;

struct T_CameraMouseControl : public A_MouseCtrl
{
	T_Camera& camera;

	explicit T_CameraMouseControl( T_Camera& cam ) : camera( cam ) {}

	void handleDragAndDrop(
			ImVec2 const& move ,
			T_KbdMods modifiers ,
			T_MouseButtons buttons ) noexcept override;
	void handleWheel(
			float wheel ,
			T_KbdMods modifiers ,
			T_MouseButtons buttons ) noexcept override;
};

enum class E_CameraChange {
	FOV ,
	MATRIX
};
using T_CameraChanges = T_Flags< E_CameraChange >;

T_CameraChanges CameraUI( T_Camera& camera ) noexcept;