using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Reflection;
using WeifenLuo.WinFormsUI.Docking;
using MySQL.Grt;
using MySQL.Workbench;
using MySQL.GUI.Mdc;
using MySQL.GUI.Workbench.Properties;
using MySQL.GUI.Workbench.Plugins;

namespace MySQL.GUI.Workbench
{
	public partial class ModelDiagramForm : DockContent, IWorkbenchDocument
  {
    #region Member Variables

		private WbContext wbContext;
		private WorkbenchDocumentClosing onWorkbenchDocumentClosing = null;
    private SortedDictionary<String, Cursor> cursors = new SortedDictionary<String, Cursor>();
    private MySQL.Workbench.ModelViewForm formBE= null;

    #endregion

    #region Constructors

    public ModelDiagramForm(WbContext WbContext, String id)
		{
			InitializeComponent();

			wbContext= WbContext;

      if (wbContext.use_opengl())
        InitializeGLCanvas(id);
      else
        InitializeGDICanvas(id);

      FocusCanvasControl();

      openGlCanvasViewer.CanvasPanel.MouseMove += new MouseEventHandler(CanvasPanel_MouseMove);
      openGlCanvasViewer.CanvasPanel.MouseDown += new MouseEventHandler(CanvasPanel_MouseDown);
      openGlCanvasViewer.CanvasPanel.MouseUp += new MouseEventHandler(CanvasPanel_MouseUp);
      openGlCanvasViewer.CanvasPanel.KeyDown += new KeyEventHandler(CanvasPanel_KeyDown);
      openGlCanvasViewer.CanvasPanel.KeyUp += new KeyEventHandler(CanvasPanel_KeyUp);
      openGlCanvasViewer.CanvasPanel.MouseLeave += new EventHandler(CanvasPanel_MouseLeave);

      HideOnClose = true;
    }

    #endregion

		#region IWorkbenchDocument Interface

		public WorkbenchDocumentClosing OnWorkbenchDocumentClosing
		{
			get { return onWorkbenchDocumentClosing; }
			set { onWorkbenchDocumentClosing = value; }
		}

    public UIForm BackendClass
    {
      get { return formBE; }
    }

		#endregion

    #region Properties

    public BaseWindowsCanvasView Canvas
    {
      get { return (BaseWindowsCanvasView)openGlCanvasViewer.Canvas; }
    }

    public MySQL.Utilities.WindowsCanvasViewer CanvasViewer
    {
      get { return openGlCanvasViewer; }
    }

    #endregion

    #region Public Functions

    public BaseWindowsCanvasView InitializeGLCanvas(String id)
    {
      BaseWindowsCanvasView canvas = openGlCanvasViewer.InitializeGLCanvas(this, false);

      formBE = wbContext.get_diagram_form_for_diagram(id);

      return canvas;
    }

    public BaseWindowsCanvasView InitializeGDICanvas(String id)
    {
      BaseWindowsCanvasView canvas = openGlCanvasViewer.InitializeGDICanvas(this, false);

      formBE = wbContext.get_diagram_form_for_diagram(id);

      return canvas;
    }

    public void UpdateCursor()
    {
      SetCursor(formBE.get_tool_cursor());
    }

    private void SetCursor(string CursorFileName)
    {
      // if no cursor is specified, use default arrow
      if (CursorFileName.Equals(""))
      {
        openGlCanvasViewer.Cursor = System.Windows.Forms.Cursors.Default;
        return;
      }

      // Check if cursor already cached
      if (cursors.ContainsKey(CursorFileName))
        openGlCanvasViewer.Cursor = cursors[CursorFileName];
      else
      {
        // Load cursor
        Cursor c = null;
        string fullPath = Path.Combine("./images/cursors/", CursorFileName + ".cur");

        if (System.IO.File.Exists(fullPath))
        {
          c = new Cursor(fullPath);
          if (c != null)
          {
            // Add cursor to cache
            cursors.Add(CursorFileName, c);
            openGlCanvasViewer.Cursor = c;
          }
        }

        if (c == null)
          openGlCanvasViewer.Cursor = System.Windows.Forms.Cursors.Default;
      }
    }

    public void FocusCanvasControl()
    {
      ActiveControl = openGlCanvasViewer.CanvasPanel;
    }

    #endregion

    #region Form implementation

		private void openGlCanvasViewer_DragEnter(object sender, DragEventArgs e)
		{
      bool dragObjectIsMyClass =
                (e.Data.GetDataPresent(typeof(GrtValue)) == true) ||
                (e.Data.GetDataPresent(typeof(List<GrtValue>)) == true);
      if (dragObjectIsMyClass)
      {
        GrtValue val = (GrtValue)e.Data.GetData(typeof(GrtValue));
        Point p = this.PointToClient(new Point(e.X, e.Y));

        if (val != null)
        {
          List<GrtValue> list = new List<GrtValue>();

          list.Add(val);

          if (formBE.accepts_drop(p.X, p.Y,
            "x-mysql-wb/db.DatabaseObject", list))
            e.Effect = DragDropEffects.Copy;
        }
        else
        {
          List<GrtValue> list = (List<GrtValue>)e.Data.GetData(typeof(List<GrtValue>));

          if (list != null)
            if (formBE.accepts_drop(p.X, p.Y,
                "x-mysql-wb/db.DatabaseObject", list))
              e.Effect = DragDropEffects.Copy;
        }
      }
		}

		private void openGlCanvasViewer_DragDrop(object sender, DragEventArgs e)
		{
      GrtValue val = (GrtValue)e.Data.GetData(typeof(GrtValue));
      Point p = this.PointToClient(new Point(e.X, e.Y));

      if (val != null)
      {
        List<GrtValue> list = new List<GrtValue>();

        list.Add(val);

        formBE.perform_drop(p.X, p.Y,
          "x-mysql-wb/db.DatabaseObject", list);
      }
      else
      {
        List<GrtValue> list = (List<GrtValue>)e.Data.GetData(typeof(List<GrtValue>));

        if (list != null)
          formBE.perform_drop(p.X, p.Y,
            "x-mysql-wb/db.DatabaseObject", list);
      }
		}

		private void ModelViewForm_FormClosing(object sender, FormClosingEventArgs e)
		{
      openGlCanvasViewer.FinalizeCanvas();

			if (onWorkbenchDocumentClosing != null)
				onWorkbenchDocumentClosing(sender, e);
		}

    void CanvasPanel_MouseUp(object sender, MouseEventArgs e)
    {
      Point p = e.Location;
      formBE.OnMouseUp(e, p.X, p.Y, ModifierKeys, MouseButtons);
    }

    void CanvasPanel_MouseDown(object sender, MouseEventArgs e)
    {
      Point p = e.Location;
      formBE.OnMouseDown(e, p.X, p.Y, ModifierKeys, MouseButtons);
    }

    void CanvasPanel_MouseMove(object sender, MouseEventArgs e)
    {
      Point p = PointToClient(MousePosition);
      formBE.OnMouseMove(e, p.X, p.Y, ModifierKeys, MouseButtons);
    }

    void CanvasPanel_MouseLeave(object sender, EventArgs e)
    {
      if (!IsDisposed && !Disposing)
        formBE.OnMouseMove(new MouseEventArgs(0, 0, -1, -1, 0), -1, -1, ModifierKeys, MouseButtons);
    }

    void CanvasPanel_KeyUp(object sender, KeyEventArgs e)
    {
      formBE.OnKeyUp(e, ModifierKeys);
    }

    void CanvasPanel_KeyDown(object sender, KeyEventArgs e)
    {
      formBE.OnKeyDown(e, ModifierKeys);
    }

    #endregion

	}
}