// qsgmaterial.sip generated by MetaSIP
//
// This file is part of the QtQuick Python extension module.
//
// Copyright (c) 2024 Riverbank Computing Limited <info@riverbankcomputing.com>
// 
// This file is part of PyQt5.
// 
// This file may be used under the terms of the GNU General Public License
// version 3.0 as published by the Free Software Foundation and appearing in
// the file LICENSE included in the packaging of this file.  Please review the
// following information to ensure the GNU General Public License version 3.0
// requirements will be met: http://www.gnu.org/copyleft/gpl.html.
// 
// If you do not wish to use this file under the terms of the GPL version 3.0
// then you may purchase a commercial license.  For more information contact
// info@riverbankcomputing.com.
// 
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.


class QSGMaterialShader /Supertype=sip.wrapper/
{
%TypeHeaderCode
#include <qsgmaterial.h>
%End

public:
    class RenderState
    {
%TypeHeaderCode
#include <qsgmaterial.h>
%End

    public:
        enum DirtyState
        {
            DirtyMatrix,
            DirtyOpacity,
%If (Qt_5_8_0 -)
            DirtyCachedMaterialData,
%End
%If (Qt_5_8_0 -)
            DirtyAll,
%End
        };

        typedef QFlags<QSGMaterialShader::RenderState::DirtyState> DirtyStates;
        QSGMaterialShader::RenderState::DirtyStates dirtyStates() const;
        bool isMatrixDirty() const;
        bool isOpacityDirty() const;
        float opacity() const;
        QMatrix4x4 combinedMatrix() const;
        QMatrix4x4 modelViewMatrix() const;
        QRect viewportRect() const;
        QRect deviceRect() const;
        float determinant() const;
%If (PyQt_OpenGL)
        QOpenGLContext *context() const;
%End
%If (Qt_5_1_0 -)
        QMatrix4x4 projectionMatrix() const;
%End
%If (Qt_5_1_0 -)
        float devicePixelRatio() const;
%End
%If (Qt_5_8_0 -)
        bool isCachedMaterialDataDirty() const;
%End
    };

    QSGMaterialShader();
    virtual ~QSGMaterialShader();
    virtual void activate();
    virtual void deactivate();
    virtual void updateState(const QSGMaterialShader::RenderState &state, QSGMaterial *newMaterial, QSGMaterial *oldMaterial);
    virtual SIP_PYOBJECT attributeNames() const = 0 /TypeHint="List[str]"/ [const char * const * ()];
%MethodCode
        const char * const *names = sipCpp->attributeNames();
        
        Py_ssize_t nr_names = 0;
        
        if (names)
            while (names[nr_names])
                ++nr_names;
            
        sipRes = PyList_New(nr_names);
            
        if (!sipRes)
            sipIsErr = 1;
        else
            for (Py_ssize_t i = 0; i < nr_names; ++i)
            {
                const char *name = names[i];
                PyObject *el;
        
        #if PY_MAJOR_VERSION >= 3
                el = PyUnicode_DecodeASCII(name, strlen(name), 0);
        #else
                el = PyString_FromString(name);
        #endif
                
                if (!el)
                {
                    Py_DECREF(sipRes);
                    sipIsErr = 1;
                    break;
                }
        
                PyList_SetItem(sipRes, i, el);
            }
%End

%VirtualCatcherCode
        PyObject *names = sipCallMethod(&sipIsErr, sipMethod, "");
        
        if (names)
        {
            sipRes = qtquick_anc_get_attr_names(sipPySelf, sipMethod, names);
            
            if (!sipRes)
                sipIsErr = 1;
            
            Py_DECREF(names);
        }
%End

%If (PyQt_OpenGL)
    QOpenGLShaderProgram *program();
%End

protected:
%If (PyQt_OpenGL)
    virtual void compile();
%End
    virtual void initialize();
%If (Qt_5_2_0 -)
%If (PyQt_OpenGL)
    virtual const char *vertexShader() const;
%End
%End
%If (- Qt_5_2_0)
%If (PyQt_OpenGL)
    virtual const char *vertexShader() const = 0;
%End
%End
%If (Qt_5_2_0 -)
%If (PyQt_OpenGL)
    virtual const char *fragmentShader() const;
%End
%End
%If (- Qt_5_2_0)
%If (PyQt_OpenGL)
    virtual const char *fragmentShader() const = 0;
%End
%End
%If (Qt_5_2_0 -)
%If (PyQt_OpenGL)
    void setShaderSourceFile(QOpenGLShader::ShaderType type, const QString &sourceFile);
%End
%End
%If (Qt_5_2_0 -)
%If (PyQt_OpenGL)
    void setShaderSourceFiles(QOpenGLShader::ShaderType type, const QStringList &sourceFiles);
%End
%End

private:
    QSGMaterialShader(const QSGMaterialShader &);
};

