# 
# Copyright (C) 2006-2018 Matthias Koefferlein
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#

# --------------------------------------------------------------
# Provides the definitions of QCoreApplication, QApplication and QGuiApplication

def add_native_qapp_ctor_impl(cls)

  qapplication_ctor_code = <<'CODE'
  static %CLS% *ctor_%CLS%_Adaptor_args(const std::vector<std::string> &args%ADDARGS%)
  {
    //  %CLS% needs static sources, so we give it some.
    static char **argv = 0;
    static std::vector<std::string> args_copy;
    static int argc = 0;

    if (argv != 0) {
      throw tl::Exception(tl::to_string(QObject::tr("%CLS% cannot be instantiated twice")));
    }
    argv = new char *[args.size ()];
    args_copy = args;
    argc = int (args.size ());
    for (std::vector<std::string>::const_iterator a = args_copy.begin (); a != args_copy.end (); ++a) {
      argv[a - args_copy.begin ()] = (char *) a->c_str ();
    }

    return new %CLS%_Adaptor (argc, argv%ADDARGSCALL%);
  }

  %CLS%_Adaptor (int &argc, char **argv%ADDARGS%) : %CLS% (argc, argv%ADDARGSCALL%) { }
CODE

  qapplication_ctor_decl = <<'DECL'
    gsi::constructor("new", &%CLS%_Adaptor::ctor_%CLS%_Adaptor_args, gsi::arg ("argv")%ADDARGS%, "@brief Creates a new %CLS% object\n\n@param argv The command line arguments to pass to Qt%ADDDOC%")
DECL

  if cls == "QApplication" 
    add_native_impl(cls + "_Adaptor", 
                    qapplication_ctor_code.gsub("%CLS%", cls).gsub("%ADDARGS%", ", bool gui").gsub("%ADDARGSCALL%", ", gui"), 
                    qapplication_ctor_decl.gsub("%CLS%", cls).gsub("%ADDARGS%", ", gsi::arg (\"gui\", true)").gsub("%ADDDOC%", "\\n@param gui If true, a GUI-enabled application is constructed"))
  else
    add_native_impl(cls + "_Adaptor", 
                    qapplication_ctor_code.gsub("%CLS%", cls).gsub("%ADDARGS%", "").gsub("%ADDARGSCALL%", ""), 
                    qapplication_ctor_decl.gsub("%CLS%", cls).gsub("%ADDARGS%", "").gsub("%ADDDOC%", ""))
  end

end

# --------------------------------------------------------------
# Provides the definitions for QObject::findChild and QObject::findChildren

def add_native_impl_QObject_findChild()

  # alternative implementation for QObject::findChild using QObject for T
  add_native_impl("QObject", <<'CODE', <<'DECL')

#if QT_VERSION < 0x50000

#include <QRegExp>

  QObject *find_child_impl (QObject *object, const QString &name) 
  { 
    return object->findChild<QObject *> (name); 
  }
  QList<QObject *> find_children_impl (QObject *object, const QString &name)
  { 
    return object->findChildren<QObject *> (name); 
  }
  QList<QObject *> find_children_impl2 (QObject *object, const QRegExp &re)
  { 
    return object->findChildren<QObject *> (re); 
  }
#else

#include <QRegularExpression>

  QObject *find_child_impl (QObject *object, const QString &name, Qt::FindChildOptions options)
  { 
    return object->findChild<QObject *> (name, options); 
  }
  QList<QObject *> find_children_impl (QObject *object, const QString &name, Qt::FindChildOptions options)
  { 
    return object->findChildren<QObject *> (name, options); 
  }
  QList<QObject *> find_children_impl2 (QObject *object, const QRegularExpression &re, Qt::FindChildOptions options)
  { 
    return object->findChildren<QObject *> (re, options); 
  }
#endif
CODE
#if QT_VERSION < 0x50000
  gsi::method_ext("findChild", &find_child_impl, gsi::arg("name", QString(), "null"), "@brief Specialisation for findChild (uses QObject as T).") +
  gsi::method_ext("findChildren", &find_children_impl, gsi::arg("name", QString(), "null"), "@brief Specialisation for findChildren (uses QObject as T).") +
  gsi::method_ext("findChildren", &find_children_impl2, gsi::arg("re"), "@brief Specialisation for findChildren (uses QObject as T).") 
