using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WinAPI;

namespace QuickMsg
{
    /// <summary>
    /// 消息客户端类
    /// </summary>
    public class MsgClient
    {
        readonly CustomMsg MSG;
        /// <summary>
        /// 判断当前消息主服务器是否创建成功
        /// </summary>
        public bool IsOk
        {
            get; private set;
        }
        /// <summary>
        /// 最后一次接收消息的时间,可用来判断服务端是否有响应
        /// </summary>
        public DateTime Last_RecvTime { get; set; } = DateTime.Now.AddDays(-10);
        /// <summary>
        /// 主句柄
        /// </summary>
        public IntPtr main_handle = IntPtr.Zero;
        /// <summary>
        /// 当收到消息时激发
        /// </summary>
        public event CustomMsg.MsgEventHandler OnMsg;
        /// <summary>
        /// 连接上主服务器时触发
        /// </summary>
        public event EventHandler OnConnected;
        /// <summary>
        /// 收到服务端关闭通知
        /// </summary>
        public event EventHandler OnClose;
        /// <summary>
        /// 收到服务端关闭通知，即将关闭
        /// </summary>
        public event CustomMsg.ClosingEventHandler OnClosing;
        /// <summary>
        /// 服务端大小改变时激发
        /// </summary>
        public event CustomMsg.SizeEventHandler OnResize;
        //private readonly string client_id="";
        /// <summary>
        /// 实例化客户端
        /// </summary>
        /// <param name="main_id">服务端ID</param>
        /// <param name="client_id">当前客户端ID,会向服务器报告当前ID</param>
        /// <param name="_form">客户端</param>
        public MsgClient(string main_id,string client_id, Form _form)
        {
            object mainHandle = RyMemoryShare.ReadFromMemory(1024, typeof(Int64), main_id);
            //this.client_id = client_id;
            if (mainHandle == null)
            {
                IsOk = false;
            }
            else
            {
                main_handle = new IntPtr((Int64)mainHandle);
                MSG = new CustomMsg(_form);//创建消息通道
                MSG.OnMsg += MSG_OnMsg;
                ryCommon.Storage Stor = new ryCommon.Storage();
                Stor.SelectNodeBySet();
                Stor.SetAttrValue("op", "connect");
                Stor.SetAttrValue("clientid", client_id);
                MSG.Send(main_handle, MyDb.RyWin32.Sys_chanel_id, "xml" + Stor.XMLText);//向服务端发起连接请求
            }
        }
        /// <summary>
        /// 
        /// </summary>
        ~MsgClient()
        {
            DisConnect();
        }
        /// <summary>
        /// 断开服务端连接
        /// </summary>
        public void DisConnect()
        {
            if (IsOk)
                MSG.Send(main_handle, MyDb.RyWin32.Sys_chanel_id, "disconnect");//向服务端发起断开连接请求
            IsOk = false;
        }
        /// <summary>
        /// 发送消息,采用多线程发送
        /// </summary>
        /// <param name="wParam"></param>
        /// <param name="msg"></param>
        public void Send(int wParam, string msg)
        {
            MSG.Send(main_handle, wParam, msg);//发送消息
        }
        /// <summary>
        /// 向服务端发送心跳包
        /// </summary>
        public void SendHeart()
        {
            MSG.Send2(main_handle, MyDb.RyWin32.Sys_chanel_id, "heart");//发送消息
        }
        /// <summary>
        /// 判断服务端句柄是否存在。
        /// </summary>
        /// <returns></returns>
        public bool MainExist()
        {
            return User32.IsWindow(main_handle);
        }
        private void MSG_OnMsg(object sender, MsgArgs e)
        {
            Last_RecvTime = DateTime.Now;
            OnMsg?.Invoke(this,e);
            if (e.WParam == MyDb.RyWin32.Sys_chanel_id) //如果是系统通道请求
            {
                switch (e.Msg_text)
                {
                    case "connected"://与服务端连接成功
                        IsOk = true;
                        OnConnected?.Invoke(this,new EventArgs());
                        break;
                    case "close"://服务端关闭通知
                        IsOk = false;
                        bool cancel = false;
                        OnClosing?.Invoke(this,cancel);
                        if (!cancel)
                        {
                            OnClose?.Invoke(this, new EventArgs());
                        }
                        break;
                    default:
                        #region 如果是xml消息
                        if (e.Msg_text.StartsWith("xml"))
                        {
                            ryCommon.Storage Stor = new ryCommon.Storage(e.Msg_text.Substring(3));
                            Stor.SelectNodeBySet();
                            switch (Stor.GetAttrValue("op"))
                            {
                                case "resize"://服务端大小改变
                                    OnResize?.Invoke(this, Stor.GetAttrValue("width", 0), Stor.GetAttrValue("height", 0));
                                    break;
                            }
                        }
                        break; 
                        #endregion
                }
            }
        }
    }
}
