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

#ifndef _WF_CODE_EDITOR_H_
#define _WF_CODE_EDITOR_H_

/**
 * Implements an mforms wrapper class for the Scintilla editor.
 *
 * @ingroup mforms
 */

using namespace System;
using namespace Windows::Forms;

namespace MySQL {
  namespace Forms {

    public ref class ScintillaControl : public Control
    {
    private:
      sptr_t direct_pointer;
      SciFnDirect message_function;
    protected:

      virtual void WndProc(Windows::Forms::Message% m) override;
      virtual void OnMouseDown(MouseEventArgs^ e) override;

      virtual property Windows::Forms::CreateParams^ CreateParams
      {
        Windows::Forms::CreateParams^ get() override;
      }

    public:
      ScintillaControl();

      sptr_t direct_call(unsigned int message, uptr_t wParam, sptr_t lParam);

      // For interaction with the UI we need some public methods/properties and forward these events
      // to the backend.
      property bool CanUndo
      {
        bool get();
      }
      property bool CanRedo
      {
        bool get();
      }
      property bool CanCopy
      {
        bool get();
      }
      property bool CanCut
      {
        bool get();
      }
      property bool CanPaste
      {
        bool get();
      }
      property bool CanDelete
      {
        bool get();
      }

      void Undo();
      void Redo();
      void Copy();
      void Cut();
      void Paste();
      void Delete();
      void SelectAll();

      void ShowFindPanel(bool doReplace);
    };

    public ref class CodeEditorImpl : public ViewImpl
    {
    private:
      [UnmanagedFunctionPointerAttribute(CallingConvention::Cdecl)]
      delegate void ShowFindPanelDelegate(mforms::CodeEditor*, bool);
      typedef void (*CodeEditorImpl::ShowFindPanelDelegateType)(mforms::CodeEditor*, bool);

      ShowFindPanelDelegate^ show_find_panel_delegate;

    protected:
      CodeEditorImpl(mforms::CodeEditor* editor);

      void show_find_panel(mforms::CodeEditor* editor, bool show);

      static bool create(mforms::CodeEditor* editor);
      static sptr_t send_editor(mforms::CodeEditor* editor, unsigned int message, uptr_t wParam, sptr_t lParam);
    public:
      static void init(Manager ^mgr)
      {
        ::mforms::ControlFactory *f= ::mforms::ControlFactory::get_instance();

        DEF_CALLBACK1(bool, mforms::CodeEditor*, mgr, f->_code_editor_impl, CodeEditorImpl, create);
        DEF_CALLBACK4(sptr_t, mforms::CodeEditor*, unsigned int, uptr_t, sptr_t, mgr, f->_code_editor_impl, CodeEditorImpl, send_editor);
      }
    };

  };
};

#endif // _WF_CODE_EDITOR_H_
