/* 
 * © 2009 Sun Microsystems, Inc.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */
/**
 * Contains the implementation of the wrapper for a .NET form used by the mforms backend.
 */

#include "stdafx.h"

#include "wf_form.h"

using namespace System;
using namespace Drawing;
using namespace Windows::Forms;

using namespace MySQL;
using namespace MySQL::Forms;

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

bool FormImpl::create(::mforms::Form *self, ::mforms::Form *owner, ::mforms::FormFlag flag)
{
  FormImpl ^form= gcnew FormImpl(self, owner, flag);

  if (form != nullptr)
  {
    Windows::Forms::Form ^f= ViewImpl::create<Form>(self, form);
    f->StartPosition= FormStartPosition::CenterScreen;
    f->Disposed += gcnew System::EventHandler(&FormImpl::disposed);
    return true;
  }
  return false;
}

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

void FormImpl::set_title(::mforms::Form *self, const std::string &title)
{
  FormImpl^ form= (FormImpl^)ObjectImpl::FromUnmanaged(self);

  if (form != nullptr)
    form->get_control<Form>()->Text= gcnew String(title.c_str());
}

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

void FormImpl::show_modal(::mforms::Form *self, ::mforms::Button *accept,::mforms::Button *cancel)
{
  FormImpl^ form= (FormImpl^)ObjectImpl::FromUnmanaged(self);

  if (form != nullptr)
  {
    Form ^f= form->get_control<Form>();

    if (accept)
    {
      f->AcceptButton= ((ViewImpl^)ObjectImpl::FromUnmanaged(accept))->get_control<Button>();
      f->AcceptButton->DialogResult= DialogResult::OK;
    }
    if (cancel)
    {
      f->CancelButton= ((ViewImpl^)ObjectImpl::FromUnmanaged(cancel))->get_control<Button>();
      f->CancelButton->DialogResult= DialogResult::Cancel;
    }
    // Make the window top most (so it stays above all others), but non-blocking.
    f->TopMost= true;
    f->Show();
  }
}

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

bool FormImpl::run_modal(::mforms::Form *self, ::mforms::Button *accept,::mforms::Button *cancel)
{
  FormImpl^ form= (FormImpl^)ObjectImpl::FromUnmanaged(self);

  if (form != nullptr)
  {
    Form ^f= form->get_control<Form>();

    if (accept)
    {
      f->AcceptButton= ((ViewImpl^)ObjectImpl::FromUnmanaged(accept))->get_control<Button>();
      f->AcceptButton->DialogResult= DialogResult::OK;
    }
    if (cancel)
    {
      f->CancelButton= ((ViewImpl^)ObjectImpl::FromUnmanaged(cancel))->get_control<Button>();
      f->CancelButton->DialogResult= DialogResult::Cancel;
    }
    return f->ShowDialog() == DialogResult::OK;
  }
  return false;
}

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

/**
 * Called by the backend when a form is closed from the application side.
 */
void FormImpl::close(::mforms::Form *self)
{
  FormImpl^ form= (FormImpl^)ObjectImpl::FromUnmanaged(self);

  if (form != nullptr)
    form->get_control<Form>()->Close();
}

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

void FormImpl::set_content(::mforms::Form *self, ::mforms::View *view)
{
  FormImpl^ form= (FormImpl^)ObjectImpl::FromUnmanaged(self);

  if (form != nullptr)
  {
    view->set_resize_mode(mforms::ResizeNone);
    ViewImpl^ child= (ViewImpl^)ObjectImpl::FromUnmanaged(view);
    Control^ ctl= child->get_control<Control>();
    ctl->Dock= DockStyle::Fill;

    form->get_control<Form>()->Controls->Add(ctl);
  }
}

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


void FormImpl::center(::mforms::Form *self)
{
  FormImpl^ form= (FormImpl^)ObjectImpl::FromUnmanaged(self);
  if (form != nullptr)
    form->center();
}

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

void FormImpl::flush_events(::mforms::Form *self)
{
  FormImpl^ form= (FormImpl^)ObjectImpl::FromUnmanaged(self);
  if (form != nullptr)
    form->flush_events();
}

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

FormImpl::FormImpl(::mforms::Form *form, ::mforms::Form *owner, ::mforms::FormFlag flag)
  : ViewImpl(form)
{
}

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

/**
 * Centers the form on the screen which currently contains the largest portion of it.
 */
void FormImpl::center()
{
  Form^ form= get_control<Form>();
  Screen^ screen= Screen::FromControl(form);
  Drawing::Rectangle workingArea= screen->WorkingArea;
  form->Location= Point((workingArea.Width - form->Width) / 2, (workingArea.Height - form->Height) / 2);
}

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

void FormImpl::flush_events()
{
  Application::DoEvents();
}

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

/**
 * Called by the OS if the form is destroyed by the user (e.g. via red cross close button and
 * the form is set to destroy itself when closed).
 */
void FormImpl::disposed(System::Object ^sender, System::EventArgs ^e)
{
  Windows::Forms::Form^ native_form= (Windows::Forms::Form^)sender;

  if (native_form->Tag != nullptr)
  {
    ::mforms::Form* form= reinterpret_cast<::mforms::Form*>(((IntPtr^)native_form->Tag)->ToPointer());
    form->was_closed();
    delete form;
  }
}

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