#else
  gsi::method_ext("findChild", &find_child_impl, gsi::arg("name", QString(), "null"), gsi::arg("options", Qt::FindChildrenRecursively, "Qt::FindChildrenRecursively"), "@brief Specialisation for findChild (uses QObject as T).") +
  gsi::method_ext("findChildren", &find_children_impl, gsi::arg("name", QString(), "null"), gsi::arg("options", Qt::FindChildrenRecursively, "Qt::FindChildrenRecursively"), "@brief Specialisation for findChildren (uses QObject as T).") +
  gsi::method_ext("findChildren", &find_children_impl2, gsi::arg("re"), gsi::arg("options", Qt::FindChildrenRecursively, "Qt::FindChildrenRecursively"), "@brief Specialisation for findChildren (uses QObject as T).") 
#endif
DECL

end

# --------------------------------------------------------------
# Add native implementations for QImage
# Constructor from raw packed data without the cleanup functions

def add_native_impl_QImage

  add_native_impl("QImage_Adaptor", <<'CODE', <<'DECL')

  //  NOTE: QImage does not take ownership of the data, so 
  //  we will provide a buffer to do so. This requires an additional 
  //  copy, but as GSI is not guaranteeing the lifetime of the 
  //  data, this is required here.
  class DataHolder
  {
  public:

    DataHolder() : mp_data(0) { }
    DataHolder(unsigned char *data) : mp_data(data) { }

    ~DataHolder() 
    { 
      if (mp_data) {
        delete[](mp_data); 
      }
      mp_data = 0;
    }

    static unsigned char *alloc(const std::string &data)
    {
      unsigned char *ptr = new unsigned char[data.size()];
      memcpy(ptr, data.c_str(), data.size());
      return ptr;
    }

  private:
    unsigned char *mp_data;
  };

  static QImage_Adaptor *new_qimage_from_data1(const std::string &data, int width, int height, int bytesPerLine, QImage::Format format) 
  {
    return new QImage_Adaptor(DataHolder::alloc(data), width, height, bytesPerLine, format);
  }

  static QImage_Adaptor *new_qimage_from_data2(const std::string &data, int width, int height, QImage::Format format) 
  {
    return new QImage_Adaptor(DataHolder::alloc(data), width, height, format);
  }

  QImage_Adaptor(unsigned char *data, int width, int height, int bytesPerLine, QImage::Format format)
    : QImage(data, width, height, bytesPerLine, format), m_holder(data)
  {
  }

  QImage_Adaptor(unsigned char *data, int width, int height, QImage::Format format)
    : QImage (data, width, height, format), m_holder(data)
  {
  }

  DataHolder m_holder;

CODE
  gsi::constructor("new", &QImage_Adaptor::new_qimage_from_data1, gsi::arg ("data"), gsi::arg ("width"), gsi::arg ("height"), gsi::arg ("bytesPerLine"), gsi::arg ("format"),
    "@brief QImage::QImage(const uchar *data, int width, int height, int bytesPerLine)\n"
    "The cleanupFunction parameter is available currently."
  ) +
  gsi::constructor("new", &QImage_Adaptor::new_qimage_from_data2, gsi::arg ("data"), gsi::arg ("width"), gsi::arg ("height"), gsi::arg ("format"),
    "@brief QImage::QImage(const uchar *data, int width, int height)\n"
    "The cleanupFunction parameter is available currently."
  )
DECL

end

# --------------------------------------------------------------
# Alternative implementation for QFont::Light, QFont::Bold, QFont::Normal, QFont::DemiBold, QFont::Black

def add_native_impl_QFont

  add_native_impl("QFont", <<'CODE', <<'DECL')
  static unsigned int font_const_light () { return (unsigned int) QFont::Light; }
  static unsigned int font_const_normal () { return (unsigned int) QFont::Normal; }
  static unsigned int font_const_demibold () { return (unsigned int) QFont::DemiBold; }
  static unsigned int font_const_bold () { return (unsigned int) QFont::Bold; }
  static unsigned int font_const_black () { return (unsigned int) QFont::Black; }
