// qmatrix4x4.sip generated by MetaSIP on Fri Apr 16 11:32:08 2010
//
// This file is part of the QtGui Python extension module.
//
// Copyright (c) 2010 Riverbank Computing Limited <info@riverbankcomputing.com>
// 
// This file is part of PyQt.
// 
// This file may be used under the terms of the GNU General Public
// License versions 2.0 or 3.0 as published by the Free Software
// Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
// included in the packaging of this file.  Alternatively you may (at
// your option) use any later version of the GNU General Public
// License if such license has been publicly approved by Riverbank
// Computing Limited (or its successors, if any) and the KDE Free Qt
// Foundation. In addition, as a special exception, Riverbank gives you
// certain additional rights. These rights are described in the Riverbank
// GPL Exception version 1.1, which can be found in the file
// GPL_EXCEPTION.txt in this package.
// 
// Please review the following information to ensure GNU General
// Public Licensing requirements will be met:
// http://trolltech.com/products/qt/licenses/licensing/opensource/. If
// you are unsure which license is appropriate for your use, please
// review the following information:
// http://trolltech.com/products/qt/licenses/licensing/licensingoverview
// or contact the sales department at sales@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.


%If (Qt_4_6_0 -)
%ModuleCode
#include <qmatrix4x4.h>
%End
%End

%If (Qt_4_6_0 -)

class QMatrix4x4
{

%TypeHeaderCode
#include <qmatrix4x4.h>
%End

%PickleCode
    qreal data[16];
    
    // We want the data in row-major order.
    sipCpp->copyDataTo(data);
    
    sipRes = Py_BuildValue((char *)"dddddddddddddddd",
            data[0], data[1], data[2], data[3],
            data[4], data[5], data[6], data[7],
            data[8], data[9], data[10], data[11],
            data[12], data[13], data[14], data[15]);
%End

public:
    QMatrix4x4();
    explicit QMatrix4x4(SIP_PYOBJECT /DocType="sequence-of-float"/) [(const qreal *values /DocType="sequence-of-float"/)];
%MethodCode
        qreal values[16];
        
        if ((sipError = qtgui_matrixDataFromSequence(a0, 16, values)) == sipErrorNone)
            sipCpp = new QMatrix4x4(values);
%End

    QMatrix4x4(qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal, qreal);
    QMatrix4x4(const QTransform &);
    QMatrix4x4(const QMatrix &);
    SIP_PYOBJECT __repr__() const /DocType="str"/;
%MethodCode
        bool bad = false;
        int i;
        PyObject *m[16];
        qreal data[16];
        
        // The raw data is in column-major order but we want row-major order.
        sipCpp->copyDataTo(data);
        
        for (i = 0; i < 16; ++i)
        {
            m[i] = PyFloat_FromDouble(data[i]);
        
            if (!m[i])
                bad = true;
        }
        
        if (!bad)
        {
        #if PY_MAJOR_VERSION >= 3
            sipRes = PyUnicode_FromFormat("PyQt4.QtGui.QMatrix4x4("
                    "%R, %R, %R, %R, "
                    "%R, %R, %R, %R, "
                    "%R, %R, %R, %R, "
                    "%R, %R, %R, %R)",
                    m[0], m[1], m[2], m[3],
                    m[4], m[5], m[6], m[7],
                    m[8], m[9], m[10], m[11],
                    m[12], m[13], m[14], m[15]);
        #else
            sipRes = PyString_FromString("PyQt4.QtGui.QMatrix4x4(");
        
            for (i = 0; i < 16; ++i)
            {
                if (i != 0)
                    PyString_ConcatAndDel(&sipRes, PyString_FromString(", "));
        
                PyString_ConcatAndDel(&sipRes, PyObject_Repr(m[i]));
            }
        
            PyString_ConcatAndDel(&sipRes, PyString_FromString(")"));
        #endif
        }
        
        for (i = 0; i < 16; ++i)
            Py_XDECREF(m[i]);
%End

