#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_Base;
typedef grt::Ref<test_Base> test_BaseRef;
class test_Publication;
typedef grt::Ref<test_Publication> test_PublicationRef;
class test_Book;
typedef grt::Ref<test_Book> test_BookRef;
class test_Author;
typedef grt::Ref<test_Author> test_AuthorRef;
class test_Publisher;
typedef grt::Ref<test_Publisher> test_PublisherRef;
class test_Bridged;
typedef grt::Ref<test_Bridged> test_BridgedRef;


class  test_Base : public grt::internal::Object
{
public:
  class ImplData;
  friend class ImplData;
  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_Publication : public test_Base
{
public:
  class ImplData;
  friend class ImplData;
  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"; }

  grt::StringRef title() const { return _title; }
  virtual void title(const grt::StringRef &value)
  {
    grt::ValueRef ovalue(_title);
   _title= value;
    _changed_signal.emit("title", ovalue);
  }

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
{
public:
  class ImplData;
  friend class ImplData;
  test_Book(grt::GRT *grt, grt::MetaClass *meta=0)
  : test_Publication(grt, meta ? meta : grt->get_metaclass(static_class_name())),
    _authors(grt, this),
    _extras(grt, this),
     _pages(),
     _price()

  {
  }

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

  // authors is owned by test_Book
  grt::ListRef<test_Author> authors() const { return _authors; }
  virtual void authors(const grt::ListRef<test_Author> &value)
  {
    grt::ValueRef ovalue(_authors);

    if (_is_global && _authors.is_valid()) _authors.valueptr()->unmark_global();
    _authors= value;
    if (_is_global && _authors.is_valid()) _authors.valueptr()->mark_global();
    _changed_signal.emit("authors", ovalue);
  }

  grt::DictRef extras() const { return _extras; }
  virtual void extras(const grt::DictRef &value)
  {
    grt::ValueRef ovalue(_extras);
   _extras= value;
    _changed_signal.emit("extras", ovalue);
  }

  grt::IntegerRef pages() const { return _pages; }
  virtual void pages(const grt::IntegerRef &value)
  {
    grt::ValueRef ovalue(_pages);
   _pages= value;
    _changed_signal.emit("pages", ovalue);
  }

  grt::DoubleRef price() const { return _price; }
  virtual void price(const grt::DoubleRef &value)
  {
    grt::ValueRef ovalue(_price);
   _price= value;
    _changed_signal.emit("price", ovalue);
  }

  test_PublisherRef publisher() const { return _publisher; }
  virtual void publisher(const test_PublisherRef &value)
  {
    grt::ValueRef ovalue(_publisher);
   _publisher= value;
    _changed_signal.emit("publisher", ovalue);
  }

protected:

  grt::ListRef<test_Author> _authors;// owned
  grt::DictRef _extras;
  grt::IntegerRef _pages;
  grt::DoubleRef _price;
  test_PublisherRef _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 test_PublisherRef &)= &test_Book::publisher;
      test_PublisherRef (test_Book::*getter)() const= &test_Book::publisher;
      meta->bind_member("publisher", new grt::MetaClass::Property<test_Book,test_PublisherRef >(getter,setter));
    }
  }
};


class  test_Author : public test_Base
{
public:
  class ImplData;
  friend class ImplData;
  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"; }

  grt::StringRef name() const { return _name; }
  virtual void name(const grt::StringRef &value)
  {
    grt::ValueRef ovalue(_name);
   _name= value;
    _changed_signal.emit("name", ovalue);
  }

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_Publisher : public test_Base
{
public:
  class ImplData;
  friend class ImplData;
  test_Publisher(grt::GRT *grt, grt::MetaClass *meta=0)
  : test_Base(grt, meta ? meta : grt->get_metaclass(static_class_name())),
     _name(""),
     _phone("")

  {
  }

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

  grt::StringRef name() const { return _name; }
  virtual void name(const grt::StringRef &value)
  {
    grt::ValueRef ovalue(_name);
   _name= value;
    _changed_signal.emit("name", ovalue);
  }

  grt::StringRef phone() const { return _phone; }
  virtual void phone(const grt::StringRef &value)
  {
    grt::ValueRef ovalue(_phone);
   _phone= value;
    _changed_signal.emit("phone", ovalue);
  }

protected:

  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::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_Bridged : public grt::internal::Object
{
public:
  class ImplData;
  friend class ImplData;
  test_Bridged(grt::GRT *grt, grt::MetaClass *meta=0)
  : grt::internal::Object(grt, meta ? meta : grt->get_metaclass(static_class_name())),
    _books(grt, this),
     _name(""),
     _x(),
     _y()

  {
  }

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

  grt::ListRef<test_Book> books() const { return _books; }
  virtual void books(const grt::ListRef<test_Book> &value)
  {
    grt::ValueRef ovalue(_books);
   _books= value;
    _changed_signal.emit("books", ovalue);
  }

  grt::StringRef name() const { return _name; }
  virtual void name(const grt::StringRef &value)
  {
    grt::ValueRef ovalue(_name);
   _name= value;
    _changed_signal.emit("name", ovalue);
  }

  grt::IntegerRef x() const { return _x; }
  virtual void x(const grt::IntegerRef &value)
  {
    grt::ValueRef ovalue(_x);
   _x= value;
    _changed_signal.emit("x", ovalue);
  }

  grt::IntegerRef y() const { return _y; }
  virtual void y(const grt::IntegerRef &value)
  {
    grt::ValueRef ovalue(_y);
   _y= value;
    _changed_signal.emit("y", ovalue);
  }

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));
    }
  }
};




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

#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
