#pragma once
#include "Common.h"
#include "Python.h"

class PyLinkedColor;
class UIDrawable; // forward declare for pointer

typedef struct {
    std::weak_ptr<UIDrawable> parent; // lifetime management: parent must still exist
    int index; // specific to the parent class, which color is it?
    sf::Color(*getter)();
    void(*setter)(sf::Color);
} _PyLinkedColorData;

typedef struct {
    PyObject_HEAD
    _PyLinkedColorData data;
} PyLinkedColorObject;

class PyLinkedColor
{
private:
    _PyLinkedColorData data;
    PyColor(_PyColorData); // private constructor / for operations transferring between C++ and Python

public:
    PyLinkedColor(sf::Color (*)(), void (*)(sf::Color), std::weak_ptr<UIDrawable>, int);
    void set(sf::Color);  // change target value, behavior determined by the mode
    sf::Color get();      // retrieve target value, behavior determined by the mode
    PyObject* pyParent(); // UIDrawable derived parent object or None
    std::string field();  // interpret the index as a field's name on UIDrawable
    bool alive();         // true if SELF_OWNED or parent still exists
    PyObject* pyObject();
    static PyLinkedColor fromPy(PyObject*);
    static PyLinkedColor fromPy(PyLinkedColorObject*);
    static PyObject* repr(PyObject*);
    static Py_hash_t hash(PyObject*);
    static int init(PyLinkedColorObject*, PyObject*, PyObject*);
    static PyObject* pynew(PyTypeObject* type, PyObject* args=NULL, PyObject* kwds=NULL);
    static PyObject* get_member(PyObject*, void*);
    static int set_member(PyObject*, PyObject*, void*);
    static PyGetSetDef getsetters[];
};

namespace mcrfpydef {
    static PyTypeObject PyLinkedColorType = {
        .tp_name = "mcrfpy.LinkedColor",
        .tp_basicsize = sizeof(PyLinkedColorObject),
        .tp_itemsize = 0,
        .tp_repr = PyLinkedColor::repr,
        .tp_hash = PyLinkedColor::hash,
        .tp_flags = Py_TPFLAGS_DEFAULT,
        .tp_doc = PyDoc_STR("SFML Color Object - Linked to UIDrawable Field"),
        .tp_getset = PyLinkedColor::getsetters,
        .tp_init = (initproc)PyLinkedColor::init,
        .tp_new = PyLinkedColor::pynew,
    };
}
