using System;
using System.Data;
using System.Collections;
using System.Windows.Forms;

using Core.Mes.IBaseInterface;
using System.ComponentModel;
using System.Drawing;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Net.Sockets;

namespace Core.Mes.ClientFrameWork
{
    /// <summary>
    /// RemotingHelp 的摘要说明。
    /// </summary>
    public class RemotingHelp
    {
        public RemotingHelp()
        {

        }
        public DataSet ServerUrlList
        {
            set
            {
                DataSet ds = value;
                if (ds != null || ds.Tables.Count > 0)
                {
                    _htServerUrlList = new Hashtable();
                    foreach (DataRow dr in ds.Tables[0].Rows)
                    {
                        string url = dr["Url"].ToString() + "/" + dr["ServerName"];
                        List<string> urls = MultiTcpUrl(url);
                        _htServerUrlList.Add(dr["ServerName"].ToString(), urls);
                    }
                }
                ds.Dispose();
            }
        }
        private Hashtable _htServerUrlList = new Hashtable();
        private Hashtable _htRemoteServer = new Hashtable();

        private bool GetServer(string serverName)
        {
            try
            {
                if (!_htRemoteServer.Contains(serverName))
                {
                    List<string> urls = _htServerUrlList[serverName] as List<string>;
                    List<ICommon> iCommons = new List<ICommon>();

                    foreach (string url in urls)
                    {
                        //ICommon tCommon = (ICommon)Activator.CreateInstance(typeof(ICommon), url);
                        //
                        ICommon iCommon = (ICommon)Activator.GetObject(typeof(ICommon), url);
                        iCommons.Add(iCommon);
                    }

                    _htRemoteServer.Add(serverName, iCommons);

                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return false;
            }
            return true;
        }
        public object ExecuteMethod(CallingMessage par, out string errorInfo)
        {
            errorInfo = "";

            if (!FindRemoteServer(par.ServerName))
            {
                errorInfo = "未找到请求的服务！";
                return null;
            }
            try
            {
                List<string> urls = _htServerUrlList[par.ServerName] as List<string>;

                List<ICommon> iCommons = _htRemoteServer[par.ServerName] as List<ICommon>;
                Random rd = new Random();
                int index = rd.Next(iCommons.Count);
               
                ICommon iCommon = iCommons[index];


                string url = urls[index];

                ReturnObject rtnObj = iCommon.MethodHandler(par, new ValidateInfo());
                errorInfo = rtnObj.ErrMessage;

                return rtnObj.RealObject;
            }
            catch (Exception ex)
            {
                errorInfo = ex.Message;
                return null;
            }
        }

        public object ExecuteMethod(string serverName, string className, string methodName, object[] args, out string errorInfo)
        {
            //==	解析参数
            CallingMessage par = new CallingMessage();
            par.ServerName = serverName;
            par.ClassName = className;
            par.MethodName = methodName;
            par.args = args;

            par.ServerType = MesServerType.IComponentContainServer;
            par.TransType = NetWorkTransType.Remoting;
            par.visitType = VisitType.Method;

            errorInfo = "";

            return ExecuteMethod(par, out errorInfo);
        }
        private bool FindRemoteServer(string serverName)
        {
            if (!_htRemoteServer.Contains(serverName))
                return GetServerUrl(serverName);
            return true;
        }
        private bool GetServerUrl(string serverName)
        {
            if (!_htServerUrlList.Contains(serverName))
                return false;

            return GetServer(serverName);
        }
        public void InitServerUrlList(string serverName, string url)
        {
            if (_htServerUrlList.Count == 0)
            {
                List<string> strs = MultiTcpUrl(url);
                _htServerUrlList.Add(serverName, strs);
            }
        }


        #region add maliang 2012-5-4
        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <returns></returns>
        private List<string> MultiTcpUrl(string url)
        {
            List<string> strs = new List<string>();
            try
            {
               
                Regex r = new Regex(@"^\w+://[^/]+?(?<port>\d+)?/", RegexOptions.Compiled);
                string strPort = r.Match(url).Result("${port}");
                int iport = Convert.ToInt32(strPort);
                strs.Add(url);

                url = url.ToUpper().Replace("TCP://", "http://");
                int iport_a = iport + 5;
                string url_a = url.Replace(strPort, iport_a.ToString());
                strs.Add(url_a);

                int iport_b = iport + 10;
                string url_b = url.Replace(strPort, iport_b.ToString());
                strs.Add(url_b);

                

            }
            catch
            {
                //dologs 匹配端口号失败。启用默认的地址。
                strs.Add(url);
            }
            return strs;
        }

        #endregion






        public AsyncExecute AsyncExecute
        {
            get
            {
                return new AsyncExecute(this);
            }
        }
    }
    #region add maliang 2012-4-12
    public class AsyncExecute
    {

