/*
 * File automatically generated by
 * gengen 1.0 by Lorenzo Bettini 
 * http://www.gnu.org/software/gengen
 */

#ifndef CLASS_GEN_CLASS_H
#define CLASS_GEN_CLASS_H

#include <string>
#include <iostream>

using std::string;
using std::ostream;

class class_gen_class
{
 protected:
  string author;
  string classname;
  string classnameinclude;
  bool destructor;
  string fields;
  string generate;
  bool genstring;
  bool hasinitializations;
  string initdefaults;
  bool memberwiseconstructor;
  string othercomments;
  string package;
  string paramassignments;
  string params;
  string setmethods;
  string version;

 public:
  class_gen_class() :
    destructor (false), genstring (false), hasinitializations (false), memberwiseconstructor (false)
  {
  }
  
  class_gen_class(const string &_author, const string &_classname, const string &_classnameinclude, bool _destructor, const string &_fields, const string &_generate, bool _genstring, bool _hasinitializations, const string &_initdefaults, bool _memberwiseconstructor, const string &_othercomments, const string &_package, const string &_paramassignments, const string &_params, const string &_setmethods, const string &_version) :
    author (_author), classname (_classname), classnameinclude (_classnameinclude), destructor (_destructor), fields (_fields), generate (_generate), genstring (_genstring), hasinitializations (_hasinitializations), initdefaults (_initdefaults), memberwiseconstructor (_memberwiseconstructor), othercomments (_othercomments), package (_package), paramassignments (_paramassignments), params (_params), setmethods (_setmethods), version (_version)
  {
  }

  virtual ~class_gen_class()
  {
  }

  static void
  generate_string(const string &s, ostream &stream, unsigned int indent)
  {
    if (!indent || s.find('\n') == string::npos)
      {
        stream << s;
        return;
      }

    string::size_type pos;
    string::size_type start = 0;
    string ind (indent, ' ');
    while ( (pos=s.find('\n', start)) != string::npos)
      {
        stream << s.substr (start, (pos+1)-start);
        start = pos+1;
        if (start+1 <= s.size ())
          stream << ind;
      }
    if (start+1 <= s.size ())
      stream << s.substr (start);
  }

  void set_author(const string &_author)
  {
    author = _author;
  }

  void set_classname(const string &_classname)
  {
    classname = _classname;
  }

  void set_classnameinclude(const string &_classnameinclude)
  {
    classnameinclude = _classnameinclude;
  }

  void set_destructor(bool _destructor)
  {
    destructor = _destructor;
  }

  virtual void generate_fields(ostream &stream, unsigned int indent) = 0;

  void set_fields(const string &_fields)
  {
    fields = _fields;
  }

  virtual void generate_generate(ostream &stream, unsigned int indent) = 0;

  void set_generate(const string &_generate)
  {
    generate = _generate;
  }

  void set_genstring(bool _genstring)
  {
    genstring = _genstring;
  }

  void set_hasinitializations(bool _hasinitializations)
  {
    hasinitializations = _hasinitializations;
  }

  void set_initdefaults(const string &_initdefaults)
  {
    initdefaults = _initdefaults;
  }

  void set_memberwiseconstructor(bool _memberwiseconstructor)
  {
    memberwiseconstructor = _memberwiseconstructor;
  }

  void set_othercomments(const string &_othercomments)
  {
    othercomments = _othercomments;
  }

  void set_package(const string &_package)
  {
    package = _package;
  }

  void set_paramassignments(const string &_paramassignments)
  {
    paramassignments = _paramassignments;
  }

  void set_params(const string &_params)
  {
    params = _params;
  }

  virtual void generate_setmethods(ostream &stream, unsigned int indent) = 0;

  void set_setmethods(const string &_setmethods)
  {
    setmethods = _setmethods;
  }

  void set_version(const string &_version)
  {
    version = _version;
  }

