/* 
 * Copyright (c) 2009, 2013, 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 __OVERVIEW_H__
#define __OVERVIEW_H__

namespace MySQL {
  namespace Workbench {

    public ref class Overview : public ::MySQL::Grt::TreeModel
    {
    protected:
      ref class OverviewUIForm : public ::MySQL::Base::UIForm
      {
      public:
        OverviewUIForm(::bec::UIForm *inn)
          : MySQL::Base::UIForm(inn)
        {}
      };

      OverviewUIForm^ uiform;

    public:
      enum class Columns
      {
        Label= ::wb::OverviewBE::Label,
        NodeType = ::wb::OverviewBE::NodeType,
        ChildNodeType = ::wb::OverviewBE::ChildNodeType,
        Expanded = ::wb::OverviewBE::Expanded,
        Height = ::wb::OverviewBE::Height,
        DisplayMode = ::wb::OverviewBE::DisplayMode,

        FirstDetailField = ::wb::OverviewBE::FirstDetailField
      };
      enum class NodeType
      {
        Root= ::wb::OverviewBE::ORoot,
        Division= ::wb::OverviewBE::ODivision,
        Group= ::wb::OverviewBE::OGroup,
        Section= ::wb::OverviewBE::OSection,
        Item= ::wb::OverviewBE::OItem
      };
      enum class DisplayMode
      {
        None= ::wb::OverviewBE::MNone,
        LargeIcon= ::wb::OverviewBE::MLargeIcon,
        SmallIcon= ::wb::OverviewBE::MSmallIcon,
        List= ::wb::OverviewBE::MList
      };

      inline ::wb::OverviewBE *get_unmanaged_object()
      { return static_cast<::wb::OverviewBE*>(TreeModel::get_unmanaged_object()); }


      Overview(::wb::OverviewBE *inn)
        : ::MySQL::Grt::TreeModel(inn)
      { 
        uiform = gcnew OverviewUIForm(inn);
      }

      ~Overview()
      {
        uiform->init(NULL); // Reset the BE MySQL::Base::UIForm reference. It is a shared one not managed by the overview.
        delete uiform;
      }

      MySQL::Base::UIForm^ get_uiform()
      {
        return uiform;
      }

      bool matches_handle(System::IntPtr handle)
      {
        return (dynamic_cast<bec::UIForm*>(get_unmanaged_object()) == reinterpret_cast<bec::UIForm*>(handle.ToPointer()));
      }

      System::String^ get_title()
      {
        std::string title= get_unmanaged_object()->get_title();
        if (title.empty())
          return nullptr;
        return CppStringToNative(title);
      }

      System::String^ get_node_unique_id(::MySQL::Grt::NodeId^ node)
      {
        std::string id= get_unmanaged_object()->get_node_unique_id(*node->get_unmanaged_object());
        if (id.empty()) return nullptr;
        return CppStringToNative(id);
      }


      ::MySQL::Grt::NodeId^ get_focused_child(::MySQL::Grt::NodeId^ node)
      {
        return gcnew ::MySQL::Grt::NodeId(&get_unmanaged_object()->get_focused_child(*node->get_unmanaged_object())); 
      }

      void select_node(::MySQL::Grt::NodeId^ node)
      {
        get_unmanaged_object()->select_node(*node->get_unmanaged_object());
      }

      System::Collections::Generic::List<int>^ get_selected_children(::MySQL::Grt::NodeId^ node)
      {
        System::Collections::Generic::List<int>^ list= gcnew System::Collections::Generic::List<int>();

        std::list<int> items= get_unmanaged_object()->get_selected_children(*node->get_unmanaged_object());

        for (std::list<int>::iterator i= items.begin(); i != items.end(); ++i)
          list->Add(*i);

        return list;
      }

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

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

      void focus_node(::MySQL::Grt::NodeId^ node)
      {
        get_unmanaged_object()->focus_node(*node->get_unmanaged_object());
      }

      void begin_selection_marking()
      {
        get_unmanaged_object()->begin_selection_marking();
      }

      void end_selection_marking()
      {
        get_unmanaged_object()->end_selection_marking();
      }


      bool is_editable(::MySQL::Grt::NodeId^ node)
      {
        return get_unmanaged_object()->is_editable(*node->get_unmanaged_object());
      }

      bool request_add_object(::MySQL::Grt::NodeId^ node)
      {
        return get_unmanaged_object()->request_add_object(*node->get_unmanaged_object());
      }

      bool request_delete_object(::MySQL::Grt::NodeId^ node)
      {
          return get_unmanaged_object()->request_delete_object(*node->get_unmanaged_object());
      }

      bool request_delete_selection()
      {
        return get_unmanaged_object()->request_delete_selected();
      }

      void refresh_node(::MySQL::Grt::NodeId^ node, bool children)
      {
        try
        {
          get_unmanaged_object()->refresh_node(*node->get_unmanaged_object(), children);
        }
        catch (std::exception &exc)
        {
          OutputDebugStringA(base::strfmt("Exception during overview refresh: %s\n", exc.what()).c_str());
        }
      }

      System::String ^get_field_name(::MySQL::Grt::NodeId^ node, int column)
      {
        std::string name= get_unmanaged_object()->get_field_name(*node->get_unmanaged_object(), column);
        return CppStringToNative(name);
      }

      int get_details_field_count(::MySQL::Grt::NodeId^ node)
      {
        return get_unmanaged_object()->get_details_field_count(*node->get_unmanaged_object());
      }

      ::MySQL::Grt::NodeId^ search_child_item_node_matching(::MySQL::Grt::NodeId ^node, 
                                                        ::MySQL::Grt::NodeId^ starting_node,
                                                        System::String ^text)
      {
        bec::NodeId cnode= node != nullptr ? *node->get_unmanaged_object() : bec::NodeId();
        bec::NodeId cstarting_node= starting_node != nullptr ? *starting_node->get_unmanaged_object() : bec::NodeId();

        bec::NodeId result= get_unmanaged_object()->search_child_item_node_matching(cnode, 
                                                          cstarting_node,
                                                          NativeToCppString(text));

        if (result.is_valid())
          return gcnew ::MySQL::Grt::NodeId(&result);
        return nullptr;
      }

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

      void close()
      {
        get_unmanaged_object()->close();
      }

      System::Collections::Generic::List<::MySQL::Base::ToolbarItem^> ^get_toolbar_items(::MySQL::Grt::NodeId^ node)
      {
        bec::ToolbarItemList items = get_unmanaged_object()->get_toolbar_items(*node->get_unmanaged_object());
        return MySQL::Grt::CppVectorToObjectList<::bec::ToolbarItem, ::MySQL::Base::ToolbarItem> (items);
      }

      bool activate_toolbar_item(::MySQL::Grt::NodeId^ node, System::String^ name)
      {
        return get_unmanaged_object()->activate_toolbar_item(*node->get_unmanaged_object(), NativeToCppString(name));
      }
    };

  } // namespace Workbench
} // namespace MySQL

#endif // __OVERVIEW_H__