        private RemotingHelp _RemotingHelp = null;
        public AsyncExecute(RemotingHelp pRemotingHelp)
        {
            _RemotingHelp = pRemotingHelp;
        }
        private Form m_ParentBusy;
        /// <summary>
        /// 需要显示忙的窗体。
        /// </summary>
        public Form ParentBusy
        {
            get { return m_ParentBusy; }
            set { m_ParentBusy = value; }
        }

        private Point m_BusyLocation = new Point(0, 0);
        /// <summary>
        /// 需要显示忙的窗体。
        /// </summary>
        public Point BusyLocation
        {
            get { return m_BusyLocation; }
            set { m_BusyLocation = value; }
        }

        /// <summary>
        /// 请求完成的委托
        /// </summary>
        /// <param name="returnObj">返回的对象</param> 
        /// <param name="returnMsg">返回的消息内容</param>
        public delegate void CompleteEventHandler(object returnObj, string returnMsg);

        /// <summary>
        /// 请求完成的事件,如果返回的对象需要处理，请订阅该事件
        /// </summary>
        public event CompleteEventHandler OnComplete;
        /// <summary>
        /// 参数
        /// </summary>
        private CallingMessage CallingMessage;
        /// <summary>
        /// 错误信息
        /// </summary>
        private string errorInfo = string.Empty;
        /// <summary>
        /// 返回的对象
        /// </summary>
        private object returnObj;

        public void AsyncExecuteMethod(CallingMessage par)
        {
            CallingMessage = par;
            BackgroundWorker bw = new BackgroundWorker();
            bw.DoWork += new DoWorkEventHandler(DoWork);
            bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(RunWorkerCompleted);
            bw.WorkerReportsProgress = true;
            bw.RunWorkerAsync();

        }


        /// <summary>
        /// 请求完成
        /// </summary> 
        void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {


            if (ParentBusy != null)
            {
                BusyCtl.Stop();
                ParentBusy.Controls.Remove(BusyCtl);
            }
            string msg = string.Empty;

            //如果订阅了该事件并且返回的结果没有问题才调用完成的事件
            if (OnComplete == null)
            {
                throw new Exception("调用接口请求时未订阅OnComplete事件,请在调用AsyncExecuteMethod请求对象是订阅OnComplete事件");
            }

            OnComplete.Invoke(returnObj, errorInfo);

        }
        private BusyControl BusyCtl = new BusyControl();
        /// <summary>
        /// 发送请求
        /// </summary> 
        void DoWork(object sender, DoWorkEventArgs e)
        {
            if (ParentBusy != null)
            {

                ParentBusy.Invoke(new dlgAddControl(addCtl), ParentBusy, BusyCtl);

            }
            errorInfo = "";
            returnObj = _RemotingHelp.ExecuteMethod(CallingMessage, out errorInfo);
        }

        delegate void dlgAddControl(Control Pctl, BusyControl BusyCtl);

        private void addCtl(Control Pctl, BusyControl BusyCtl)
        {
            BusyCtl.Size = new System.Drawing.Size(32, 32);
            Pctl.Controls.Add(BusyCtl);

            BusyCtl.BringToFront();
            BusyCtl.Location = BusyLocation;

            BusyCtl.Start();
        }

        public void AsyncExecuteMethod(string serverName, string className, string methodName, object[] args)
        {
            //==	解析参数
            CallingMessage par = new CallingMessage();
            par.ServerName = serverName;
            par.ClassName = className;
            par.MethodName = methodName;
            par.args = args;

            par.ServerType = MesServerType.IComponentContainServer;
            par.TransType = NetWorkTransType.Remoting;
            par.visitType = VisitType.Method;

            AsyncExecuteMethod(par);
        }



    }
    #endregion
}
