using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace Sun.WinFormControl
{
    /// <summary>
    /// 类似微信的聊天对话框。
    /// </summary>
    /// <remarks>
    /// Author:SunYujing
    /// DateTime:2012-07-19
    /// </remarks>
    public class WxChartBox : Control
    {
        /// <summary>
        /// 构造方法。
        /// </summary>
        public WxChartBox()
        {
            SetStyle(ControlStyles.DoubleBuffer, true);                   //双缓冲防止重绘时闪烁
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);           //忽略 WM_ERASEBKGND 窗口消息减少闪烁
            SetStyle(ControlStyles.UserPaint, true);                      //自定义绘制控件内容
            SetStyle(ControlStyles.SupportsTransparentBackColor, true);   //模拟透明            
            SetStyle(ControlStyles.Selectable, false);                     //接收焦点
            Size = new Size(500, 60);                                      //初始大小
            Font = new Font("微软雅黑", 10);
        }
        /// <summary>
        /// 用户名。
        /// </summary>
        private string _username = "用户名";
        /// <summary>
        /// 消息日期时间。
        /// </summary>
        private DateTime _messagetime = DateTime.Now;
        /// <summary>
        /// 消息内容。
        /// </summary>
        private string _messagecontent = "消息内容";
        /// <summary>
        /// 每行消息数据的字节数。
        /// </summary>
        private int _perlinebit = 68;
        /// <summary>
        /// 每行字符数。
        /// </summary>
        private int _perlinechar = 34;
        /// <summary>
        /// 消息内容的行高。
        /// </summary>
        private int _lineheight = 22;
        /// <summary>
        /// 背景图高。
        /// </summary>
        private int _imageheight = 8;
        /// <summary>
        /// 背景图宽。
        /// </summary>
        private int _imagewidth = 8;
        /// <summary>
        /// 消息类型。
        /// </summary>
        private MessageType _messagetype = MessageType.Reseave;
        /// <summary>
        /// 获取或设置用户名。
        /// </summary>
        [Description("获取或设置用户名。")]
        public string UserName
        {
            get
            {
                return _username;
            }
            set
            {
                _username = value;
                Invalidate(false);
            }
        }
        /// <summary>
        /// 获取或设置用户名。
        /// </summary>
        [Description("获取或设置用户名。")]
        public DateTime MessageTime
        {
            get
            {
                return _messagetime;
            }
            set
            {
                _messagetime = value;
                Invalidate(false);
            }
        }
        /// <summary>
        /// 获取或设置消息内容。
        /// </summary>
        [Description("获取或设置消息内容。")]
        public string MessageContent
        {
            get
            {
                return _messagecontent;
            }
            set
            {
                _messagecontent = value;
                Invalidate(false);
            }
        }
        /// <summary>
        /// 获取或设置消息的类型。
        /// </summary>
        [Description("获取或设置消息的类型。")]
        public MessageType MType
        {
            get
            {
                return _messagetype;
            }
            set
            {
                _messagetype = value;
                Invalidate(false);
            }
        }
        /// <summary>
        /// 自定义绘制。
        /// </summary>
        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            Graphics g = e.Graphics;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.PixelOffsetMode = PixelOffsetMode.HighQuality;
            Width = 500;
            Height = InitHeight();
            DrawImage(g);
            DrawText(g);
            DrawLine(g);
            DrawMessageContent(g);
        }
        /// <summary>
        /// 绘制用户名和消息时间。
        /// </summary>
        private void DrawText(Graphics g)
        {
            Font f = new Font("微软雅黑", 10,FontStyle.Bold);
            g.DrawString(UserName+"  "+MessageTime.ToString("yyyy-MM-dd HH:mm:ss"), f, new SolidBrush(ForeColor), 8+_imagewidth, 2);
        }
        /// <summary>
        /// 绘制一条直线。
        /// </summary>
        private void DrawLine(Graphics g)
        {
            Color color = Color.Green;
            if(MType==MessageType.Reseave)
                color = Color.Red;
            Pen p = new Pen(color);
            p.Width = 1;
            g.DrawLine(p, 4 + _imagewidth, 22, Width - 8 - _imagewidth , 22);
        }
        /// <summary>
        /// 绘制短信内容。
        /// </summary>
        private void DrawMessageContent(Graphics g)
        {
            int initheight = 22;
            int rowscount = MessageLineCount();
            string contents = MessageContent;
            string content = "";
            for (int i = 0; i < rowscount; i++)
            {
                if (contents.Length > _perlinechar)
                {
                    content = contents.Substring(0, _perlinechar);
                    contents = contents.Remove(0, _perlinechar);
                }
                else
                {
                    content = contents;
                }
                g.DrawString(content, Font, new SolidBrush(ForeColor), 4+_imagewidth, initheight + i * _lineheight);
            }
        }
        /// <summary>
        /// 绘制背景图片。
        /// </summary>
        /// <param name="g"></param>
        private void DrawImage(Graphics g)
        {
            //绘制左上角背景图
            g.DrawImage(Properties.Resources.ZSJ, _imagewidth, 0);
            //绘制上边框
            g.DrawImage(Properties.Resources.HS, _imagewidth * 2, 0, Width - _imagewidth * 4, _imageheight);
            //绘制右上角背景图
            g.DrawImage(Properties.Resources.YHJ, Width - _imagewidth * 2-3, 0);
            //绘制右边框
            if (MType == MessageType.Send)
            {
                g.DrawImage(Properties.Resources.Y, Width - _imagewidth-1, _imageheight+1);
                g.DrawImage(Properties.Resources.SY, Width - _imagewidth * 2, _imageheight * 2+2, _imagewidth, Height - _imageheight * 3-2);
            }
            else
            {
                g.DrawImage(Properties.Resources.SY, Width - _imagewidth * 2, _imageheight, _imagewidth, Height - _imageheight * 2);
            }
            //绘制右下角背景图
            g.DrawImage(Properties.Resources.YXJ, Width - _imagewidth * 2 - 3, Height - _imageheight-2);
            //绘制下边框
            g.DrawImage(Properties.Resources.HX, _imagewidth * 2, Height - _imageheight, Width - _imagewidth * 4, _imageheight);
            //绘制左下角背景图
            g.DrawImage(Properties.Resources.ZXJ, _imagewidth, Height - _imageheight-2);
            //绘制左边框
            if (MType == MessageType.Reseave)
            {
                g.DrawImage(Properties.Resources.Z, 0, _imageheight+1);
                g.DrawImage(Properties.Resources.SZ, _imagewidth, _imageheight * 2+2, _imagewidth, Height - _imageheight * 3-2);
            }
            else
            {
                g.DrawImage(Properties.Resources.SZ, _imagewidth, _imageheight, _imagewidth, Height - _imageheight * 2);
            }
        }
        /// <summary>
        /// 动态计算控件高度。
        /// </summary>
        /// <returns>控件高度。</returns>
        public int InitHeight()
        {
            if(MessageLineCount()<2)
                return 2 * _lineheight + 22;
            else
                return MessageLineCount() * _lineheight + 22;
        }
        /// <summary>
        /// 获取消息行数。
        /// </summary>
        /// <returns>消息行数。</returns>
        private int MessageLineCount()
        {
            int MessageBits = System.Text.Encoding.Default.GetByteCount(MessageContent.Trim());
            return (int)Math.Ceiling(MessageBits * 1.0 / _perlinebit);
        }
    }
    /// <summary>
    /// 消息类型。
    /// </summary>
    public enum MessageType
    {
        /// <summary>
        /// 发送消息。
        /// </summary>
        Send,
        /// <summary>
        /// 接收消息。
        /// </summary>
        Reseave
    }
}