#ifndef __DB_OBJECT_EDITOR_H__
#define __DB_OBJECT_EDITOR_H__

#include "grtdb/editor_dbobject.h"
#include "sql_editor_wr.h"
#include "Grt.h"
#include "GrtTemplates.h"
#include "BaseEditor.h"
#include "SigCSlot.h"


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

namespace MySQL {
namespace Grt {
namespace Db {

public ref class DBObjectEditorBE : public BaseEditor
{
protected:

  DBObjectEditorBE(::bec::DBObjectEditorBE *inn)
    : BaseEditor(inn)
  {}

public:
  ::bec::DBObjectEditorBE *get_unmanaged_object()
  { return static_cast<::bec::DBObjectEditorBE *>(inner); }

  //virtual db_DatabaseObject get_dbobject()= 0;
  //virtual db_mgmt_Rdbms get_rdbms() { return _rdbms; }

  String^ get_name()
  { return CppStringToNative(get_unmanaged_object()->get_name()); }
  
  void set_name(String^ name)
  { get_unmanaged_object()->set_name(NativeToCppString(name)); }

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

  void set_comment(String^ descr)
  { get_unmanaged_object()->set_comment(NativeToCppString(descr)); }

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

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

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

  void set_custom_data(String^ name, String^ value)
  { get_unmanaged_object()->set_custom_data(NativeToCppString(name), NativeToCppString(value)); }

  size_t count_custom_data()
  { return get_unmanaged_object()->count_custom_data(); }

  void get_custom_data(unsigned int index, [Out] String^ %name, [Out] String^ %value)
  {
    std::string name_str= NativeToCppString(name);
    std::string value_str= NativeToCppString(value);
    get_unmanaged_object()->set_custom_data(name_str, value_str);
    name= CppStringToNative(name_str);
    value= CppStringToNative(value_str);
  }

  void delete_custom_data(String ^name)
  { get_unmanaged_object()->delete_custom_data(NativeToCppString(name)); }

  // Helpers
  GrtValue^ get_catalog()
  {
    return gcnew GrtValue(static_cast<::bec::DBObjectEditorBE *>(inner)->get_catalog());
  }

  GrtValue^ get_schema()
  {
    return gcnew GrtValue(static_cast<::bec::DBObjectEditorBE *>(inner)->get_schema());
  }

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

  List<String^>^ get_all_table_names()
  {
    return CppStringListToNative(
      static_cast<::bec::DBObjectEditorBE *>(inner)->get_all_table_names());
  }

  List<String^>^ get_schema_table_names()
  {
    return CppStringListToNative(
      static_cast<::bec::DBObjectEditorBE *>(inner)->get_schema_table_names());
  }

  List<String^>^ get_table_column_names(String ^table_name)
  {
    List<String^>^ val= CppStringListToNative(
      static_cast<::bec::DBObjectEditorBE *>(inner)->get_table_column_names(NativeToCppString(table_name)));
    return val;
  }

  List<String^>^ get_table_column_names(GrtValue^ table)
  {
    return CppStringListToNative(
      static_cast<::bec::DBObjectEditorBE *>(inner)->get_table_column_names(db_TableRef::cast_from(table->get_unmanaged_object())));
  }

  List<String^>^ get_charset_collation_list()
  {
    return CppStringListToNative(
      static_cast<::bec::DBObjectEditorBE *>(inner)->get_charset_collation_list());
  }

  delegate void VoidStringListDelegate(List<String^>^);
  void set_sql_parser_log_cb(VoidStringListDelegate^ dt)
  {
    on_parse_sql_log_delegate= dt;
    on_parse_sql_log_wrapper_delegate= 
      gcnew VoidStringVectorWrapperDelegate(this, &DBObjectEditorBE::on_parse_sql_log_wrapper);
    IntPtr ip = Marshal::GetFunctionPointerForDelegate(on_parse_sql_log_wrapper_delegate);
    VOID_STRINGVECTOR_CB cb = static_cast<VOID_STRINGVECTOR_CB>(ip.ToPointer());
    get_unmanaged_object()->set_sql_parser_log_cb(sigc::ptr_fun(cb));
  }

  typedef DelegateSlot4<
    int, int,
    int, int,
    int, int,
    int, int,
    std::string, String^> ParseErrorDelegate;

  void set_sql_parser_err_cb(ParseErrorDelegate::ManagedDelegate ^cb)
  {
    on_parse_err_delegate= gcnew ParseErrorDelegate(cb);
    get_unmanaged_object()->set_sql_parser_err_cb(on_parse_err_delegate->get_slot());
  }

private:
  VoidStringListDelegate^ on_parse_sql_log_delegate;
  ParseErrorDelegate^ on_parse_err_delegate;

  delegate void VoidStringVectorWrapperDelegate(std::vector<std::string>);
  VoidStringVectorWrapperDelegate^ on_parse_sql_log_wrapper_delegate;

  typedef void (*DBObjectEditorBE::VOID_STRINGVECTOR_CB)(std::vector<std::string>);
  void on_parse_sql_log_wrapper(std::vector<std::string> stringvec)
  { on_parse_sql_log_delegate(CppStringListToNative(stringvec)); }
};

} // namespace Db
} // namespace Grt
} // namespace MySQL

#endif // __DB_OBJECT_EDITOR_H__
