using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using WeifenLuo.WinFormsUI.Docking;
using MySQL.Grt;
using MySQL.Utilities;

namespace MySQL.GUI.Workbench.Plugins
{
	/// <summary>
	/// Generic GRT Object Editor
	/// </summary>
	public partial class DockablePlugin : DockContent
  {
    #region Member Variables

    /// <summary>
		/// The GRT Manager that controlls the GRT
		/// </summary>
		protected GrtManager grtManager;

		/// <summary>
		/// The GRT Object this Editor is operating on
		/// </summary>
		protected GrtValue grtList;

		/// <summary>
		/// GCHandle, needed for fixed pointer
		/// </summary>
		GCHandle gcHandle;

    #endregion

    #region Constructors

    /// <summary>
		/// Standard constructor
		/// </summary>
		protected DockablePlugin()
		{
			InitializeComponent();
		}

		/// <summary>
		/// Overloaded constructor taking the GRT Manager and GRT object to edit
		/// </summary>
		/// <param name="GrtManager">The GRT Manager</param>
		/// <param name="GrtObject">The object to edit</param>
		public DockablePlugin(GrtManager GrtManager, GrtValue GrtList)
			: this()
		{
			grtManager = GrtManager;
			grtList = GrtList;
		}

    ~DockablePlugin()
		{
			// Make sure the GCHandle is released
			ReleaseHandle();
    }

    #endregion

    #region Properties

    public GrtManager GrtManager { get { return grtManager;} }

    #endregion Properties

    #region Memory Handling

    /// <summary>
		/// Returns a fixed pointer to this object that will not be modified by the GC
		/// </summary>
		/// <returns>fixed int pointer to this object</returns>
		public IntPtr GetFixedPtr()
		{
			if (!gcHandle.IsAllocated)
				 gcHandle = GCHandle.Alloc(this);

			return GCHandle.ToIntPtr(gcHandle);
		}

		/// <summary>
		/// Needs to be called when destroying the object
		/// </summary>
		public void ReleaseHandle()
		{
      if (gcHandle.IsAllocated) // e.g. after exception during module loading
			  gcHandle.Free();
		}

		/// <summary>
		/// Returns the object based on the fixed pointer retrieved by GetFixedPtr()
		/// </summary>
		/// <param name="ptr">The pointer to look up</param>
		/// <returns>The corresponding instance</returns>
		static public DockablePlugin GetFromFixedPtr(IntPtr ptr)
		{
			GCHandle gcHandle = GCHandle.FromIntPtr(ptr);
      return (DockablePlugin)gcHandle.Target;
    }

    #endregion

  }
}