CODE
  gsi::method("Light", &font_const_light, "@brief Font weight constant 'QFont::Light'.") +
  gsi::method("Normal", &font_const_normal, "@brief Font weight constant 'QFont::Normal'.") +
  gsi::method("DemiBold", &font_const_demibold, "@brief Font weight constant 'QFont::DemiBold'.") +
  gsi::method("Bold", &font_const_bold, "@brief Font weight constant 'QFont::Bold'.") +
  gsi::method("Black", &font_const_black, "@brief Font weight constant 'QFont::Black'.")
DECL

end

# --------------------------------------------------------------
# Alternative implementation for QRegion

def add_native_impl_QRegion

  # alternative implementation for QRegion::setRects
  add_native_impl("QRegion", <<'CODE', <<'DECL')
  static void f_QRegion_setRects(QRegion *r, const std::vector<QRect> &rects)
  {
    if (! rects.empty ()) {
      return r->setRects (&rects.front (), int (rects.size ()));
    }
  }
CODE
  gsi::method_ext("setRects", &f_QRegion_setRects, "@brief Adaption of setRects without pointer.")
DECL

end

# --------------------------------------------------------------
# Alternative implementation for QPersistentQModelIndex

def add_native_impl_QPersistentQModelIndex

  # alternative implementation for QPersistentQModelIndex::operator const QModelIndex &
  add_native_impl("QPersistentModelIndex", <<'CODE', <<'DECL')
#if QT_VERSION < 0x60000
  static const QModelIndex &castToQModelIndex(const QPersistentModelIndex *m)
  {
    return m->operator const QModelIndex &();
  }
#else
  static QModelIndex castToQModelIndex(const QPersistentModelIndex *m)
  {
    return m->operator QModelIndex();
  }
#endif
CODE
  gsi::method_ext("castToQModelIndex", &castToQModelIndex, "@brief Binding for \"operator const QModelIndex &\".")
DECL
  
end

# --------------------------------------------------------------
# implementation of operator<< and operator>> for QDataStream

