// qmap.sip generated by MetaSIP on Sat Dec  8 09:51:33 2012
//
// This file is part of the QtCore Python extension module.
//
// Copyright (c) 2012 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.
// 
// If you are unsure which license is appropriate for your use, please
// 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.


// QMap<TYPE1, TYPE2> is implemented as a Python dictionary.
template<TYPE1, TYPE2>
%MappedType QMap<TYPE1, TYPE2> /DocType="dict-of-TYPE1-TYPE2"/
{
%TypeHeaderCode
#include <qmap.h>
%End

%ConvertFromTypeCode
    // Create the dictionary.
    PyObject *d = PyDict_New();

    if (!d)
        return NULL;

    // Set the dictionary elements.
    QMap<TYPE1, TYPE2>::const_iterator i = sipCpp->constBegin();

    while (i != sipCpp->constEnd())
    {
        TYPE1 *t1 = new TYPE1(i.key());
        TYPE2 *t2 = new TYPE2(i.value());

        PyObject *t1obj = sipConvertFromNewType(t1, sipType_TYPE1, sipTransferObj);
        PyObject *t2obj = sipConvertFromNewType(t2, sipType_TYPE2, sipTransferObj);

        if (t1obj == NULL || t2obj == NULL || PyDict_SetItem(d, t1obj, t2obj) < 0)
        {
            Py_DECREF(d);

            if (t1obj)
            {
                Py_DECREF(t1obj);
            }
            else
            {
                delete t1;
            }

            if (t2obj)
            {
                Py_DECREF(t2obj);
            }
            else
            {
                delete t2;
            }

            return NULL;
        }

        Py_DECREF(t1obj);
        Py_DECREF(t2obj);

        ++i;
    }

    return d;
%End

%ConvertToTypeCode
    PyObject *t1obj, *t2obj;
    SIP_SSIZE_T i = 0;

    // Check the type if that is all that is required.
    if (sipIsErr == NULL)
    {
        if (!PyDict_Check(sipPy))
            return 0;

        while (PyDict_Next(sipPy, &i, &t1obj, &t2obj))
        {
            if (!sipCanConvertToType(t1obj, sipType_TYPE1, SIP_NOT_NONE))
                return 0;

            if (!sipCanConvertToType(t2obj, sipType_TYPE2, SIP_NOT_NONE))
                return 0;
        } 

        return 1;
    }

    QMap<TYPE1, TYPE2> *qm = new QMap<TYPE1, TYPE2>;
 
    while (PyDict_Next(sipPy, &i, &t1obj, &t2obj))
    {
        int state1, state2;

        TYPE1 *t1 = reinterpret_cast<TYPE1 *>(sipConvertToType(t1obj, sipType_TYPE1, sipTransferObj, SIP_NOT_NONE, &state1, sipIsErr));
        TYPE2 *t2 = reinterpret_cast<TYPE2 *>(sipConvertToType(t2obj, sipType_TYPE2, sipTransferObj, SIP_NOT_NONE, &state2, sipIsErr));
 
        if (*sipIsErr)
        {
            sipReleaseType(t1, sipType_TYPE1, state1);
            sipReleaseType(t2, sipType_TYPE2, state2);

            delete qm;
            return 0;
        }

        qm->insert(*t1, *t2);

        sipReleaseType(t1, sipType_TYPE1, state1);
        sipReleaseType(t2, sipType_TYPE2, state2);
    }
 
    *sipCppPtr = qm;
 
    return sipGetState(sipTransferObj);
%End
};
// QMap<int, TYPE> is implemented as a Python dictionary.
template<TYPE>
%MappedType QMap<int, TYPE> /DocType="dict-of-int-TYPE"/
{
%TypeHeaderCode
#include <qmap.h>
%End

%ConvertFromTypeCode
    // Create the dictionary.
    PyObject *d = PyDict_New();

    if (!d)
        return NULL;

    // Set the dictionary elements.
    QMap<int, TYPE>::const_iterator i = sipCpp->constBegin();

    while (i != sipCpp->constEnd())
    {
        TYPE *t = new TYPE(i.value());

        PyObject *kobj = SIPLong_FromLong(i.key());
        PyObject *tobj = sipConvertFromNewType(t, sipType_TYPE, sipTransferObj);

        if (kobj == NULL || tobj == NULL || PyDict_SetItem(d, kobj, tobj) < 0)
        {
            Py_DECREF(d);

            if (kobj)
            {
                Py_DECREF(kobj);
            }

            if (tobj)
            {
                Py_DECREF(tobj);
            }
            else
            {
                delete t;
            }

            return NULL;
        }

        Py_DECREF(kobj);
        Py_DECREF(tobj);

        ++i;
    }

    return d;
%End

%ConvertToTypeCode
    PyObject *kobj, *tobj;
    SIP_SSIZE_T i = 0;

    // Check the type if that is all that is required.
    if (sipIsErr == NULL)
    {
        if (!PyDict_Check(sipPy))
            return 0;

        while (PyDict_Next(sipPy, &i, &kobj, &tobj))
            if (!sipCanConvertToType(tobj, sipType_TYPE, SIP_NOT_NONE))
                return 0;

        return 1;
    }

    QMap<int, TYPE> *qm = new QMap<int, TYPE>;
 
    while (PyDict_Next(sipPy, &i, &kobj, &tobj))
    {
        int state, k = SIPLong_AsLong(kobj);
        TYPE *t = reinterpret_cast<TYPE *>(sipConvertToType(tobj, sipType_TYPE, sipTransferObj, SIP_NOT_NONE, &state, sipIsErr));
 
        if (*sipIsErr)
        {
            sipReleaseType(t, sipType_TYPE, state);

            delete qm;
            return 0;
        }

        qm->insert(k, *t);

        sipReleaseType(t, sipType_TYPE, state);
    }
 
    *sipCppPtr = qm;
 
    return sipGetState(sipTransferObj);
%End
};
// QMultiMap<TYPE1, TYPE2> is implemented as a Python dictionary with a Python list as the value type.
template<TYPE1, TYPE2>
%MappedType QMultiMap<TYPE1, TYPE2> /DocType="dict-of-TYPE1-list-of-TYPE2"/
{
%TypeHeaderCode
#include <qmap.h>
%End

%ConvertFromTypeCode
    // Create the dictionary.
    PyObject *d = PyDict_New();

    if (!d)
        return NULL;

    // Set the dictionary elements.
    QList<TYPE1> keys = sipCpp->keys();
    QList<TYPE1>::const_iterator kit = keys.constBegin();

    while (kit != keys.constEnd())
    {
        // Create a Python list as the dictionary value.
        QList<TYPE2> values = sipCpp->values(*kit);
        PyObject *value_obj = PyList_New(values.count());

        if (!value_obj)
        {
            Py_DECREF(d);
            return NULL;
        }

        // Wrap each value associated with the key.
        QList<TYPE2>::const_iterator vit = values.constBegin();
        int i = 0;

        while (vit != values.constEnd())
        {
            TYPE2 *val_copy = new TYPE2(*vit);
            PyObject *val_obj = sipConvertFromNewType(val_copy, sipType_TYPE2, sipTransferObj);

            if (!val_obj)
            {
                delete val_copy;

                Py_DECREF(value_obj);
                Py_DECREF(d);
                return NULL;
            }

            PyList_SET_ITEM(value_obj, i, val_obj);

            ++i;
            ++vit;
        }

        // Wrap a copy of the key.
        TYPE1 *key_copy = new TYPE1(*kit);
        PyObject *key_obj = sipConvertFromNewType(key_copy, sipType_TYPE1, sipTransferObj);

        if (!key_obj)
        {
            delete key_copy;

            Py_DECREF(value_obj);
            Py_DECREF(d);
            return NULL;
        }

        // Add to the dictionary.
        if (PyDict_SetItem(d, key_obj, value_obj) < 0)
        {
            Py_DECREF(key_obj);
            Py_DECREF(value_obj);
            Py_DECREF(d);
            return NULL;
        }

        Py_DECREF(key_obj);
        Py_DECREF(value_obj);

        ++kit;
    }

    return d;
%End

%ConvertToTypeCode
    PyObject *key_obj, *value_obj;
    SIP_SSIZE_T i = 0;

    // Check the type if that is all that is required.
    if (sipIsErr == NULL)
    {
        if (!PyDict_Check(sipPy))
            return 0;

        while (PyDict_Next(sipPy, &i, &key_obj, &value_obj))
        {
            if (!sipCanConvertToType(key_obj, sipType_TYPE1, SIP_NOT_NONE))
                return 0;

            if (!PyList_Check(value_obj))
                return 0;

            for (SIP_SSIZE_T vi = 0; vi < PyList_GET_SIZE(value_obj); ++vi)
                if (!sipCanConvertToType(PyList_GET_ITEM(value_obj, vi), sipType_TYPE2, SIP_NOT_NONE))
                    return 0;
        } 

        return 1;
    }

    QMultiMap<TYPE1, TYPE2> *qm = new QMultiMap<TYPE1, TYPE2>;
 
    while (PyDict_Next(sipPy, &i, &key_obj, &value_obj))
    {
        int key_state;

        TYPE1 *key = reinterpret_cast<TYPE1 *>(sipConvertToType(key_obj, sipType_TYPE1, sipTransferObj, SIP_NOT_NONE, &key_state, sipIsErr));

        SIP_SSIZE_T vi = PyList_GET_SIZE(value_obj);

        // We go through the list backwards to maintain the Qt semantics of
        // later items appearing first.
        while (vi--)
        {
            int val_state;

            TYPE2 *val = reinterpret_cast<TYPE2 *>(sipConvertToType(PyList_GET_ITEM(value_obj, vi), sipType_TYPE2, sipTransferObj, SIP_NOT_NONE, &val_state, sipIsErr));
 
            if (*sipIsErr)
            {
                sipReleaseType(val, sipType_TYPE2, val_state);
                break;
            }

            qm->insert(*key, *val);
            sipReleaseType(val, sipType_TYPE2, val_state);
        }

        sipReleaseType(key, sipType_TYPE1, key_state);

        if (*sipIsErr)
        {
            delete qm;
            return 0;
        }
    }
 
    *sipCppPtr = qm;
 
    return sipGetState(sipTransferObj);
%End
};
