/* 
 * Copyright (c) 2009, 2014, 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 "wf_mforms.h"

#include "wf_base.h"
#include "wf_view.h"
#include "wf_button.h"
#include "wf_form.h"
#include "wf_checkbox.h"
#include "wf_textentry.h"
#include "wf_textbox.h"
#include "wf_imagebox.h"
#include "wf_label.h"
#include "wf_selector.h"
#include "wf_panel.h"
#include "wf_tabview.h"
#include "wf_box.h"
#include "wf_progressbar.h"
#include "wf_radiobutton.h"
#include "wf_table.h"
#include "wf_filechooser.h"
#include "wf_listbox.h"
#include "wf_wizard.h"
#include "wf_scrollpanel.h"
#include "wf_utilities.h"
#include "wf_drawbox.h"
#include "wf_splitter.h"
#include "wf_webbrowser.h"
#include "wf_popup.h"
#include "wf_menu.h"
#include "wf_menubar.h"
#include "wf_toolbar.h"
#include "wf_code_editor.h"
#include "wf_hypertext.h"
#include "wf_popover.h"
#include "wf_treenodeview.h"
#include "wf_find_panel.h"
#include "wf_native.h"
#include "wf_canvas.h"
#include "wf_record_grid_view.h"

#include "wf_appview.h"
#include "wf_app.h"

#include "base/log.h"

using namespace System::Threading;

using namespace MySQL;
using namespace MySQL::Forms;

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

Manager::Manager()
{
  created = 0;
  destroyed = 0;

  base::Logger::log(base::Logger::LogInfo, DOMAIN_MFORMS_WRAPPER, "Initializing mforms wrapper\n");

  ViewWrapper::init();
  LabelWrapper::init();
  BoxWrapper::init();
  MenuBarWrapper::init();
  UtilitiesWrapper::init();
  AppWrapper::init();
  ToolBarWrapper::init();
  AppViewWrapper::init();
  FormWrapper::init();
  ButtonWrapper::init();
  CheckBoxWrapper::init();
  TextEntryWrapper::init();
  TextBoxWrapper::init();
  SelectorWrapper::init();
  PanelWrapper::init();
  TabViewWrapper::init();
  ProgressBarWrapper::init();
  ImageBoxWrapper::init();
  RadioButtonWrapper::init();
  TableWrapper::init();
  FileChooserWrapper::init();
  ListBoxWrapper::init();
  WizardWrapper::init();
  ScrollPanelWrapper::init();
  DrawBoxWrapper::init();
  SplitterWrapper::init();
  WebBrowserWrapper::init();
  PopupWrapper::init();
  MenuWrapper::init();
  FindPanelWrapper::init();
  CodeEditorWrapper::init();
  HyperTextWrapper::init();
  PopoverWrapper::init();
  TreeNodeViewWrapper::init();
  CanvasWrapper::init();
//  mforms::ControlFactory::get_instance()->check_impl();
}

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

Manager::~Manager()
{
  base::Logger::log(base::Logger::LogInfo, DOMAIN_MFORMS_WRAPPER, "Shutting down mforms wrapper\n");
  /* Doesn't really work since on app shutdown many objects are just not regularly freed.
  base::Logger::log(base::Logger::LogDebug2, DOMAIN_MFORMS_WRAPPER,
    "Created %i wrapper objects, destroyed %i, leaking %i objects\n",
    created, destroyed, created - destroyed);
    */
}

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

Manager^ MySQL::Forms::Manager::get_instance()
{
  // The manager is created very early in the app startup process from the main thread, so this
  // should never be a concurrency problem here.
  if (singleton == nullptr)
    singleton = gcnew Manager();
  return singleton;
}

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

void Manager::instance_created()
{
  // Atomic increment shouldn't be necessary as we always create and destroy wrappers in the
  // main thread. But better safe than sorry.
  Interlocked::Increment(created);
}

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

void Manager::instance_destroyed()
{
  Interlocked::Increment(destroyed);
}

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

