#region COPYRIGHT
//
//     THIS IS GENERATED BY TEMPLATE
//     
//     AUTHOR  :     ROYE
//     DATE       :     2010
//
//     COPYRIGHT (C) 2010, TIANXIAHOTEL TECHNOLOGIES CO., LTD. ALL RIGHTS RESERVED.
//
#endregion

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Web;
using System.Text;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using TX.Framework.WindowUI.Forms;

namespace TX.Framework.WindowUI.Controls
{
    public class ThumbnailView : ListView
    {
        private delegate void SetThumbnailDelegate(string imageKey, Image image);

        private BackgroundWorker _LoadWorker;
        private PictureBox _PictureBox;
        private IContainer components = null;
        private ContextMenuStrip menuAction;
        private ToolStripMenuItem menuItemDelete;
        private int _Id;
        private Color _BorderColor = SkinManager.CurrentSkin.BorderColor;
        public event EventHandler LoadCompleted;
        public event EventHandler<ItemDeletedEventArgs> ItemDeleted;
        public event EventHandler<ItemAddedEventArgs> ItemAdded;

        public ThumbnailView()
            : base()
        {
            InitializeComponent();

            ThumbnailSize = 95;
            ThumbBorderColor = Color.Wheat;
            _Id = 1;
            _PictureBox = new PictureBox();
            base.BorderStyle = BorderStyle.FixedSingle;
            ImageList imageList = new ImageList();
            imageList.ImageSize = new Size(ThumbnailSize, ThumbnailSize);
            imageList.ColorDepth = ColorDepth.Depth32Bit;
            imageList.TransparentColor = Color.White;
            this.LargeImageList = imageList;
        }

        private void AddDefaultThumbnail()
        {
            using (Bitmap bmp = new Bitmap(LargeImageList.ImageSize.Width, LargeImageList.ImageSize.Height, PixelFormat.Format32bppRgb))
            using (Graphics g = Graphics.FromImage(bmp))
            using (Brush brush = new SolidBrush(Color.White))
            using (Pen pen = new Pen(Color.Wheat, 1))
            {
                Rectangle rectangle = new Rectangle(0, 0, bmp.Width - 1, bmp.Height - 1);
                g.FillRectangle(brush, rectangle);
                g.DrawRectangle(pen, 0, 0, bmp.Width - 1, bmp.Height - 1);
                LargeImageList.Images.Add(bmp);
            }
        }

        public void Add(string[] fileList)
        {
            if ((_LoadWorker != null) && (_LoadWorker.IsBusy))
            {
                _LoadWorker.CancelAsync();
            }

            BeginUpdate();

            Dictionary<string, string> imageKeys = new Dictionary<string, string>();
            foreach (string fileName in fileList)
            {
                if (fileName.IsValid())
                {
                    ListViewItem item = this.Items.Add((_Id++).ToString());
                    item.Text = string.Empty;
                    item.Tag = fileName;
                    item.ImageKey = Guid.NewGuid().ToString();
                    imageKeys.Add(item.ImageKey, fileName);

                    if (ItemAdded != null)
                    {
                        ItemAdded(this, new ItemAddedEventArgs(item));
                    }
                }
            }

            EndUpdate();

            if (_LoadWorker != null)
            {
                if (!_LoadWorker.CancellationPending)
                {
                    _LoadWorker.RunWorkerAsync(imageKeys);
                }
            }
        }

        private void loadWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            if (_LoadWorker.CancellationPending) return;
            Dictionary<string, string> fileList = (Dictionary<string, string>)e.Argument;
            foreach (KeyValuePair<string, string> file in fileList)
            {
                try
                {
                    _PictureBox.Load(file.Value);
                    SetThumbnail(file.Key, ImageHelper.CreateThumbnail(_PictureBox.Image, ThumbnailSize, ThumbnailSize, ThumbBorderColor));
                }
                catch { }
            }
        }

        private void SetThumbnail(string imageKey, Image image)
        {
            if (Disposing) return;

            if (this.InvokeRequired)
            {
                this.Invoke(new SetThumbnailDelegate(SetThumbnail), imageKey, image);
            }
            else
            {
                this.LargeImageList.Images.Add(imageKey, image);
            }
        }

