#ifndef __MYSQL_TABLE_EDITOR_BE_H__
#define __MYSQL_TABLE_EDITOR_BE_H__

#include "mysql_table_editor.h"
#include "grtpp.h"
#include "GrtTemplates.h"

#ifdef _MSC_VER
//#include  <vcclr.h> // .net interop helpers
using namespace MySQL::Grt;
using namespace System;
using namespace System::Collections::Generic;
using namespace System::Runtime::InteropServices;
#endif

namespace MySQL {
namespace GUI {
namespace Workbench {
namespace Plugins {

ref class MySQLTableEditorBE;

public ref class MySQLTableColumnsListBE : public Db::TableColumnsListBE
{
public:
  enum class MySQLColumnListColumns
  {
    Name= ::bec::TableColumnsListBE::Name,
    Type= ::bec::TableColumnsListBE::Type,
    IsPK= ::bec::TableColumnsListBE::IsPK,
    IsNotNull= ::bec::TableColumnsListBE::IsNotNull,
    IsBinary = ::bec::TableColumnsListBE::IsBinary,
    IsUnsigned = ::bec::TableColumnsListBE::IsUnsigned,
    IsZerofill = ::bec::TableColumnsListBE::IsZerofill,
    Flags= ::bec::TableColumnsListBE::Flags,
    Default= ::bec::TableColumnsListBE::Default,
    CharsetCollation= ::bec::TableColumnsListBE::CharsetCollation,
    Charset= ::bec::TableColumnsListBE::Charset,
    Collation= ::bec::TableColumnsListBE::Collation,
    HasCharset= ::bec::TableColumnsListBE::HasCharset,
    Comment= ::bec::TableColumnsListBE::Comment,
    IsAutoIncrement= ::MySQLTableColumnsListBE::IsAutoIncrement,
    IsAutoIncrementable= ::MySQLTableColumnsListBE::IsAutoIncrementable
  };

  //MySQLTableColumnsListBE(MySQLTableEditorBE^ owner);

  MySQLTableColumnsListBE(::MySQLTableColumnsListBE *inn);

  inline ::MySQLTableColumnsListBE *get_unmanaged_object()
  { return static_cast<::MySQLTableColumnsListBE *>(inner); }

  //virtual bool set_field(const NodeId &node, int column, String^ value);
  bool set_column_type(NodeId ^nodeid, GrtValue^ value)
  {
    return get_unmanaged_object()->set_column_type(*nodeid->get_unmanaged_object(), GrtObjectRef::cast_from(value->get_unmanaged_object()));
  }

  List<String^>^ get_datatype_flags(NodeId ^nodeid)
  { return CppStringListToNative(get_unmanaged_object()->get_datatype_flags(*nodeid->get_unmanaged_object())); }

  void set_column_flag(NodeId ^nodeid, String^ flag_name, int is_set)
  { get_unmanaged_object()->set_column_flag(*nodeid->get_unmanaged_object(), NativeToCppString(flag_name), is_set); }

  int get_column_flag(NodeId ^nodeid, String^ flag_name)
  { return get_unmanaged_object()->get_column_flag(*nodeid->get_unmanaged_object(), NativeToCppString(flag_name)); }

  /*
  void set_column_flags(NodeId ^nodeid, List<String^>^ flags)
  { get_unmanaged_object()->set_column_flags(*nodeid->get_unmanaged_object(), NativeToCppStringList(flags)); }

  List<String^>^ get_column_flags(NodeId ^nodeid)
  { return CppStringListToNative(get_unmanaged_object()->get_column_flags(*nodeid->get_unmanaged_object())); }
  */

};


public ref class MySQLIndexListBE : public Db::IndexListBE
{
public:
  MySQLIndexListBE(::MySQLTableIndexListBE *inner) : Db::IndexListBE(inner) {}

  enum class Columns {
    StorageType = ::MySQLTableIndexListBE::StorageType,
    RowBlockSize = ::MySQLTableIndexListBE::RowBlockSize,
    Parser = ::MySQLTableIndexListBE::Parser
  };
};



public ref class MySQLTablePartitionTreeBE : public TreeModel
{
public:
  MySQLTablePartitionTreeBE(::MySQLTablePartitionTreeBE *inner) : TreeModel(inner) {}

  enum class Columns {
    Name= ::MySQLTablePartitionTreeBE::Name,
    Value= ::MySQLTablePartitionTreeBE::Value,
    MinRows= ::MySQLTablePartitionTreeBE::MinRows,
    MaxRows= ::MySQLTablePartitionTreeBE::MaxRows,
    DataDirectory= ::MySQLTablePartitionTreeBE::DataDirectory,
    IndexDirectory= ::MySQLTablePartitionTreeBE::IndexDirectory,
    Comment= ::MySQLTablePartitionTreeBE::Comment
  };
};



public ref class MySQLTableEditorBE : public Db::TableEditorBE
{
public:
  // this one
  //MySQLTableEditorBE(GRTManager *grtm, const db_mysql_TableRef &table, const db_mgmt_RdbmsRef &rdbms);
  // replaced with this one
  MySQLTableEditorBE(GrtManager^ grtm, GrtValue^ arglist);

  //XXX this should be removed at some time
  bool is_new_table() { return get_unmanaged_object()->table()->createDate() == get_unmanaged_object()->table()->lastChangeDate(); }

  ::MySQLTableEditorBE *get_unmanaged_object()
  { return static_cast<::MySQLTableEditorBE *>(inner); }

  virtual MySQLTableColumnsListBE^ get_columns();

  void set_table_option_by_name(System::String^ name, System::String^ value)
  { get_unmanaged_object()->set_table_option_by_name(NativeToCppString(name), NativeToCppString(value)); }

  List<String^>^ get_engines_list()
  { return CppStringListToNative(get_unmanaged_object()->get_engines_list()); }

  List<String^>^ get_index_storage_types()
  { return CppStringListToNative(get_unmanaged_object()->get_index_storage_types()); }

  List<String^>^ get_fk_action_options()
  { return CppStringListToNative(get_unmanaged_object()->get_fk_action_options()); }

  String^ MySQLTableEditorBE::get_table_option_by_name(String^ name)
  { return CppStringToNative(get_unmanaged_object()->get_table_option_by_name(NativeToCppString(name))); }

  void set_triggers_sql(String^ sql)
  { get_unmanaged_object()->set_triggers_sql(NativeToCppString(sql)); }

  String^ get_all_triggers_sql()
  { return CppStringToNative(get_unmanaged_object()->get_all_triggers_sql()); }
  //

  bool set_partition_type(String^ type)
  { return get_unmanaged_object()->set_partition_type(NativeToCppString(type)); }

  String^ get_partition_type()
  { return CppStringToNative(get_unmanaged_object()->get_partition_type()); }
 
  void set_partition_expression(String^ expr)
  { get_unmanaged_object()->set_partition_expression(NativeToCppString(expr)); }

  String^ get_partition_expression()
  { return CppStringToNative(get_unmanaged_object()->get_partition_expression()); }

  void set_partition_count(int count)
  { get_unmanaged_object()->set_partition_count(count); }

  int get_partition_count()
  { return get_unmanaged_object()->get_partition_count(); }

  bool set_subpartition_type(String^ type)
  { return get_unmanaged_object()->set_subpartition_type(NativeToCppString(type)); }

  String^ get_subpartition_type()
  { return CppStringToNative(get_unmanaged_object()->get_subpartition_type()); }
 
  bool set_subpartition_expression(String^ expr)
  { return get_unmanaged_object()->set_subpartition_expression(NativeToCppString(expr)); }

  String^ get_subpartition_expression()
  { return CppStringToNative(get_unmanaged_object()->get_subpartition_expression()); }

  void set_subpartition_count(int count)
  { get_unmanaged_object()->set_subpartition_count(count); }

  int get_subpartition_count()
  { return get_unmanaged_object()->get_subpartition_count(); }

  MySQLTablePartitionTreeBE^ get_partitions();

  // whether partitions and subpartitions will be defined by the user or not 
  // if false, only count is needed otherwise the partitionslist must be defined
  void set_explicit_partitions(bool flag)
  { get_unmanaged_object()->set_explicit_partitions(flag); }

  void set_explicit_subpartitions(bool flag)
  { get_unmanaged_object()->set_explicit_subpartitions(flag); }

  bool get_explicit_partitions()
  { return get_unmanaged_object()->get_explicit_partitions(); }

  bool get_explicit_subpartitions()
  { return get_unmanaged_object()->get_explicit_subpartitions(); }
};


};  // namespace Plugins
};  // namespace Workbench
};  // namespace GUI
};  // namespace MySQL

#endif // __MYSQL_TABLE_EDITOR_BE_H__