/*
* Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved.
*
* 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; version 2 of the
* License.
*
* 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
*/

#ifndef __grts_structs_test_h__
#define __grts_structs_test_h__

#include <grtpp.h>

#ifdef _WIN32
  #pragma warning(disable: 4355) // 'this' : used in base member initizalizer list
  #ifdef GRT_STRUCTS_TEST_EXPORT
  #define GRT_STRUCTS_TEST_PUBLIC __declspec(dllexport)
#else
  #define GRT_STRUCTS_TEST_PUBLIC __declspec(dllimport)
#endif
#else
  #define GRT_STRUCTS_TEST_PUBLIC
#endif



class test_Bridged;
typedef grt::Ref<test_Bridged> test_BridgedRef;
class test_Base;
typedef grt::Ref<test_Base> test_BaseRef;
class test_Publisher;
typedef grt::Ref<test_Publisher> test_PublisherRef;
class test_Author;
typedef grt::Ref<test_Author> test_AuthorRef;
class test_Publication;
typedef grt::Ref<test_Publication> test_PublicationRef;
class test_Book;
typedef grt::Ref<test_Book> test_BookRef;


namespace mforms { 
	class Object;
}; 

namespace grt { 
	class AutoPyObject;
}; 

class  test_Bridged : public grt::internal::Object
{
  typedef grt::internal::Object super;
public:
  test_Bridged(grt::GRT *grt, grt::MetaClass *meta=0)
  : grt::internal::Object(grt, meta ? meta : grt->get_metaclass(static_class_name())),
    _books(grt, this, false),
     _name(""),
     _x(0),
     _y(0)

  {
  }

  static std::string static_class_name() { return "test.Bridged"; }

  /** Getter for attribute books (read-only)
   
    
   \par In Python:
value = obj.books
   */
  grt::ListRef<test_Book> books() const { return _books; }
private: // the next attribute is read-only
  virtual void books(const grt::ListRef<test_Book> &value)
  {
    grt::ValueRef ovalue(_books);
   _books= value;
    member_changed("books", ovalue, value);
  }
public:

  /** Getter for attribute name
   
    
   \par In Python:
value = obj.name
   */
  grt::StringRef name() const { return _name; }
  /** Setter for attribute name
   
    
    \par In Python:
obj.name = value
   */
  virtual void name(const grt::StringRef &value)
  {
    grt::ValueRef ovalue(_name);
   _name= value;
    member_changed("name", ovalue, value);
  }

  /** Getter for attribute x
   
    
   \par In Python:
value = obj.x
   */
  grt::IntegerRef x() const { return _x; }
  /** Setter for attribute x
   
    
    \par In Python:
obj.x = value
   */
  virtual void x(const grt::IntegerRef &value)
  {
    grt::ValueRef ovalue(_x);
   _x= value;
    member_changed("x", ovalue, value);
  }

  /** Getter for attribute y
   
    
   \par In Python:
value = obj.y
   */
  grt::IntegerRef y() const { return _y; }
  /** Setter for attribute y
   
    
    \par In Python:
obj.y = value
   */
  virtual void y(const grt::IntegerRef &value)
  {
    grt::ValueRef ovalue(_y);
   _y= value;
    member_changed("y", ovalue, value);
  }

protected:

  grt::ListRef<test_Book> _books;
  grt::StringRef _name;
  grt::IntegerRef _x;
  grt::IntegerRef _y;
private: // wrapper methods for use by grt
  static grt::ObjectRef create(grt::GRT *grt)
  {
    return grt::ObjectRef(new test_Bridged(grt));
  }


public:
  static void grt_register(grt::GRT *grt)
  {
    grt::MetaClass *meta= grt->get_metaclass(static_class_name());
    if (!meta) throw std::runtime_error("error initializing grt object class, metaclass not found");
    meta->bind_allocator(&test_Bridged::create);
    {
      void (test_Bridged::*setter)(const grt::ListRef<test_Book> &)= &test_Bridged::books;
      grt::ListRef<test_Book> (test_Bridged::*getter)() const= &test_Bridged::books;
      meta->bind_member("books", new grt::MetaClass::Property<test_Bridged,grt::ListRef<test_Book> >(getter,setter));
    }
    {
      void (test_Bridged::*setter)(const grt::StringRef &)= &test_Bridged::name;
      grt::StringRef (test_Bridged::*getter)() const= &test_Bridged::name;
      meta->bind_member("name", new grt::MetaClass::Property<test_Bridged,grt::StringRef >(getter,setter));
    }
    {
      void (test_Bridged::*setter)(const grt::IntegerRef &)= &test_Bridged::x;
      grt::IntegerRef (test_Bridged::*getter)() const= &test_Bridged::x;
      meta->bind_member("x", new grt::MetaClass::Property<test_Bridged,grt::IntegerRef >(getter,setter));
    }
    {
      void (test_Bridged::*setter)(const grt::IntegerRef &)= &test_Bridged::y;
      grt::IntegerRef (test_Bridged::*getter)() const= &test_Bridged::y;
      meta->bind_member("y", new grt::MetaClass::Property<test_Bridged,grt::IntegerRef >(getter,setter));
    }
  }
};


