/* 
 * Copyright (c) 2008, 2012, 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 __MYSQL_TABLE_EDITOR_BE_H__
#define __MYSQL_TABLE_EDITOR_BE_H__

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

using namespace MySQL::Grt;
using namespace System;
using namespace System::Windows::Forms;
using namespace System::Collections::Generic;

namespace MySQL {
namespace Grt {
namespace Db {

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,
    IsUnique= ::bec::TableColumnsListBE::IsUnique,
    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:
  MySQLTableEditorBE(GrtManager^ grtm, GrtValue^ arglist);

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

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

  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, bool sync)
  { get_unmanaged_object()->set_triggers_sql(NativeToCppString(sql), sync); }

  String^ get_all_triggers_sql()
  { return CppStringToNative(get_unmanaged_object()->get_all_triggers_sql()); }
  
  Control ^get_trigger_panel();
  void commit_changes();

  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 Db
};  // namespace Grt
};  // namespace MySQL

#endif // __MYSQL_TABLE_EDITOR_BE_H__