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

/**
 * Contains the implementation of the wrapper for a .NET form used by the mforms backend.
 */

#include "stdafx.h"

#include "mforms/mforms.h"
#include "wf_view.h"
#include "wf_box.h"
#include "wf_appview.h"
#include "wf_menubar.h"
#include "wf_toolbar.h"

#include "ConvUtils.h"

using namespace System::Drawing::Drawing2D;

using namespace MySQL::Forms;
using namespace MySQL::Controls;

//--------------------------------------------------------------------------------------------------

bool AppViewImpl::create(::mforms::AppView *self, bool horizontal)
{
  AppViewImpl^ appview= gcnew AppViewImpl(self);

  if (appview != nullptr)
  {
    // The next steps are the same as with a BoxImpl.
    Box^ native_box= ViewImpl::create<Box>(self, appview);
    native_box->Horizontal= horizontal;
    self->set_resize_mode(::mforms::ResizeNone);

    return true;
  }
  return false;
}

//--------------------------------------------------------------------------------------------------

/**
 * Called when this app view is about to be docked in a host container. Create the front end
 * tab document if not yet done and return it to the caller.
 */
TabDocument^ AppViewImpl::GetHost()
{
  if (_host == nullptr)
    setup();
  return _host;
}

//--------------------------------------------------------------------------------------------------

MenuStrip^ AppViewImpl::GetMenuBar()
{
  mforms::MenuBar* menu = _appView->get_menubar();
  if (menu == NULL)
    return nullptr;

  MenuBarImpl^ menubar_impl = (MenuBarImpl^) ViewImpl::FromUnmanaged(menu);

  return menubar_impl->get_control<MenuStrip>();
}

//--------------------------------------------------------------------------------------------------

ToolStrip^ AppViewImpl::GetToolBar()
{
  mforms::ToolBar* toolbar = _appView->get_toolbar();
  if (toolbar == NULL)
    return nullptr;

  ToolBarImpl^ toolbar_impl = (ToolBarImpl^) ViewImpl::FromUnmanaged(toolbar);

  return toolbar_impl->get_control<ToolStrip>();
}

//--------------------------------------------------------------------------------------------------

String^ AppViewImpl::GetTitle()
{
  return CppStringToNativeRaw(_appView->get_title());
}

//--------------------------------------------------------------------------------------------------

bool AppViewImpl::DocumentClosing()
{
  Control^ control= get_control<Control>();

  if (control->Tag != nullptr)
  {
    ::mforms::AppView* view= ViewImpl::get_backend_control<::mforms::AppView>(control);
    if (view != NULL)
      return view->on_close();
  }
  return true;
}

//--------------------------------------------------------------------------------------------------

AppViewImpl::AppViewImpl(::mforms::AppView* app)
  : BoxImpl(app), _appView(app)
{
}

//--------------------------------------------------------------------------------------------------

AppViewImpl::~AppViewImpl()
{
  delete _host;
}

//--------------------------------------------------------------------------------------------------

void AppViewImpl::setup()
{
  // In order to ease maintenance we create a special document host for our content.
  _host = gcnew AppViewDockContent(this);
  Control^ control = get_control<Control>();
  _host->Controls->Add(control);
  control->Dock = DockStyle::Fill;
}

//--------------------------------------------------------------------------------------------------

void AppViewImpl::ContentPanelPaint(System::Object^ sender, PaintEventArgs^ e)
{
  Graphics^ g = e->Graphics;
  g->SmoothingMode = SmoothingMode::None;

  System::Drawing::Rectangle clientArea = ((Windows::Forms::Panel^)(sender))->ClientRectangle;

  Pen^ pen = gcnew Pen(Color::FromArgb(175, 210, 239), 1);
  g->DrawRectangle(pen, clientArea.Left, clientArea.Top, clientArea.Width - 1, clientArea.Height - 1);
  delete pen;
}

//--------------------------------------------------------------------------------------------------

void AppViewImpl::MenuPanelPaint(System::Object^ sender, PaintEventArgs^ e)
{
  Graphics^ g = e->Graphics;
  Windows::Forms::Panel^ panel = dynamic_cast<Windows::Forms::Panel^>(sender);

  ToolStripHelper::MenuPanelPaint(g, panel->ClientRectangle);
}

//----------------- AppViewDockContent -------------------------------------------------------------

AppViewDockContent::AppViewDockContent(AppViewImpl^ appview)
{
  _appview= appview;
  _appview->get_unmanaged_object()->retain();
};

//--------------------------------------------------------------------------------------------------

AppViewDockContent::~AppViewDockContent()
{
  _appview->get_unmanaged_object()->release();
  _appview= nullptr;
}

//--------------------------------------------------------------------------------------------------

AppViewImpl^ AppViewDockContent::GetAppView()
{
  return _appview;
};

//--------------------------------------------------------------------------------------------------

mforms::AppView* AppViewDockContent::get_unmanaged_object()
{
  return _appview->get_unmanaged_object();
}

//--------------------------------------------------------------------------------------------------

String^ AppViewDockContent::GetAppViewIdentifier()
{
  return CppStringToNative(_appview->get_unmanaged_object()->identifier());
}

//--------------------------------------------------------------------------------------------------
