/* 
 * 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
 */

#include "stdafx.h"

#include "mforms/mforms.h"
#include "wf_view.h"
#include "wf_button.h"

#include "base/string_utilities.h"
#include "ConvUtils.h"

using namespace MySQL;
using namespace MySQL::Forms;
using namespace MySQL::Utilities;

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

ButtonImpl::ButtonImpl(mforms::Button *self)
  : ViewImpl(self)
{
}

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

bool ButtonImpl::create(mforms::Button *self, mforms::ButtonType btype)
{
  ButtonImpl ^button= gcnew ButtonImpl(self);

  if (button != nullptr)
  {
    Windows::Forms::Button^ native_button= ViewImpl::create<Windows::Forms::Button>(self, button);
    
    native_button->AutoSize = false;
    native_button->UseMnemonic= true;

    switch (btype)
    {
    case mforms::ToolButton:
      native_button->FlatStyle = FlatStyle::Flat;
      native_button->TabStop = false;
      native_button->Text = "";
      native_button->FlatAppearance->BorderSize = 0;
      break;

    case mforms::AdminActionButton:
      native_button->FlatStyle = FlatStyle::System; // Important, other styles don't work.

      // Show the shield icon only if we are running restricted. Otherwise it is meaningless.
      if (!ControlUtilities::ApplicationHasAdminRights())
        Button_SetElevationRequiredState((HWND) native_button->Handle.ToPointer(), true);
      break;

    default:
      native_button->FlatStyle = FlatStyle::System;
    }

    native_button->Click += gcnew System::EventHandler(&ButtonImpl::button_click);
    return true;
  }
  return false;
}

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

void ButtonImpl::set_text(mforms::Button *self, const std::string &text)
{
  ButtonImpl^ button= (ButtonImpl^)ObjectImpl::FromUnmanaged(self);

  if (button != nullptr)
  {
    // Note: DON'T try to replace underscores by ampersand to make the UI interpreting
    //       them as mnemonic chars (in conjunction with the following character).
    //       Underscores are VALID characters and here is the wrong place to handle this.
    //       Only the caller can know the context and has to do such replacements.
    Control^ control= button->get_control<Control>();
    control->Text= CppStringToNative(text);

    if (control->Padding.Left == 0 && button->_internal_padding)
      enable_internal_padding(self, true);

    // Resize the button to fit its content.
    // Keep the button's width, though, if that is currently larger than its preferred width.
    Size size= control->PreferredSize;
    if (size.Width < control->Width)
      size.Width= control->Width;
    control->Size= size;
  }
}

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

void ButtonImpl::set_icon(mforms::Button *self, const std::string &icon)
{
  ButtonImpl^ button= (ButtonImpl^)ObjectImpl::FromUnmanaged(self);

  if (button != nullptr)
  {
    Button^ control= button->get_control<Button>();
    String^ path = CppStringToNative(mforms::App::get()->get_resource_path(icon));
    if (IO::File::Exists(path))
      try
      {
        control->Image = Image::FromFile(path);

        // Resize the button to fit its content.
        Size size= control->PreferredSize;
        if (size.Width < control->Width)
          size.Width= control->Width;
        if (size.Height < control->Height)
          size.Height= control->Height;
        control->Size= size;
      }
      catch (...)
      {
        mforms::Utilities::show_error(_("Error while loading image"), _("An error occured while loading image ")
          + icon, _("Close"));
      }
  }
}
//-------------------------------------------------------------------------------------------------

void ButtonImpl::button_click(System::Object ^sender, System::EventArgs ^e)
{
  Windows::Forms::Button^ btn= (Windows::Forms::Button^)sender;

  if (btn->Tag != nullptr)
  {
    mforms::Button* button= ViewImpl::get_backend_control<mforms::Button>(btn);
    if (button != 0)
      button->callback();
  }
}

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

void ButtonImpl::enable_internal_padding(mforms::Button *self, bool flag)
{
  ButtonImpl^ button= (ButtonImpl^)ObjectImpl::FromUnmanaged(self);

  // The internal padding feature is just some beautifying added to the button
  // gives it a bit more room left and right of the text than what is the default
  // for it. It should actually be implemented via the View::set_padding function.
  
  Button^ native_button= button->get_control<Button>();
  if (flag)
  {
    if (native_button->Padding.Left == 0)
    {
      // Only add extra padding if that didn't happen already.
      int extra= 10;
      native_button->Padding= Padding::Add(native_button->Padding, Padding(extra, 0, extra, 0));
    }
  }
  else
  {
    native_button->Padding= Padding(0, 0, 0, 0);
  }

  button->_internal_padding= flag;
}

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