def add_native_impl_streams

  add_native_impl("QDataStream", <<'CODE', <<'DECL')
  static qint8 f_QDataStream_read_qint8(QDataStream *s)
  {
    qint8 v = 0;
    *s >> v;
    return v;
  }

  static quint8 f_QDataStream_read_quint8(QDataStream *s)
  {
    quint8 v = 0;
    *s >> v;
    return v;
  }

  static qint16 f_QDataStream_read_qint16(QDataStream *s)
  {
    qint16 v = 0;
    *s >> v;
    return v;
  }

  static quint16 f_QDataStream_read_quint16(QDataStream *s)
  {
    quint16 v = 0;
    *s >> v;
    return v;
  }

  static qint32 f_QDataStream_read_qint32(QDataStream *s)
  {
    qint32 v = 0;
    *s >> v;
    return v;
  }

  static quint32 f_QDataStream_read_quint32(QDataStream *s)
  {
    quint32 v = 0;
    *s >> v;
    return v;
  }

  static quint64 f_QDataStream_read_quint64(QDataStream *s)
  {
    quint64 v = 0;
    *s >> v;
    return v;
  }

  static qint64 f_QDataStream_read_qint64(QDataStream *s)
  {
    qint64 v = 0;
    *s >> v;
    return v;
  }

  static double f_QDataStream_read_double(QDataStream *s)
  {
    double v = 0;
    *s >> v;
    return v;
  }

  static float f_QDataStream_read_float(QDataStream *s)
  {
    float v = 0;
    *s >> v;
    return v;
  }

  static bool f_QDataStream_read_bool(QDataStream *s)
  {
    bool v = 0;
    *s >> v;
    return v;
  }

  static qt_gsi::Converter<QChar>::target_type f_QDataStream_read_qchar(QDataStream *s)
  {
    QChar v = QChar (0);
    *s >> v;
    return qt_gsi::Converter<QChar>::toc (v);
  }

  static qt_gsi::Converter<QList<int> >::target_type f_QDataStream_read_int_list(QDataStream *s)
  {
    QList<int> v;
    *s >> v;
    return qt_gsi::Converter<QList<int> >::toc (v);
  }

  static qt_gsi::Converter<QVector<int> >::target_type f_QDataStream_read_int_vector(QDataStream *s)
  {
    QVector<int> v;
    *s >> v;
    return qt_gsi::Converter<QVector<int> >::toc (v);
  }

  static QString f_QDataStream_read_string(QDataStream *s)
  {
    QString v;
    *s >> v;
    return v;
  }

  static qt_gsi::Converter<QByteArray>::target_type f_QDataStream_read_bytearray(QDataStream *s)
  {
    QByteArray v;
    *s >> v;
    return qt_gsi::Converter<QByteArray>::toc (v);
  }

  static QDataStream *f_QDataStream_put_qint8(QDataStream *s, qint8 v)
  {
    *s << v;
    return s;
  }

  static QDataStream *f_QDataStream_put_quint8(QDataStream *s, quint8 v)
  {
    *s << v;
    return s;
  }

  static QDataStream *f_QDataStream_put_qint16(QDataStream *s, qint16 v)
  {
    *s << v;
    return s;
  }

  static QDataStream *f_QDataStream_put_quint16(QDataStream *s, quint16 v)
  {
    *s << v;
    return s;
  }

  static QDataStream *f_QDataStream_put_qint32(QDataStream *s, qint32 v)
  {
    *s << v;
    return s;
  }

  static QDataStream *f_QDataStream_put_quint32(QDataStream *s, quint32 v)
  {
    *s << v;
    return s;
  }

  static QDataStream *f_QDataStream_put_qint64(QDataStream *s, qint64 v)
  {
    *s << v;
    return s;
  }

  static QDataStream *f_QDataStream_put_quint64(QDataStream *s, quint64 v)
  {
    *s << v;
    return s;
  }

  static QDataStream *f_QDataStream_put_float(QDataStream *s, float v)
  {
    *s << v;
    return s;
  }

  static QDataStream *f_QDataStream_put_double(QDataStream *s, double v)
  {
    *s << v;
    return s;
  }

  static QDataStream *f_QDataStream_put_bool(QDataStream *s, bool v)
  {
    *s << v;
    return s;
  }

  static QDataStream *f_QDataStream_put_qchar(QDataStream *s, const qt_gsi::Converter<QChar>::target_type &v)
  {
    *s << qt_gsi::Converter<QChar>::toq (v);
    return s;
  }

  static QDataStream *f_QDataStream_put_int_list(QDataStream *s, const qt_gsi::Converter<QList<int> >::target_type &v)
  {
    *s << qt_gsi::Converter<QList<int> >::toq (v);
    return s;
  }

  static QDataStream *f_QDataStream_put_int_vector(QDataStream *s, const qt_gsi::Converter<QVector<int> >::target_type &v)
  {
    *s << qt_gsi::Converter<QVector<int> >::toq (v);
    return s;
  }

  static QDataStream *f_QDataStream_put_string(QDataStream *s, const QString &v)
  {
    *s << v;
    return s;
  }

  static QDataStream *f_QDataStream_put_bytearray(QDataStream *s, const qt_gsi::Converter<class QByteArray>::target_type &v)
  {
    *s << qt_gsi::Converter<class QByteArray>::toq (v);
    return s;
  }

CODE
  gsi::method_ext("read_i8", &f_QDataStream_read_qint8, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_ui8", &f_QDataStream_read_quint8, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_i16", &f_QDataStream_read_qint16, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_ui16", &f_QDataStream_read_quint16, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_i32", &f_QDataStream_read_qint32, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_ui32", &f_QDataStream_read_quint32, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_i64", &f_QDataStream_read_qint64, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_ui64", &f_QDataStream_read_quint64, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_d", &f_QDataStream_read_double, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_f", &f_QDataStream_read_float, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_b", &f_QDataStream_read_bool, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_qc", &f_QDataStream_read_qchar, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_il", &f_QDataStream_read_int_list, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_iv", &f_QDataStream_read_int_vector, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_s", &f_QDataStream_read_string, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_ba", &f_QDataStream_read_bytearray, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("put_i8", &f_QDataStream_put_qint8, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_ui8", &f_QDataStream_put_quint8, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_i16", &f_QDataStream_put_qint16, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_ui16", &f_QDataStream_put_quint16, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_i32", &f_QDataStream_put_qint32, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_ui32", &f_QDataStream_put_quint32, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_i64", &f_QDataStream_put_qint64, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_ui64", &f_QDataStream_put_quint64, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_d", &f_QDataStream_put_double, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_f", &f_QDataStream_put_float, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_b", &f_QDataStream_put_bool, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_qc", &f_QDataStream_put_qchar, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_il", &f_QDataStream_put_int_list, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_iv", &f_QDataStream_put_int_vector, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_s", &f_QDataStream_put_string, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_ba", &f_QDataStream_put_bytearray, "@brief Non-ambiguous adaptation of the corresponding operator<<") 
