#pragma once

#include "ehs/EHS.h"
#include "ehs/Str.h"
#include "ehs/Vec2.h"
#include "ehs/Rect.h"
#include "ehs/io/hid/Input.h"

namespace ehs
{
	enum class WindowState : UInt_8
	{
		NONE,
		FULLSCREEN
	};

	enum class CursorImg : UInt_8
	{
		DEFAULT,
		I_BEAM
	};

    class BaseWindow
    {
	protected:
		bool created;
		bool focused;
        Vec2_s32 cursorPos;
		bool cursorVisible;
		bool cursorConstrained;
		WindowState state;
    	InputHandler ih;

    public:
		virtual ~BaseWindow() = default;

		BaseWindow();

		BaseWindow(const BaseWindow& win);

		BaseWindow& operator=(const BaseWindow& win);

        virtual void Create_32(const Str_32& title, const Vec2_s32& pos, const Vec2_u32 scale) = 0;

        virtual void Create_16(const Str_16& title, const Vec2_s32& pos, const Vec2_u32 scale) = 0;

        virtual void Create_8(const Str_8& title, const Vec2_s32& pos, const Vec2_u32 scale) = 0;

		virtual void OnCreated() = 0;

		virtual void Close() = 0;

		virtual void Show() = 0;

		virtual void Hide() = 0;

		bool IsCreated() const;

		virtual bool Poll();

		bool HasFocus() const;

    	void EnableResizing(const bool enable);

    	bool IsResizable() const;

		/// Gets the cursors position on the desktop in pixels.
		/// @param [in] relative Whether the position should be relative to the windows client.
		/// @returns The current value.
        Vec2_s32 GetCursorPos() const;

		/// Shows the cursor on the window.
		/// @param [in] toggle The new status.
		virtual void ShowCursor(bool toggle) = 0;

		/// Checks whether the cursor is shown.
		/// @returns The current status.
		bool IsCursorVisible() const;

		virtual void ConstrainCursor(const bool constrain) = 0;

		bool IsCursorConstrained() const;

        WindowState GetState() const;

    	const InputHandler* GetInputHandler() const;

		virtual void SetTitle_32(const Str_32& newTitle) = 0;

		virtual Str_32 GetTitle_32() const = 0;

		virtual void SetTitle_16(const Str_16& newTitle) = 0;

		virtual Str_16 GetTitle_16() const = 0;

		virtual void SetTitle_8(const Str_8& newTitle) = 0;

		virtual Str_8 GetTitle_8() const = 0;

        virtual void SetPos(const Vec2_s32& newPos) = 0;

        virtual Vec2_s32 GetPos() const = 0;

        virtual void SetScale(const Vec2_u32& newScale) = 0;

        virtual Vec2_u32 GetScale() const = 0;

    	virtual Serializer<UInt_64> GetClipboard() = 0;

    	virtual void SetClipboard(Serializer<UInt_64> data) = 0;

    	virtual void SetCursorImg(const CursorImg img) = 0;
    };
}