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

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

typedef struct {
    sf::Color* target; // color target to set/get
    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);
} _PyColorData;

typedef struct {
    PyObject_HEAD
    _PyColorData data;
} PyColorObject;

class PyColor
{
private:
    _PyColorData data;
    static const int SELF_OWNED = -1;
    static const int BORROWED = -2;
    PyColor(_PyColorData); // private constructor / for operations transferring between C++ and Python

public:
    PyColor(sf::Color* target, std::weak_ptr<UIDrawable> parent, int index); // linked constructor
    PyColor(sf::Color target); // simple color container
    PyColor(sf::Color (*)(), void (*)(sf::Color), std::weak_ptr<UIDrawable>, int);
    ~PyColor();
    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
    std::string mode();   // "value" for SELF_OWNED, "linked" for pointer, and "passthrough" for callbacks
    bool alive();         // true if SELF_OWNED or parent still exists
    PyObject* pyObject();
    static PyColor fromPy(PyObject*);
    static PyColor fromPy(PyColorObject*);
    static PyObject* repr(PyObject*);
    static Py_hash_t hash(PyObject*);
    static int init(PyColorObject*, 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[];
    /*static PyGetSetDef getsetters[] = {
        {"r", (getter)PyColor::get_member, (setter)PyColor::set_member, "Red component",   (void*)0},
        {"g", (getter)PyColor::get_member, (setter)PyColor::set_member, "Green component", (void*)1},
        {"b", (getter)PyColor::get_member, (setter)PyColor::set_member, "Blue component",  (void*)2},
        {"a", (getter)PyColor::get_member, (setter)PyColor::set_member, "Alpha component", (void*)3},
        {NULL}
    };*/
};

    

//     static PyTypeObject PyColorType = {
//        //PyVarObject_HEAD_INIT(NULL, 0)
//        .tp_name = "mcrfpy.Color",
//        .tp_basicsize = sizeof(PyColorObject),
//        .tp_itemsize = 0,
//        .tp_dealloc = (destructor)[](PyObject* self)
//        {
//            PyColorObject* obj = (PyColorObject*)self;
//            obj->data.reset(); 
//            Py_TYPE(self)->tp_free(self); 
//        },
//        //.tp_repr = (reprfunc)PyUIFrame_repr,
//        //.tp_hash = NULL,
//        //.tp_iter
//        //.tp_iternext
//        .tp_flags = Py_TPFLAGS_DEFAULT,
//        .tp_doc = PyDoc_STR("SFML Color object (RGBA)"),
//        //.tp_methods = PyUIFrame_methods,
//        //.tp_members = PyColor_members,
//        .tp_getset = PyColor_getsetters,
//        //.tp_base = NULL,
//        //.tp_init = (initproc)PyUIFrame_init,
//        .tp_new = [](PyTypeObject* type, PyObject* args, PyObject* kwds) -> PyObject*
//        { 
//            PyColorObject* self = (PyColorObject*)type->tp_alloc(type, 0);
//            if (self) self->data = std::make_shared<sf::Color>();
//            return (PyObject*)self;
//        }
//    };

namespace mcrfpydef {
    static PyTypeObject PyColorType = {
        .tp_name = "mcrfpy.Color",
        .tp_basicsize = sizeof(PyColorObject),
        .tp_itemsize = 0,
        .tp_repr = PyColor::repr,
        .tp_hash = PyColor::hash,
        .tp_flags = Py_TPFLAGS_DEFAULT,
        .tp_doc = PyDoc_STR("SFML Color Object"),
        .tp_getset = PyColor::getsetters,
        .tp_init = (initproc)PyColor::init,
        .tp_new = PyColor::pynew,
    };
}