DECL

# implementation of operator<< and operator>> for QTextStream
add_native_impl("QTextStream", <<'CODE', <<'DECL')
  static short f_QTextStream_read_s(QTextStream *s)
  {
    short v = 0;
    *s >> v;
    return v;
  }

  static unsigned short f_QTextStream_read_us(QTextStream *s)
  {
    unsigned short v = 0;
    *s >> v;
    return v;
  }

  static int f_QTextStream_read_i(QTextStream *s)
  {
    int v = 0;
    *s >> v;
    return v;
  }

  static unsigned int f_QTextStream_read_ui(QTextStream *s)
  {
    unsigned int v = 0;
    *s >> v;
    return v;
  }

  static qulonglong f_QTextStream_read_ull(QTextStream *s)
  {
    qulonglong v = 0;
    *s >> v;
    return v;
  }

  static qlonglong f_QTextStream_read_ll(QTextStream *s)
  {
    qlonglong v = 0;
    *s >> v;
    return v;
  }

  static double f_QTextStream_read_double(QTextStream *s)
  {
    double v = 0;
    *s >> v;
    return v;
  }

  static float f_QTextStream_read_float(QTextStream *s)
  {
    float v = 0;
    *s >> v;
    return v;
  }

  static qt_gsi::Converter<QChar>::target_type f_QTextStream_read_qchar(QTextStream *s)
  {
    QChar v = QChar (0);
    *s >> v;
    return qt_gsi::Converter<QChar>::toc (v);
  }

  static QString f_QTextStream_read_string(QTextStream *s)
  {
    QString v;
    *s >> v;
    return v;
  }

  static qt_gsi::Converter<QByteArray>::target_type f_QTextStream_read_bytearray(QTextStream *s)
  {
    QByteArray v;
    *s >> v;
    return qt_gsi::Converter<QByteArray>::toc (v);
  }

  static QTextStream *f_QTextStream_put_s(QTextStream *s, short v)
  {
    *s << v;
    return s;
  }

  static QTextStream *f_QTextStream_put_us(QTextStream *s, unsigned short v)
  {
    *s << v;
    return s;
  }

  static QTextStream *f_QTextStream_put_i(QTextStream *s, int v)
  {
    *s << v;
    return s;
  }

  static QTextStream *f_QTextStream_put_ui(QTextStream *s, unsigned int v)
  {
    *s << v;
    return s;
  }

  static QTextStream *f_QTextStream_put_ll(QTextStream *s, qlonglong v)
  {
    *s << v;
    return s;
  }

  static QTextStream *f_QTextStream_put_ull(QTextStream *s, qulonglong v)
  {
    *s << v;
    return s;
  }

  static QTextStream *f_QTextStream_put_float(QTextStream *s, float v)
  {
    *s << v;
    return s;
  }

  static QTextStream *f_QTextStream_put_double(QTextStream *s, double v)
  {
    *s << v;
    return s;
  }

  static QTextStream *f_QTextStream_put_qchar(QTextStream *s, const qt_gsi::Converter<class QChar>::target_type v)
  {
    *s << qt_gsi::Converter<class QChar>::toq (v);
    return s;
  }

  static QTextStream *f_QTextStream_put_string(QTextStream *s, const QString &v)
  {
    *s << v;
    return s;
  }

  static QTextStream *f_QTextStream_put_bytearray(QTextStream *s, const qt_gsi::Converter<class QByteArray>::target_type &v)
  {
    *s << qt_gsi::Converter<class QByteArray>::toq (v);
    return s;
  }

