using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Design;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace IMLibrary.Controls.Toolbox
{
    /// <summary>
    /// Represents a cursor wrapper of the <see cref="ToolboxItem"/> bitmap.
    /// </summary>
    public class ToolCursor : IDisposable
    {
        private ToolboxItem _item;
        private Cursor _cursor;
        private IntPtr _hIcon = IntPtr.Zero;
        private bool _disposed = false;

        private static Pen _crossPen = new Pen(Color.Blue);

        [DllImport("user32.dll", EntryPoint = "DestroyIcon")]
        static extern bool DestroyIcon(IntPtr hIcon);

        /// <summary>
        /// Initializes a new instance of the <see cref="ToolCursor"/> class.
        /// </summary>
        /// <param name="item">A <see cref="ToolboxItem"/> object.</param>
        public ToolCursor(ToolboxItem item)
        {
            _item = item;

            if (item.Bitmap != null)
            {
                using (Bitmap bitmap = CreateCursor(item.Bitmap))
                {
                    _hIcon = bitmap.GetHicon();
                    _cursor = new Cursor(_hIcon);
                }
            }
        }

        /// <summary>
        /// Gets a <see cref="Cursor"/> with the <see cref="ToolboxItem.Bitmap"/> and a cross.
        /// </summary>
        public Cursor Cursor
        {
            [DebuggerStepThrough]
            get { return _cursor; }
        }

        /// <summary>
        /// Gets a <see cref="ToolboxItem"/>.
        /// </summary>
        public ToolboxItem Item
        {
            [DebuggerStepThrough]
            get { return _item; }
        }

        private Bitmap CreateCursor(Bitmap itemBitmap)
        {
            Bitmap bitmap = new Bitmap(24, 24);
            using (Graphics graphics = Graphics.FromImage(bitmap))
            {
                graphics.DrawImage(itemBitmap, new Rectangle(7, 7, 16, 16));
                graphics.DrawLine(_crossPen, 6, 1, 6, 10);
                graphics.DrawLine(_crossPen, 1, 6, 10, 6);
            }
            return bitmap;
        }

        /// <summary>
        /// Finalizes the <see cref="ToolCursor"/> if it was not disposed.
        /// </summary>
        ~ToolCursor()
        {
            // Do not re-create Dispose clean-up code here.
            // Calling Dispose(false)is optimal in terms of
            // readability and maintainability.

            Dispose(false);
        }

        #region IDisposable Members

        /// <summary>
        /// Disposes the <see cref="ToolCursor"/>.
        /// </summary>
        public void Dispose()
        {
            Dispose(true);
        }

        private void Dispose(bool disposing)
        {
            if (!_disposed)
            {
                if (_hIcon != IntPtr.Zero)
                    DestroyIcon(_hIcon);

                if (disposing)
                    GC.SuppressFinalize(this);
                else
                    _cursor.Dispose();

                _disposed = true;
            }
        }

        #endregion
    }
}