    qreal determinant() const;
    QMatrix4x4 inverted(bool *invertible = 0) const;
    QMatrix4x4 transposed() const;
    QMatrix3x3 normalMatrix() const;
    void scale(const QVector3D &);
    void scale(qreal, qreal);
    void scale(qreal, qreal, qreal);
    void scale(qreal);
    void translate(const QVector3D &);
    void translate(qreal, qreal);
    void translate(qreal, qreal, qreal);
    void rotate(qreal, const QVector3D &);
    void rotate(qreal, qreal, qreal, qreal z = 0.0);
    void rotate(const QQuaternion &);
    void ortho(const QRect &);
    void ortho(const QRectF &);
    void ortho(qreal, qreal, qreal, qreal, qreal, qreal);
    void frustum(qreal, qreal, qreal, qreal, qreal, qreal);
    void perspective(qreal, qreal, qreal, qreal);
    void lookAt(const QVector3D &, const QVector3D &, const QVector3D &);
    void flipCoordinates();
    SIP_PYLIST copyDataTo() const /DocType="list-of-float"/;
%MethodCode
        qreal values[16];
        
        sipCpp->copyDataTo(values);
        sipError = qtgui_matrixDataAsList(16, values, &sipRes);
%End

    QMatrix toAffine() const;
    QTransform toTransform() const;
    QTransform toTransform(qreal) const;
    QRect mapRect(const QRect &) const;
    QRectF mapRect(const QRectF &) const;
    SIP_PYLIST data() /DocType="list-of-float"/;
%MethodCode
        sipError = qtgui_matrixDataAsList(16, sipCpp->constData(), &sipRes);
%End

    void optimize();
    SIP_PYOBJECT __getitem__(SIP_PYOBJECT) const;
%MethodCode
        int row, column;
        
        if ((sipError = qtgui_matrixParseIndex(a0, 4, 4, &row, &column)) == sipErrorNone)
        {
            sipRes = PyFloat_FromDouble(sipCpp->operator()(row, column));
        
            if (!sipRes)
                sipError = sipErrorFail;
        }
%End

    void __setitem__(SIP_PYOBJECT, qreal);
%MethodCode
        int row, column;
        
        if ((sipError = qtgui_matrixParseIndex(a0, 4, 4, &row, &column)) == sipErrorNone)
            sipCpp->operator()(row, column) = a1;
%End

    QVector4D column(int) const;
    void setColumn(int, const QVector4D &);
    QVector4D row(int) const;
    void setRow(int, const QVector4D &);
    bool isIdentity() const;
    void setToIdentity();
    void fill(qreal);
    QMatrix4x4 &operator+=(const QMatrix4x4 &);
    QMatrix4x4 &operator-=(const QMatrix4x4 &);
    QMatrix4x4 &operator*=(const QMatrix4x4 &);
    QMatrix4x4 &operator*=(qreal);
    QMatrix4x4 &operator/=(qreal);
    bool operator==(const QMatrix4x4 &) const;
    bool operator!=(const QMatrix4x4 &) const;
    QPoint map(const QPoint &) const;
    QPointF map(const QPointF &) const;
    QVector3D map(const QVector3D &) const;
    QVector3D mapVector(const QVector3D &) const;
    QVector4D map(const QVector4D &) const;
};

