#pragma once

#include <Either.h>
#include <UIMLView.h>
#include <VecN.h>

#include "NetworkAPIProcessor.h"

class InventoryElement : public Framework::UIMLElement
{
public:
    InventoryElement();
    //! prüft, ob dieses UIML Element für ein bestimmtes xml Element zuständig
    //! ist
    bool isApplicableFor(Framework::XML::Element& element) override;
    //! erstellt eine neue Zeichnung zu einem gegebenen xml Element
    Framework::Zeichnung* parseElement(Framework::XML::Element& element,
        Framework::UIMLContainer& generalFactory) override;
    bool updateElement(Framework::XML::Element& element,
        Framework::Zeichnung& z,
        Framework::UIMLContainer& generalFactory) override;
    //! wendet die layout parameter zu einer Zeichnung an
    void layout(Framework::XML::Element& element,
        Framework::Zeichnung& z,
        int pWidth,
        int pHeight,
        Framework::UIMLContainer& generalLayouter) override;
};

struct SlotInfo
{
    int id;
    int itemCount;
    float hp;
    float maxHp;
    float durability;
    float maxDurability;
    Framework::Text name;
    Framework::Bild* zItem;

    void render(int x,
        int y,
        Framework::Bild& rObj,
        bool selected,
        bool lightBackground);
};

class InventoryDragSource
{
public:
    virtual Framework::Either<int, Framework::VecN<int, 4>>
    getInventoryTarget() const = 0;
};

class InventoryView : public Framework::ZeichnungHintergrund,
                      public NetworkAPIProcessor,
                      public InventoryDragSource
{
private:
    int rowSize;
    // entity id or block position
    Framework::Either<int, Framework::VecN<int, 4>> target;
    Framework::Text slotNameFilter;
    Framework::Text id;
    Framework::Array<SlotInfo>* slots;
    Framework::Punkt mausPos;
    int dragStartId;
    int dragStopId;
    int currentTooltipSlot;
    int requestetTooltipSlot;
    int getSlotByLocalPos(Framework::Punkt pos);

public:
    InventoryView(Framework::Text id,
        Framework::Either<int, Framework::VecN<int, 4>> target,
        int rowSize,
        Framework::Text slotNameFilter);
    ~InventoryView();
    void api(char* message) override;
    bool tick(double tickVal) override;
    void render(Framework::Bild& rObj) override;
    void doMausEreignis(Framework::MausEreignis& me, bool userRet) override;
    Framework::Either<int, Framework::VecN<int, 4>>
    getInventoryTarget() const override;
};