class  test_Base : public grt::internal::Object
{
  typedef grt::internal::Object super;
public:
  test_Base(grt::GRT *grt, grt::MetaClass *meta=0)
  : grt::internal::Object(grt, meta ? meta : grt->get_metaclass(static_class_name()))

  {
  }

  static std::string static_class_name() { return "test.Base"; }

protected:

private: // wrapper methods for use by grt
  static grt::ObjectRef create(grt::GRT *grt)
  {
    return grt::ObjectRef(new test_Base(grt));
  }


public:
  static void grt_register(grt::GRT *grt)
  {
    grt::MetaClass *meta= grt->get_metaclass(static_class_name());
    if (!meta) throw std::runtime_error("error initializing grt object class, metaclass not found");
    meta->bind_allocator(&test_Base::create);
  }
};


class  test_Publisher : public test_Base
{
  typedef test_Base super;
public:
  test_Publisher(grt::GRT *grt, grt::MetaClass *meta=0)
  : test_Base(grt, meta ? meta : grt->get_metaclass(static_class_name())),
    _books(grt, this, false),
     _name(""),
     _phone("")

  {
  }

  static std::string static_class_name() { return "test.Publisher"; }

  // books is owned by test_Publisher
  /** Getter for attribute books (read-only)
   
    
   \par In Python:
value = obj.books
   */
  grt::ListRef<test_Book> books() const { return _books; }
private: // the next attribute is read-only
  virtual void books(const grt::ListRef<test_Book> &value)
  {
    grt::ValueRef ovalue(_books);

    _books= value;
    owned_member_changed("books", ovalue, value);
  }
public:

  /** Getter for attribute name
   
    name of the publisher
   \par In Python:
value = obj.name
   */
  grt::StringRef name() const { return _name; }
  /** Setter for attribute name
   
    name of the publisher
    \par In Python:
obj.name = value
   */
  virtual void name(const grt::StringRef &value)
  {
    grt::ValueRef ovalue(_name);
   _name= value;
    member_changed("name", ovalue, value);
  }

  /** Getter for attribute phone
   
    phone of the publisher
   \par In Python:
value = obj.phone
   */
  grt::StringRef phone() const { return _phone; }
  /** Setter for attribute phone
   
    phone of the publisher
    \par In Python:
obj.phone = value
   */
  virtual void phone(const grt::StringRef &value)
  {
    grt::ValueRef ovalue(_phone);
   _phone= value;
    member_changed("phone", ovalue, value);
  }

protected:

  grt::ListRef<test_Book> _books;// owned
  grt::StringRef _name;
  grt::StringRef _phone;
private: // wrapper methods for use by grt
  static grt::ObjectRef create(grt::GRT *grt)
  {
    return grt::ObjectRef(new test_Publisher(grt));
  }


public:
  static void grt_register(grt::GRT *grt)
  {
    grt::MetaClass *meta= grt->get_metaclass(static_class_name());
    if (!meta) throw std::runtime_error("error initializing grt object class, metaclass not found");
    meta->bind_allocator(&test_Publisher::create);
    {
      void (test_Publisher::*setter)(const grt::ListRef<test_Book> &)= &test_Publisher::books;
      grt::ListRef<test_Book> (test_Publisher::*getter)() const= &test_Publisher::books;
      meta->bind_member("books", new grt::MetaClass::Property<test_Publisher,grt::ListRef<test_Book> >(getter,setter));
    }
    {
      void (test_Publisher::*setter)(const grt::StringRef &)= &test_Publisher::name;
      grt::StringRef (test_Publisher::*getter)() const= &test_Publisher::name;
      meta->bind_member("name", new grt::MetaClass::Property<test_Publisher,grt::StringRef >(getter,setter));
    }
    {
      void (test_Publisher::*setter)(const grt::StringRef &)= &test_Publisher::phone;
      grt::StringRef (test_Publisher::*getter)() const= &test_Publisher::phone;
      meta->bind_member("phone", new grt::MetaClass::Property<test_Publisher,grt::StringRef >(getter,setter));
    }
  }
};