  void generate_class(ostream &stream, unsigned int indent = 0)
  {
    string indent_str (indent, ' ');
    indent = 0;
  
    stream << "/*";
    stream << "\n";
    stream << indent_str;
    stream << " * File automatically generated by";
    stream << "\n";
    stream << indent_str;
    stream << " * ";
    generate_string (package, stream, indent + indent_str.length ());
    stream << " ";
    generate_string (version, stream, indent + indent_str.length ());
    stream << " ";
    generate_string (author, stream, indent + indent_str.length ());
    stream << "\n";
    stream << indent_str;
    stream << " * ";
    generate_string (othercomments, stream, indent + indent_str.length ());
    stream << "\n";
    stream << indent_str;
    stream << " */";
    stream << "\n";
    stream << indent_str;
    stream << "\n";
    stream << indent_str;
    stream << "#ifndef ";
    generate_string (classnameinclude, stream, indent + indent_str.length ());
    stream << "\n";
    stream << indent_str;
    stream << "#define ";
    generate_string (classnameinclude, stream, indent + indent_str.length ());
    stream << "\n";
    stream << indent_str;
    stream << "\n";
    stream << indent_str;
    stream << "#include <string>";
    stream << "\n";
    stream << indent_str;
    stream << "#include <iostream>";
    stream << "\n";
    stream << indent_str;
    stream << "\n";
    stream << indent_str;
    stream << "using std::string;";
    stream << "\n";
    stream << indent_str;
    stream << "using std::ostream;";
    stream << "\n";
    stream << indent_str;
    stream << "\n";
    stream << indent_str;
    stream << "class ";
    generate_string (classname, stream, indent + indent_str.length ());
    stream << "\n";
    stream << indent_str;
    stream << "{";
    stream << "\n";
    stream << indent_str;
    stream << " protected:";
    stream << "\n";
    stream << indent_str;
    indent = 2;
    if (fields.size () > 0)
      generate_string (fields, stream, indent + indent_str.length ());
    else
      generate_fields (stream, indent + indent_str.length ());
    indent = 0;
    stream << indent_str;
    stream << "\n";
    stream << indent_str;
    stream << " public:";
    stream << "\n";
    stream << indent_str;
    indent = 2;
    stream << "  ";
    generate_string (classname, stream, indent + indent_str.length ());
    stream << "()";
    if (hasinitializations)
      {
        stream << " :";
        stream << "\n";
        stream << indent_str;
        indent = 4;
        stream << "    ";
        generate_string (initdefaults, stream, indent + indent_str.length ());
        indent = 0;
        stream << "\n";
        stream << indent_str;
      }
    else
      {
        stream << "\n";
        stream << indent_str;
      }
    stream << "  {";
    indent = 0;
    stream << "\n";
    stream << indent_str;
    stream << "  }";
    stream << "\n";
    stream << indent_str;
    indent = 2;
    stream << "  ";
    if (memberwiseconstructor)
      {
        stream << "\n";
        stream << indent_str;
        indent = 2;
        stream << "  ";
        generate_string (classname, stream, indent + indent_str.length ());
        stream << "(";
        generate_string (params, stream, indent + indent_str.length ());
        stream << ") :";
        indent = 0;
        stream << "\n";
        stream << indent_str;
        indent = 4;
        stream << "    ";
        generate_string (paramassignments, stream, indent + indent_str.length ());
        indent = 0;
        stream << "\n";
        stream << indent_str;
        stream << "  {";
        stream << "\n";
        stream << indent_str;
        stream << "  }";
      }
    indent = 0;
    stream << "\n";
    stream << indent_str;
    if (destructor)
      {
        stream << "\n";
        stream << indent_str;
        stream << "  virtual ~";
        generate_string (classname, stream, indent + indent_str.length ());
        stream << "()";
        stream << "\n";
        stream << indent_str;
        stream << "  {";
        stream << "\n";
        stream << indent_str;
        stream << "  }";
        stream << "\n";
        stream << indent_str;
      }
    if (genstring)
      {
        stream << "\n";
        stream << indent_str;
        stream << "  static void";
        stream << "\n";
        stream << indent_str;
        stream << "  generate_string(const string &s, ostream &stream, unsigned int indent)";
        stream << "\n";
        stream << indent_str;
        stream << "  {";
        stream << "\n";
        stream << indent_str;
        stream << "    if (!indent || s.find('\\n') == string::npos)";
        stream << "\n";
        stream << indent_str;
        stream << "      {";
        stream << "\n";
        stream << indent_str;
        stream << "        stream << s;";
        stream << "\n";
        stream << indent_str;
        stream << "        return;";
        stream << "\n";
        stream << indent_str;
        stream << "      }";
        stream << "\n";
        stream << indent_str;
        stream << "\n";
        stream << indent_str;
        stream << "    string::size_type pos;";
        stream << "\n";
        stream << indent_str;
        stream << "    string::size_type start = 0;";
        stream << "\n";
        stream << indent_str;
        stream << "    string ind (indent, ' ');";
        stream << "\n";
        stream << indent_str;
        stream << "    while ( (pos=s.find('\\n', start)) != string::npos)";
        stream << "\n";
        stream << indent_str;
        stream << "      {";
        stream << "\n";
        stream << indent_str;
        stream << "        stream << s.substr (start, (pos+1)-start);";
        stream << "\n";
        stream << indent_str;
        stream << "        start = pos+1;";
        stream << "\n";
        stream << indent_str;
        stream << "        if (start+1 <= s.size ())";
        stream << "\n";
        stream << indent_str;
        stream << "          stream << ind;";
        stream << "\n";
        stream << indent_str;
        stream << "      }";
        stream << "\n";
        stream << indent_str;
        stream << "    if (start+1 <= s.size ())";
        stream << "\n";
        stream << indent_str;
        stream << "      stream << s.substr (start);";
        stream << "\n";
        stream << indent_str;
        stream << "  }";
        stream << "\n";
        stream << indent_str;
      }
    stream << "\n";
    stream << indent_str;
    indent = 2;
    if (setmethods.size () > 0)
      generate_string (setmethods, stream, indent + indent_str.length ());
    else
      generate_setmethods (stream, indent + indent_str.length ());
    indent = 0;
    stream << indent_str;
    indent = 2;
    stream << "  ";
    if (generate.size () > 0)
      generate_string (generate, stream, indent + indent_str.length ());
    else
      generate_generate (stream, indent + indent_str.length ());
    indent = 0;
    stream << "\n";
    stream << indent_str;
    stream << "};";
    stream << "\n";
    stream << indent_str;
    stream << "\n";
    stream << indent_str;
    stream << "#endif // ";
    generate_string (classnameinclude, stream, indent + indent_str.length ());
    stream << "\n";
    stream << indent_str;
  }
};

#endif // CLASS_GEN_CLASS_H
