#pragma once

#include "WLSurface.hpp"
#include "../../helpers/math/Math.hpp"
#include "focusable/Focusable.hpp"

#include <cstdint>

namespace Desktop::View {
    enum eViewType : uint8_t {
        VIEW_TYPE_WINDOW = 0,
        VIEW_TYPE_SUBSURFACE,
        VIEW_TYPE_POPUP,
        VIEW_TYPE_LAYER_SURFACE,
        VIEW_TYPE_LOCK_SCREEN,
    };

    class IView : public virtual IFocusable {
      public:
        virtual ~IView();

        virtual SP<Desktop::View::CWLSurface> wlSurface() const;
        virtual SP<CWLSurfaceResource>        resource() const;
        virtual eViewType                     type() const              = 0;
        virtual bool                          mapped() const            = 0;
        virtual bool                          desktopComponent() const  = 0;
        virtual std::optional<CBox>           logicalBox() const        = 0;
        virtual std::optional<CBox>           surfaceLogicalBox() const = 0;

      protected:
        IView(SP<Desktop::View::CWLSurface> pWlSurface);

        void                          initView(WP<IView> self, eViewType type);

        SP<Desktop::View::CWLSurface> m_wlSurface;

      private:
        WP<IView> m_self;
        eViewType m_type        = VIEW_TYPE_WINDOW;
        uintptr_t m_address     = 0;
        bool      m_initialized = false;
    };
};