class  test_Author : public test_Base
{
  typedef test_Base super;
public:
  test_Author(grt::GRT *grt, grt::MetaClass *meta=0)
  : test_Base(grt, meta ? meta : grt->get_metaclass(static_class_name())),
     _name("")

  {
  }

  static std::string static_class_name() { return "test.Author"; }

  /** Getter for attribute name
   
    name of the author
   \par In Python:
value = obj.name
   */
  grt::StringRef name() const { return _name; }
  /** Setter for attribute name
   
    name of the author
    \par In Python:
obj.name = value
   */
  virtual void name(const grt::StringRef &value)
  {
    grt::ValueRef ovalue(_name);
   _name= value;
    member_changed("name", ovalue, value);
  }

protected:

  grt::StringRef _name;
private: // wrapper methods for use by grt
  static grt::ObjectRef create(grt::GRT *grt)
  {
    return grt::ObjectRef(new test_Author(grt));
  }


public:
  static void grt_register(grt::GRT *grt)
  {
    grt::MetaClass *meta= grt->get_metaclass(static_class_name());
    if (!meta) throw std::runtime_error("error initializing grt object class, metaclass not found");
    meta->bind_allocator(&test_Author::create);
    {
      void (test_Author::*setter)(const grt::StringRef &)= &test_Author::name;
      grt::StringRef (test_Author::*getter)() const= &test_Author::name;
      meta->bind_member("name", new grt::MetaClass::Property<test_Author,grt::StringRef >(getter,setter));
    }
  }
};


class  test_Publication : public test_Base
{
  typedef test_Base super;
public:
  test_Publication(grt::GRT *grt, grt::MetaClass *meta=0)
  : test_Base(grt, meta ? meta : grt->get_metaclass(static_class_name())),
     _title("")

  {
  }

  static std::string static_class_name() { return "test.Publication"; }

  /** Getter for attribute title
   
    title of the book
   \par In Python:
value = obj.title
   */
  grt::StringRef title() const { return _title; }
  /** Setter for attribute title
   
    title of the book
    \par In Python:
obj.title = value
   */
  virtual void title(const grt::StringRef &value)
  {
    grt::ValueRef ovalue(_title);
   _title= value;
    member_changed("title", ovalue, value);
  }

protected:

  grt::StringRef _title;
private: // wrapper methods for use by grt
  static grt::ObjectRef create(grt::GRT *grt)
  {
    return grt::ObjectRef(new test_Publication(grt));
  }


public:
  static void grt_register(grt::GRT *grt)
  {
    grt::MetaClass *meta= grt->get_metaclass(static_class_name());
    if (!meta) throw std::runtime_error("error initializing grt object class, metaclass not found");
    meta->bind_allocator(&test_Publication::create);
    {
      void (test_Publication::*setter)(const grt::StringRef &)= &test_Publication::title;
      grt::StringRef (test_Publication::*getter)() const= &test_Publication::title;
      meta->bind_member("title", new grt::MetaClass::Property<test_Publication,grt::StringRef >(getter,setter));
    }
  }
};


class  test_Book : public test_Publication
{
  typedef test_Publication super;
public:
  test_Book(grt::GRT *grt, grt::MetaClass *meta=0)
  : test_Publication(grt, meta ? meta : grt->get_metaclass(static_class_name())),
    _authors(grt, this, false),
    _extras(grt, this, false),
     _pages(0),
     _price(0.0)

  {
  }

  static std::string static_class_name() { return "test.Book"; }

  // authors is owned by test_Book
  /** Getter for attribute authors (read-only)
   
    the list of authors
   \par In Python:
value = obj.authors
   */
  grt::ListRef<test_Author> authors() const { return _authors; }
private: // the next attribute is read-only
  virtual void authors(const grt::ListRef<test_Author> &value)
  {
    grt::ValueRef ovalue(_authors);

    _authors= value;
    owned_member_changed("authors", ovalue, value);
  }
public:

  /** Getter for attribute extras (read-only)
   
    extra stuff
   \par In Python:
value = obj.extras
   */
  grt::DictRef extras() const { return _extras; }
private: // the next attribute is read-only
  virtual void extras(const grt::DictRef &value)
  {
    grt::ValueRef ovalue(_extras);
   _extras= value;
    member_changed("extras", ovalue, value);
  }
public:

  /** Getter for attribute pages
   
    number of pages in book
   \par In Python:
value = obj.pages
   */
  grt::IntegerRef pages() const { return _pages; }
  /** Setter for attribute pages
   
    number of pages in book
    \par In Python:
obj.pages = value
   */
  virtual void pages(const grt::IntegerRef &value)
  {
    grt::ValueRef ovalue(_pages);
   _pages= value;
    member_changed("pages", ovalue, value);
  }

  /** Getter for attribute price
   
    
   \par In Python:
value = obj.price
   */
  grt::DoubleRef price() const { return _price; }
  /** Setter for attribute price
   
    
    \par In Python:
obj.price = value
   */
  virtual void price(const grt::DoubleRef &value)
  {
    grt::ValueRef ovalue(_price);
   _price= value;
    member_changed("price", ovalue, value);
  }

  /** Getter for attribute publisher
   
    the book publisher
   \par In Python:
value = obj.publisher
   */
  grt::Ref<test_Publisher> publisher() const { return _publisher; }
  /** Setter for attribute publisher
   
    the book publisher
    \par In Python:
obj.publisher = value
   */
  virtual void publisher(const grt::Ref<test_Publisher> &value)
  {
    grt::ValueRef ovalue(_publisher);
   _publisher= value;
    member_changed("publisher", ovalue, value);
  }

protected:

  grt::ListRef<test_Author> _authors;// owned
  grt::DictRef _extras;
  grt::IntegerRef _pages;
  grt::DoubleRef _price;
  grt::Ref<test_Publisher> _publisher;
private: // wrapper methods for use by grt
  static grt::ObjectRef create(grt::GRT *grt)
  {
    return grt::ObjectRef(new test_Book(grt));
  }


public:
  static void grt_register(grt::GRT *grt)
  {
    grt::MetaClass *meta= grt->get_metaclass(static_class_name());
    if (!meta) throw std::runtime_error("error initializing grt object class, metaclass not found");
    meta->bind_allocator(&test_Book::create);
    {
      void (test_Book::*setter)(const grt::ListRef<test_Author> &)= &test_Book::authors;
      grt::ListRef<test_Author> (test_Book::*getter)() const= &test_Book::authors;
      meta->bind_member("authors", new grt::MetaClass::Property<test_Book,grt::ListRef<test_Author> >(getter,setter));
    }
    {
      void (test_Book::*setter)(const grt::DictRef &)= &test_Book::extras;
      grt::DictRef (test_Book::*getter)() const= &test_Book::extras;
      meta->bind_member("extras", new grt::MetaClass::Property<test_Book,grt::DictRef >(getter,setter));
    }
    {
      void (test_Book::*setter)(const grt::IntegerRef &)= &test_Book::pages;
      grt::IntegerRef (test_Book::*getter)() const= &test_Book::pages;
      meta->bind_member("pages", new grt::MetaClass::Property<test_Book,grt::IntegerRef >(getter,setter));
    }
    {
      void (test_Book::*setter)(const grt::DoubleRef &)= &test_Book::price;
      grt::DoubleRef (test_Book::*getter)() const= &test_Book::price;
      meta->bind_member("price", new grt::MetaClass::Property<test_Book,grt::DoubleRef >(getter,setter));
    }
    {
      void (test_Book::*setter)(const grt::Ref<test_Publisher> &)= &test_Book::publisher;
      grt::Ref<test_Publisher> (test_Book::*getter)() const= &test_Book::publisher;
      meta->bind_member("publisher", new grt::MetaClass::Property<test_Book,grt::Ref<test_Publisher> >(getter,setter));
    }
  }
};




inline void register_structs_test_xml()
{
  grt::internal::ClassRegistry::register_class<test_Bridged>();
  grt::internal::ClassRegistry::register_class<test_Base>();
  grt::internal::ClassRegistry::register_class<test_Publisher>();
  grt::internal::ClassRegistry::register_class<test_Author>();
  grt::internal::ClassRegistry::register_class<test_Publication>();
  grt::internal::ClassRegistry::register_class<test_Book>();
}

#ifdef AUTO_REGISTER_GRT_CLASSES
static struct _autoreg__structs_test_xml { _autoreg__structs_test_xml() { register_structs_test_xml(); } } __autoreg__structs_test_xml;
#endif

#endif
