/* 
 * Copyright (c) 2010, 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 _WF_APP_H_
#define _WF_APP_H_

#pragma make_public(mforms::App)

using namespace System;
using namespace System::Collections::Generic;
using namespace System::Runtime::InteropServices; // Needed for the [Out] keyword.

using namespace MySQL::Controls;

namespace MySQL {
  namespace Forms {
 
    public enum class AppCommand
    {
      AppQuit,
      AppGetResourcePath,
      AppSetStatusText,
      AppGetBounds,
    };

    ref class DockingPointDelegateWrapper;

    // A managed version of the App class.
    public ref class AppImpl
    {

    private:
      GCHandle _cb_handle; // Keeps an unmanaged reference to this class for mforms::App callbacks.
      
    public:
      DockingPointDelegateWrapper^ _docking_delegate;

      delegate String^ StringAppCommandAppViewStringDelegate(AppCommand, MySQL::Forms::AppViewImpl^ view, String^ str);
       
    private:
      StringAppCommandAppViewStringDelegate^ app_command_delegate;
      std::string app_command_wrapper(AppCommand command, mforms::AppView* view, const std::string &str);
    protected:
      static Object^ GetFromFixedId(IntPtr ip);

      static std::string get_resource_path(mforms::App *app, const std::string &file);
      static void set_status_text(mforms::App *app, const std::string &text);
      static base::Rect get_application_bounds(mforms::App *app);
      static int enter_event_loop(mforms::App *app, float max_wait_time);
      static void exit_event_loop(mforms::App *app, int ret_code);

      static base::Color get_system_color(mforms::SystemColor type);

    public:
 
      AppImpl(MySQL::Forms::Manager^ mgr,
        StringAppCommandAppViewStringDelegate^ app_command,
        DockingPointDelegateWrapper^ docking_delegate);

      ~AppImpl();

      static String^ get_image_path(String ^path);

      static void init(Manager ^mgr)
      {
        mforms::ControlFactory *f= mforms::ControlFactory::get_instance();

        DEF_CALLBACK2(std::string, mforms::App*, const std::string&, mgr, f->_app_impl, AppImpl, get_resource_path);
        DEF_CALLBACK2(void, mforms::App*, const std::string&, mgr, f->_app_impl, AppImpl, set_status_text);
        DEF_CALLBACK1(base::Rect, mforms::App*, mgr, f->_app_impl, AppImpl, get_application_bounds);
        DEF_CALLBACK2(int, mforms::App*, float, mgr, f->_app_impl, AppImpl, enter_event_loop);
        DEF_CALLBACK2(void, mforms::App*, int, mgr, f->_app_impl, AppImpl, exit_event_loop);
        DEF_CALLBACK1(base::Color, mforms::SystemColor, mgr, f->_app_impl, AppImpl, get_system_color);
      }
    };
  };
};

#endif // _WF_APP_H_