struct QSGMaterialType
{
%TypeHeaderCode
#include <qsgmaterial.h>
%End
};

class QSGMaterial /Supertype=sip.wrapper/
{
%TypeHeaderCode
#include <qsgmaterial.h>
%End

public:
    enum Flag
    {
        Blending,
        RequiresDeterminant,
        RequiresFullMatrixExceptTranslate,
        RequiresFullMatrix,
%If (Qt_5_2_0 -)
        CustomCompileStep,
%End
%If (Qt_5_14_0 -)
        SupportsRhiShader,
%End
%If (Qt_5_14_0 -)
        RhiShaderWanted,
%End
    };

    typedef QFlags<QSGMaterial::Flag> Flags;
    QSGMaterial();
    virtual ~QSGMaterial();
    virtual QSGMaterialType *type() const = 0;
    virtual QSGMaterialShader *createShader() const = 0 /Factory/;
    virtual int compare(const QSGMaterial *other) const;
    QSGMaterial::Flags flags() const;
    void setFlag(QSGMaterial::Flags flags, bool enabled = true);

private:
    QSGMaterial(const QSGMaterial &);
};

QFlags<QSGMaterial::Flag> operator|(QSGMaterial::Flag f1, QFlags<QSGMaterial::Flag> f2);
QFlags<QSGMaterialShader::RenderState::DirtyState> operator|(QSGMaterialShader::RenderState::DirtyState f1, QFlags<QSGMaterialShader::RenderState::DirtyState> f2);

%ModuleCode
// Release any attribute names to the heap.
static void qtquick_anc_release(char **attr_names)
{
    if (attr_names)
    {
        for (int i = 0; attr_names[i]; ++i)
            delete[] attr_names[i];

        delete[] attr_names;
    }
}


// The destructor for the attribute names PyCapsule.
static void qtquick_anc_destructor(PyObject *cap)
{
    qtquick_anc_release(
            reinterpret_cast<char **>(PyCapsule_GetPointer(cap, NULL)));
}


// Get the attribute names or 0 if there was an error.
static char **qtquick_anc_get_attr_names(sipSimpleWrapper *pySelf, PyObject *method, PyObject *attr_names_obj)
{
    // Dispose of any existing names.
    Py_XDECREF(sipGetUserObject(pySelf));
    sipSetUserObject(pySelf, NULL);

    // Convert the new names.
    if (!PyList_Check(attr_names_obj))
    {
        sipBadCatcherResult(method);
        return 0;
    }

    char **names = new char *[PyList_Size(attr_names_obj) + 1];

    for (Py_ssize_t i = 0; i < PyList_Size(attr_names_obj); ++i)
    {
        char *name;
        PyObject *el = PyList_GetItem(attr_names_obj, i);

#if PY_MAJOR_VERSION >= 3
        PyObject *name_obj = PyUnicode_AsASCIIString(el);

        name = (name_obj ? PyBytes_AsString(name_obj) : 0);
#else
        name = PyString_AsString(el);
#endif

        if (!name)
        {
            names[i] = 0;
            qtquick_anc_release(names);

            sipBadCatcherResult(method);
            return 0;
        }

        char *name_copy = new char[strlen(name) + 1];
        strcpy(name_copy, name);
        names[i] = name_copy;

#if PY_MAJOR_VERSION >= 3
        Py_DECREF(name_obj);
#endif
    }

    names[PyList_Size(attr_names_obj)] = 0;

    sipSetUserObject(pySelf, PyCapsule_New(names, NULL, qtquick_anc_destructor));

    if (!sipGetUserObject(pySelf))
    {
        qtquick_anc_release(names);
        return 0;
    }

    return names;
}
%End