        private void loadWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            if (LoadCompleted != null)
            {
                LoadCompleted(sender, e);
            }
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            //if (e.Button == MouseButtons.Right)
            //{
            //    this.menuAction.Show(this, e.X, e.Y);
            //}
            base.OnMouseDown(e);
        }

        protected override void OnKeyDown(KeyEventArgs e)
        {
            if ((Control.ModifierKeys & Keys.Control) != 0)
            {
                if (e.KeyCode == Keys.A)
                {
                    foreach (ListViewItem item in this.Items)
                    {
                        item.Selected = true;
                    }
                }
                else if (e.KeyCode == Keys.D)
                {
                    DeleteSelectedItems();
                }
            }

            if (e.KeyCode == Keys.Delete)
            {
                DeleteSelectedItems();
            }

            base.OnKeyDown(e);
        }

        protected override void WndProc(ref Message m)
        {
            base.WndProc(ref m);
            switch (m.Msg)
            {
                case (int)WindowMessages.WM_NCPAINT:
                    this.NcPaint(ref m);
                    break;
                default:
                    break;
            }
        }

        private void menuAction_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            if (e.ClickedItem == this.menuItemDelete)
            {
                DeleteSelectedItems();
            }
        }

        private void DeleteSelectedItems()
        {
            if (TXMessageBoxExtensions.Question("确认删除", "确定删除所选择的图片吗？") == DialogResult.OK)
            {
                foreach (ListViewItem item in this.SelectedItems)
                {
                    this.LargeImageList.Images.RemoveByKey(item.ImageKey);
                    this.Items.Remove(item);
                    if (ItemDeleted != null)
                    {
                        ItemDeleted(this, new ItemDeletedEventArgs(item));
                    }
                }
            }
        }


        #region InitializeComponent

        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            this._LoadWorker = new System.ComponentModel.BackgroundWorker();
            this.menuAction = new System.Windows.Forms.ContextMenuStrip(this.components);
            this.menuItemDelete = new System.Windows.Forms.ToolStripMenuItem();
            this.menuAction.SuspendLayout();
            this.SuspendLayout();
            this.View = View.LargeIcon;
            // 
            // _LoadWorker
            // 
            this._LoadWorker.WorkerSupportsCancellation = true;
            this._LoadWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(this.loadWorker_DoWork);
            this._LoadWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.loadWorker_RunWorkerCompleted);
            // 
            // menuAction
            // 
            this.menuAction.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.menuItemDelete});
            this.menuAction.Name = "menuAction";
            this.menuAction.Size = new System.Drawing.Size(99, 26);
            this.menuAction.ItemClicked += new System.Windows.Forms.ToolStripItemClickedEventHandler(this.menuAction_ItemClicked);
            // 
            // menuItemDelete
            // 
            this.menuItemDelete.Name = "menuItemDelete";
            this.menuItemDelete.Size = new System.Drawing.Size(98, 22);
            this.menuItemDelete.Text = " 删除(&D) ";
            this.menuAction.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        #endregion

        [Category("TXProperties")]
        public int ThumbnailSize { get; set; }

        [Category("TXProperties")]
        public Color ThumbBorderColor { get; set; }

        [Category("TXProperties")]
        [Description("边框颜色")]
        public Color BorderColor
        {
            get { return _BorderColor; }
            set
            {
                this._BorderColor = value;
                base.Invalidate(true);
            }
        }

        #region NcPaint

        private void NcPaint(ref Message msg)
        {
            if (base.BorderStyle == BorderStyle.None)
            {
                return;
            }

            IntPtr hDC = Win32.GetWindowDC(msg.HWnd);
            if (hDC == IntPtr.Zero)
            {
                throw new Win32Exception();
            }

            Rectangle bounds = new Rectangle(0, 0, Width - 1, Height - 1);
            using (Graphics g = Graphics.FromHdc(hDC))
            {
                GDIHelper.DrawPathBorder(g, new RoundRectangle(bounds, 0), this._BorderColor);
            }
            msg.Result = IntPtr.Zero;
            Win32.ReleaseDC(msg.HWnd, hDC);
        }
        #endregion
    }

    public class ItemDeletedEventArgs : EventArgs
    {
        public ItemDeletedEventArgs(ListViewItem item)
        {
            Item = item;
        }
        public ListViewItem Item { get; private set; }
    }

    public class ItemAddedEventArgs : EventArgs
    {
        public ItemAddedEventArgs(ListViewItem item)
        {
            Item = item;
        }
        public ListViewItem Item { get; private set; }
    }
}