CODE
  gsi::method_ext("read_s", &f_QTextStream_read_s, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_us", &f_QTextStream_read_us, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_i", &f_QTextStream_read_i, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_ui", &f_QTextStream_read_ui, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_ull", &f_QTextStream_read_ull, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_ll", &f_QTextStream_read_ll, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_d", &f_QTextStream_read_double, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_f", &f_QTextStream_read_float, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_qc", &f_QTextStream_read_qchar, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_s", &f_QTextStream_read_string, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("read_ba", &f_QTextStream_read_bytearray, "@brief Non-ambiguous adaptation of the corresponding operator>>") +
  gsi::method_ext("put_s", &f_QTextStream_put_s, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_us", &f_QTextStream_put_us, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_i", &f_QTextStream_put_i, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_ui", &f_QTextStream_put_ui, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_ull", &f_QTextStream_put_ull, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_ll", &f_QTextStream_put_ll, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_d", &f_QTextStream_put_double, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_f", &f_QTextStream_put_float, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_qc", &f_QTextStream_put_qchar, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_s", &f_QTextStream_put_string, "@brief Non-ambiguous adaptation of the corresponding operator<<") +
  gsi::method_ext("put_ba", &f_QTextStream_put_bytearray, "@brief Non-ambiguous adaptation of the corresponding operator<<") 
DECL

end

# --------------------------------------------------------------
# enhance QPolygon by some missing methods because we dropped the base class and 
# support for db methods

# enhance QPolygon by some missing methods because we dropped the base class
def add_native_impl_polygons

  # enhance QPolygon by some missing methods because we dropped the base class
  add_native_impl("QPolygon", <<'CODE', <<'DECL')

#include "dbPolygon.h"

  static QPolygon *ctor_QPolygon_from_polygon (const db::Polygon &pts)
  {
    QPolygon *p = new QPolygon ();
    p->reserve (int (pts.hull ().size ()));
    for (db::Polygon::polygon_contour_iterator q = pts.begin_hull (); q != pts.end_hull (); ++q) {
      p->push_back (QPoint ((*q).x (), (*q).y ()));
    }
    return p;
  }

  static QPolygon *ctor_QPolygon_from_simple_polygon (const db::SimplePolygon &pts)
  {
    QPolygon *p = new QPolygon ();
    p->reserve (int (pts.hull ().size ()));
    for (db::SimplePolygon::polygon_contour_iterator q = pts.begin_hull (); q != pts.end_hull (); ++q) {
      p->push_back (QPoint ((*q).x (), (*q).y ()));
    }
    return p;
  }

  static QPolygon::const_iterator f_QPolygon_each_begin (const QPolygon *m)
  {
    return m->begin ();
  }

  static QPolygon::const_iterator f_QPolygon_each_end (const QPolygon *m)
  {
    return m->end ();
  }

  static QPoint f_QPolygon_at (const QPolygon *m, int i)
  {
    return m->at(i);
  }

  static QPoint f_QPolygon_front (const QPolygon *m)
  {
    return m->front();
  }

  static QPoint f_QPolygon_back (const QPolygon *m)
  {
    return m->back();
  }

  static int f_QPolygon_size (const QPolygon *m)
  {
    return m->size();
  }

  static void f_QPolygon_clear (QPolygon *m)
  {
    m->clear();
  }

  static void f_QPolygon_remove (QPolygon *m, int i)
  {
    m->remove (i);
  }

  static void f_QPolygon_insert (QPolygon *m, int i, const QPoint &p)
  {
    m->insert (i, p);
  }

  static void f_QPolygon_replace (QPolygon *m, int i, const QPoint &p)
  {
    m->replace (i, p);
  }

  static void f_QPolygon_pop_front (QPolygon *m)
  {
    m->pop_front ();
  }

  static void f_QPolygon_pop_back (QPolygon *m)
  {
    m->pop_back ();
  }

  static void f_QPolygon_push_front (QPolygon *m, const QPoint &p)
  {
    m->push_front (p);
  }

  static void f_QPolygon_push_back (QPolygon *m, const QPoint &p)
  {
    m->push_back (p);
  }

  static void f_QPolygon_reserve (QPolygon *m, int n)
  {
    m->reserve (n);
  }

  static void f_QPolygon_resize (QPolygon *m, int n)
  {
    m->resize (n);
  }

  static void f_QPolygon_fill (QPolygon *m, const QPoint &p, int n)
  {
    m->fill (p, n);
  }
CODE
  gsi::constructor("new", &ctor_QPolygon_from_polygon, gsi::arg ("p"), "@brief Creates a polygon from the given KLayout Polygon\nRemark: holes are not transferred into the QPolygon.") +
  gsi::constructor("new", &ctor_QPolygon_from_simple_polygon, gsi::arg ("p"), "@brief Creates a polygon from the given KLayout SimplePolygon") +
  gsi::iterator_ext ("each", &f_QPolygon_each_begin, &f_QPolygon_each_end, "@brief Iterates over all points of the polygon.") +
  gsi::method_ext("[]", &f_QPolygon_at, gsi::arg ("index"), "@brief Gets the point at the given position") +
  gsi::method_ext("front", &f_QPolygon_front, "@brief Gets the first point") +
  gsi::method_ext("back", &f_QPolygon_back, "@brief Gets the last point") +
  gsi::method_ext("size", &f_QPolygon_size, "@brief Gets the number of points in the polygon") +
  gsi::method_ext("clear", &f_QPolygon_clear, "@brief Empties the polygon") +
  gsi::method_ext("remove", &f_QPolygon_remove, gsi::arg ("index"), "@brief Removes the point at the given position") +
  gsi::method_ext("insert", &f_QPolygon_insert, gsi::arg ("p"), gsi::arg ("p"), "@brief Inserts the point after the given position") +
  gsi::method_ext("replace", &f_QPolygon_replace, gsi::arg ("p"), gsi::arg ("p"), "@brief Replaces the point at the given position") +
  gsi::method_ext("pop_front", &f_QPolygon_pop_front, "@brief Removes the point at the beginning of the list") +
  gsi::method_ext("pop_back", &f_QPolygon_pop_back, "@brief Removes the point at the end of the list") +
  gsi::method_ext("push_front", &f_QPolygon_push_front, gsi::arg ("p"), "@brief Inserts the point at the beginning of the list") +
  gsi::method_ext("push_back", &f_QPolygon_push_back, gsi::arg ("p"), "@brief Inserts the point at the end of the list") +
  gsi::method_ext("reserve", &f_QPolygon_reserve, gsi::arg ("n"), "@brief Reserve memory for the given number of points") +
  gsi::method_ext("resize", &f_QPolygon_resize, gsi::arg ("l"), "@brief Sets the number of points to the given length") +
  gsi::method_ext("fill", &f_QPolygon_fill, gsi::arg ("p"), gsi::arg ("l"), "@brief Resizes the polygon to l points and sets all elements to the given point") 
DECL

  # enhance QPolygonF by some missing methods because we dropped the base class
  add_native_impl("QPolygonF", <<'CODE', <<'DECL')

#include "dbPolygon.h"

  static QPolygonF *ctor_QPolygonF_from_polygon (const db::DPolygon &pts)
  {
    QPolygonF *p = new QPolygonF ();
    p->reserve (int (pts.hull ().size ()));
    for (db::DPolygon::polygon_contour_iterator q = pts.begin_hull (); q != pts.end_hull (); ++q) {
      p->push_back (QPointF ((*q).x (), (*q).y ()));
    }
    return p;
  }

  static QPolygonF *ctor_QPolygonF_from_simple_polygon (const db::DSimplePolygon &pts)
  {
    QPolygonF *p = new QPolygonF ();
    p->reserve (int (pts.hull ().size ()));
    for (db::DSimplePolygon::polygon_contour_iterator q = pts.begin_hull (); q != pts.end_hull (); ++q) {
      p->push_back (QPointF ((*q).x (), (*q).y ()));
    }
    return p;
  }

  static QPolygonF::const_iterator f_QPolygonF_each_begin (const QPolygonF *m)
  {
    return m->begin ();
  }

  static QPolygonF::const_iterator f_QPolygonF_each_end (const QPolygonF *m)
  {
    return m->end ();
  }

  static QPointF f_QPolygonF_at (const QPolygonF *m, int i)
  {
    return m->at(i);
  }

  static QPointF f_QPolygonF_front (const QPolygonF *m)
  {
    return m->front();
  }

  static QPointF f_QPolygonF_back (const QPolygonF *m)
  {
    return m->back();
  }

  static int f_QPolygonF_size (const QPolygonF *m)
  {
    return m->size();
  }

  static void f_QPolygonF_clear (QPolygonF *m)
  {
    m->clear();
  }

  static void f_QPolygonF_remove (QPolygonF *m, int i)
  {
    m->remove (i);
  }

  static void f_QPolygonF_insert (QPolygonF *m, int i, const QPointF &p)
  {
    m->insert (i, p);
  }

  static void f_QPolygonF_replace (QPolygonF *m, int i, const QPointF &p)
  {
    m->replace (i, p);
  }

  static void f_QPolygonF_pop_front (QPolygonF *m)
  {
    m->pop_front ();
  }

  static void f_QPolygonF_pop_back (QPolygonF *m)
  {
    m->pop_back ();
  }

  static void f_QPolygonF_push_front (QPolygonF *m, const QPointF &p)
  {
    m->push_front (p);
  }

  static void f_QPolygonF_push_back (QPolygonF *m, const QPointF &p)
  {
    m->push_back (p);
  }

  static void f_QPolygonF_reserve (QPolygonF *m, int n)
  {
    m->reserve (n);
  }

  static void f_QPolygonF_resize (QPolygonF *m, int n)
  {
    m->resize (n);
  }

  static void f_QPolygonF_fill (QPolygonF *m, const QPointF &p, int n)
  {
    m->fill (p, n);
  }
CODE
  gsi::constructor("new", &ctor_QPolygonF_from_polygon, gsi::arg ("p"), "@brief Creates a polygon from the given KLayout DPolygon\nRemark: holes are not transferred into the QPolygonF.") +
  gsi::constructor("new", &ctor_QPolygonF_from_simple_polygon, gsi::arg ("p"), "@brief Creates a polygon from the given KLayout DSimplePolygon") +
  gsi::iterator_ext ("each", &f_QPolygonF_each_begin, &f_QPolygonF_each_end, "@brief Iterates over all points of the polygon.") +
  gsi::method_ext("[]", &f_QPolygonF_at, gsi::arg ("index"), "@brief Gets the point at the given position") +
  gsi::method_ext("front", &f_QPolygonF_front, "@brief Gets the first point") +
  gsi::method_ext("back", &f_QPolygonF_back, "@brief Gets the last point") +
  gsi::method_ext("size", &f_QPolygonF_size, "@brief Gets the number of points in the polygon") +
  gsi::method_ext("clear", &f_QPolygonF_clear, "@brief Empties the polygon") +
  gsi::method_ext("remove", &f_QPolygonF_remove, gsi::arg ("index"), "@brief Removes the point at the given position") +
  gsi::method_ext("insert", &f_QPolygonF_insert, gsi::arg ("index"), gsi::arg ("p"), "@brief Inserts the point after the given position") +
  gsi::method_ext("replace", &f_QPolygonF_replace, gsi::arg ("index"), gsi::arg ("p"), "@brief Replaces the point at the given position") +
  gsi::method_ext("pop_front", &f_QPolygonF_pop_front, "@brief Removes the point at the beginning of the list") +
  gsi::method_ext("pop_back", &f_QPolygonF_pop_back, "@brief Removes the point at the end of the list") +
  gsi::method_ext("push_front", &f_QPolygonF_push_front, gsi::arg ("p"), "@brief Inserts the point at the beginning of the list") +
  gsi::method_ext("push_back", &f_QPolygonF_push_back, gsi::arg ("p"), "@brief Inserts the point at the end of the list") +
  gsi::method_ext("reserve", &f_QPolygonF_reserve, gsi::arg ("n"), "@brief Reserve memory for the given number of points") +
  gsi::method_ext("resize", &f_QPolygonF_resize, gsi::arg ("l"), "@brief Sets the number of points to the given length") +
  gsi::method_ext("fill", &f_QPolygonF_fill, gsi::arg ("p"), gsi::arg ("l"), "@brief Resizes the polygon to l points and sets all elements to the given point") 
DECL

end