%End
%If (Qt_4_6_0 -)
QMatrix4x4 operator/(const QMatrix4x4 &, qreal);
%End
%If (Qt_4_6_0 -)
QMatrix4x4 operator+(const QMatrix4x4 &, const QMatrix4x4 &);
%End
%If (Qt_4_6_0 -)
QMatrix4x4 operator-(const QMatrix4x4 &, const QMatrix4x4 &);
%End
%If (Qt_4_6_0 -)
QMatrix4x4 operator*(const QMatrix4x4 &, const QMatrix4x4 &);
%End
%If (Qt_4_6_0 -)
QVector3D operator*(const QVector3D &, const QMatrix4x4 &);
%End
%If (Qt_4_6_0 -)
QVector3D operator*(const QMatrix4x4 &, const QVector3D &);
%End
%If (Qt_4_6_0 -)
QVector4D operator*(const QVector4D &, const QMatrix4x4 &);
%End
%If (Qt_4_6_0 -)
QVector4D operator*(const QMatrix4x4 &, const QVector4D &);
%End
%If (Qt_4_6_0 -)
QPoint operator*(const QPoint &, const QMatrix4x4 &);
%End
%If (Qt_4_6_0 -)
QPointF operator*(const QPointF &, const QMatrix4x4 &);
%End
%If (Qt_4_6_0 -)
QPoint operator*(const QMatrix4x4 &, const QPoint &);
%End
%If (Qt_4_6_0 -)
QPointF operator*(const QMatrix4x4 &, const QPointF &);
%End
%If (Qt_4_6_0 -)
QMatrix4x4 operator-(const QMatrix4x4 &);
%End
%If (Qt_4_6_0 -)
QMatrix4x4 operator*(qreal, const QMatrix4x4 &);
%End
%If (Qt_4_6_0 -)
QMatrix4x4 operator*(const QMatrix4x4 &, qreal);
%End
%If (Qt_4_6_0 -)
bool qFuzzyCompare(const QMatrix4x4 &, const QMatrix4x4 &);
%End
%If (Qt_4_6_0 -)
QDataStream &operator<<(QDataStream &, const QMatrix4x4 & /Constrained/);
%End
%If (Qt_4_6_0 -)
QDataStream &operator>>(QDataStream &, QMatrix4x4 & /Constrained/);
%End

%ModuleHeaderCode
// Helpers for the matrix classes.
sipErrorState qtgui_matrixParseIndex(PyObject *tup, int nr_rows,
        int nr_columns, int *row, int *column);
sipErrorState qtgui_matrixDataFromSequence(PyObject *seq, int nr_values,
        qreal *values);
sipErrorState qtgui_matrixDataAsList(int nr_values, const qreal *values,
        PyObject **list);
%End

%ModuleCode
// Convert a Python object to a row and column.
sipErrorState qtgui_matrixParseIndex(PyObject *tup, int nr_rows,
        int nr_columns, int *row, int *column)
{
    sipErrorState es = sipErrorContinue;

    if (PyTuple_Check(tup) && PyArg_ParseTuple(tup, "ii", row, column))
        if (*row >= 0 && *row < nr_rows && *column >= 0 && *column < nr_columns)
            es = sipErrorNone;

    if (es == sipErrorContinue)
        PyErr_Format(PyExc_IndexError, "an index must be a row in the range 0 to %d and a column in the range 0 to %d", nr_rows - 1, nr_columns - 1);

    return es;
}


// Convert a Python object to an array of qreals.
sipErrorState qtgui_matrixDataFromSequence(PyObject *seq, int nr_values,
        qreal *values)
{
    sipErrorState es;

    if (PySequence_Size(seq) == nr_values)
    {
        es = sipErrorNone;

        for (int i = 0; i < nr_values; ++i)
        {
            PyObject *value = PySequence_GetItem(seq, i);

            if (!value)
            {
                es = sipErrorFail;
                break;
            }

            PyErr_Clear();

            double d = PyFloat_AsDouble(value);

            if (PyErr_Occurred())
            {
                Py_DECREF(value);
                es = sipErrorContinue;
                break;
            }

            Py_DECREF(value);

            *values++ = d;
        }
    }
    else
    {
        es = sipErrorContinue;
    }

    if (es == sipErrorContinue)
        PyErr_Format(PyExc_TypeError, "a sequence of %d floats is expected",
                nr_values);

    return es;
}


// Convert an array of qreals to a Python list.
sipErrorState qtgui_matrixDataAsList(int nr_values, const qreal *values,
        PyObject **list)
{
    PyObject *l = PyList_New(nr_values);

    if (!l)
        return sipErrorFail;

    for (int i = 0; i < nr_values; ++i)
    {
        PyObject *value = PyFloat_FromDouble(*values++);

        if (!value)
        {
            Py_DECREF(l);
            return sipErrorFail;
        }

        PyList_SET_ITEM(l, i, value);
    }

    *list = l;

    return sipErrorNone;
}
%End
