//===========================================================================
// Smarclient FPMS Demo Project a sample project for SmartClient technology.
// Smarclient FPMS Demo is designed and implemented bases Microsoft Application Block tech.
// Author: SFPMS Team, Date 2004-11
// Vision 1.0
// Revison History
//=============================================================================
using System;
using System.Configuration; 
using System.Data;
using System.Diagnostics; 
using System.Windows.Forms;
using System.Threading;
using System.Timers;  
using System.IO;
using System.Xml;
using Microsoft.ApplicationBlocks.ApplicationUpdater;
using Microsoft.ApplicationBlocks.SmartClient.Offline;
using JSW.Tool;
using JSW.FPMS.Tool;
using JSW.FPMS.Xiang.ShiTu;
using JSW.FPMS.Xiang.YeWu;
using JSW.FPMS.Xiang.ShuJu; 
using JSW.FPMS.Xiang.ShiJian;

namespace JSW.FPMS.Xiang.KongZhi
{
	/// <summary>
	/// clsXuQiuChaXunKongZhi 需求查询控制器，响应界面业务请求，处理反馈消息，管理应用程序状态等
	/// MVC结构中的Controler角色
	/// </summary>
	public class clsXuQiuChaXunKongZhi
	{
		#region 成员变量区域		
		//界面
		private XuQiuChaXunForm			jieMian			=	null;
		//MOAB引用
		private OfflineBlockBuilder		lixianKongZhi	=	null;
		//业务代表引用
		private clsYeWuDaiBiao			yewuDaiBiao     =	null;				
		//数据管理
		private clsShuJuGuanLi			shujuGuanLi		=	null;
		//网络状态
		private Microsoft.ApplicationBlocks.SmartClient.Offline.ConnectionState    wangluoZhuangTai;
		//MUAB引用
		private ApplicationUpdateManager gengXinKongZhi	= null;
		//应用程序组件更新引用
		private Thread      			gengXinXC		= null;
		//组件更新是否开始
		private bool					shifouGengXin	= false;
		private delegate void MarshalEventDelegate( object sender, UpdaterActionEventArgs e );
		//是否连接
		private bool                   shifouLianJie  =  false;
		
		#endregion

		#region 私有方法区域
		
		#region 事件响应方法区域
		/// <summary>
		/// 连接状态变化处理函数
		/// </summary>
		private void ConnectionManagerConnectionStateChangedEvent(object sender, 
			ConnectionStateChangedEventArgs args)
		{
			clsRiZhiChuLi.JiLuRiZhi("..........."+ args.CurrentState.ToString());
			wangluoZhuangTai = args.CurrentState;			
			if(Microsoft.ApplicationBlocks.SmartClient.Offline.ConnectionState.OnLine == wangluoZhuangTai)//已经上线
			{				
				shifouLianJie = true;
				//开始组件更新
				this.KaiShiZuJianGengXin(); 
				
			}
			else//没有上线
			{
				shifouLianJie = false;				
				//停止组件更新
				this.TingZhiZuJianGengXin();
				
			}
			//设置界面状态条情况
			this.jieMian.LianJieZhuangTai(this.shifouLianJie);	
			//设置界面数据更新时钟运行
			this.jieMian.SheZhiTimer(this.shifouLianJie);

		}

		/// <summary>
		/// 错误处理函数
		/// </summary>
		private void FailSafeServiceAgentErrorEvent(object sender, MethodExecutionFailureReportEventArgs args)
		{
			String cuowuXinXi = "";
			//错误处理
			if(args.Payload.FailureReason.GetType() == typeof(System.Web.Services.Protocols.SoapException))
			{
				
				System.Text.RegularExpressions.MatchCollection mc = System.Text.RegularExpressions.Regex.Matches(
					args.Payload.FailureReason.Message, 
					"---> ([^:]+):");
			
				if (mc.Count >= 1 && mc[0].Groups[1].Value == "System.Data.DBConcurrencyException")
				{
					cuowuXinXi += "数据同步错误";
				}
			}
			cuowuXinXi += args.Payload.FailureReason.Message;
			clsRiZhiChuLi.JiLuRiZhi(cuowuXinXi); 
			//根据情况，重新发送请求

		}

		/// <summary>
		/// 业务代表错误事件响应函数
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="args"></param>
		private void YeWuDaiBiaoReportErrorEvent(object sender, ReportErrorEventArgs args)
		{
			
			clsRiZhiChuLi.JiLuRiZhi(args.FailureReason);			
		}
		
		/// <summary>
		/// 需求提交返回处理函数
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="args"></param>
		private void XuQiuTiJiaoFanHui(object sender, XuQiuTiJiaoFanHuiShiJianArgs args)
		{
			
			clsRiZhiChuLi.JiLuRiZhi("需求提交返回......");			
		}
		/// <summary>
		/// 需求查询返回处理函数
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="args"></param>
		private void XuQiuChaXunFanHui(object sender, XuQiuChaXunFanHuiShiJianArgs args)
		{
			shujuGuanLi.ShuJuGengXin(clsChangLiang.SHUJU_XUQIU);  
			//如果需求数据变化了，更新页面
			if(shujuGuanLi.XuQiuBianHua())
			{
				this.jieMian.GengXinXuQiu(shujuGuanLi.HuoDeShuJu(clsChangLiang.SHUJU_XUQIU_WEIDAFU),
					shujuGuanLi.HuoDeShuJu(clsChangLiang.SHUJU_XUQIU_YIDAFU));  
			}
			else 
			{
				clsRiZhiChuLi.JiLuRiZhi("需求查询返回数据没有变化");
			}	
			clsRiZhiChuLi.JiLuRiZhi("需求更新数据返回。。。。。。");
		}
		
		/// <summary>
		/// 获得基本数据返回处理函数
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="args"></param>
		private void HuoDeJiBenShuJuFanHui(object sender, HuoDeJiBenShuJuFanHuiShiJianArgs args)
		{
			shujuGuanLi.ShuJuGengXin(clsChangLiang.SHUJU_JIBENSHUJU); 			
		}
		
		/// <summary>
		/// 获得配置文件返回处理函数
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="args"></param>
		private void HuoDePeiZhiFanHui(object sender, HuoDePeiZhiXinXiFanHuiShiJianArgs args)
		{
			shujuGuanLi.ShuJuGengXin(clsChangLiang.SHUJU_PEIZHIXINXI);	
		}		
		
		/// <summary>
		///程序组件更新下载开始，使用异步调用方法，更新界面
		/// </summary>
		private void ChengXuXiaZaiKaiShi( object sender, UpdaterActionEventArgs e ) 
		{		
			this.jieMian.Invoke( 
				new MarshalEventDelegate(this.jieMian.XiaZaiKaiShi), 
				new object[] { sender, e } );
		}

		/// <summary>
		///程序组件文件可以运行,下载完成，并且经过检验后。
		/// </summary>
		private void ChengXuWenJianKeYiYunXing( object sender, UpdaterActionEventArgs e ) 
		{	
			if(this.jieMian.YunXinChengXu(e)) 
			{
				YunXingXinChengXu(e.ServerInformation);
			}
			
		}

		/// <summary>
		///程序组件可以下载，如果存在新的版本，获得该版本
		///2004-11-22 为了提高演示性能，根据设置来弹出发现新版本的对话框
		/// </summary>
		private void ChengXuZuJianKeYiXiaZai( object sender, UpdaterActionEventArgs e ) 
		{		

				
			if(!this.shifouLianJie) 
			{
				//停止组件更新
				this.TingZhiZuJianGengXin(); 
				return;
			}
			//当发现新的版本的时候，如果设置为不提示，应用不弹出提示
			if(ConfigurationSettings.AppSettings[clsChangLiang.TISHIXINBANBEN].Equals(clsChangLiang.TISHI_XINBANBEN)) 
			{
				//提示是否下载新的程序
				string message = String.Format( 
					"发现新的乡级系统(版本：{0})，是否更新现有的乡级系统(版本：{1})？", 
					e.ServerInformation.AvailableVersion,  
					ConfigurationSettings.AppSettings["version"] ) ;
				//提示是否更新组件，如果不更新，停止MUAB
				DialogResult dialog = MessageBox.Show(this.jieMian, message, 
					"组件更新提示", MessageBoxButtons.YesNo,MessageBoxIcon.Question);

				if( DialogResult.No == dialog )
				{
					//停止组件更新
					this.TingZhiZuJianGengXin(); 
				}
			} 
			else 
			{
				//停止组件更新
				this.TingZhiZuJianGengXin(); 
			}
		}

		/// <summary>
		///程序组件下载完成
		/// </summary>
		private void ChengXuXiaZaiWanCheng( object sender, UpdaterActionEventArgs e ) 
		{		
			this.jieMian.Invoke( 
				new MarshalEventDelegate(this.jieMian.XiaZaiJieShu), 
				new object[] { sender, e } );
		}

		private void gengXinKongZhi_FilesValidationFailed( object sender, UpdaterActionEventArgs e ) 
		{
			
			MessageBox.Show(this.jieMian,e.ServerInformation.ManifestSignature); 
		}
		
		
		#endregion	

		/// <summary>
		/// 运行新版本的应用程序
		/// </summary>
		/// <param name="server"></param>
		private void YunXingXinChengXu( ServerApplicationInfo server )
		{
			XmlDocument doc = new XmlDocument();
			doc.Load( AppDomain.CurrentDomain.SetupInformation.ConfigurationFile );
			string baseDir = doc.SelectSingleNode("configuration/appUpdater/UpdaterConfiguration/application/client/baseDir").InnerText;
			string newDir = Path.Combine( baseDir, "AppStart.exe" );
			ProcessStartInfo process = new ProcessStartInfo( newDir );
			process.WorkingDirectory = Path.Combine( newDir , server.AvailableVersion );
			Process.Start( process );
			this.XiaoHui();
			Environment.Exit( 0 );
		}
		/// <summary>
		/// 停止数据更新线程
		/// </summary>
		private void TingZhiShuJuGengXin() 
		{				
			//MOAB销毁				
			lixianKongZhi.Dispose();			
		}
		/// <summary>
		/// 开始组件更新
		/// </summary>
		private void KaiShiZuJianGengXin() 
		{
			if(!shifouGengXin) 
			{
				//获得MUAB实例
				this.gengXinKongZhi = new ApplicationUpdateManager();				
				//注册应用程序组件更新事件
				gengXinKongZhi.DownloadStarted +=new UpdaterActionEventHandler(ChengXuXiaZaiKaiShi );
				gengXinKongZhi.FilesValidated +=new UpdaterActionEventHandler(ChengXuWenJianKeYiYunXing );
				gengXinKongZhi.UpdateAvailable +=new UpdaterActionEventHandler(ChengXuZuJianKeYiXiaZai );
				gengXinKongZhi.DownloadCompleted +=new UpdaterActionEventHandler(ChengXuXiaZaiWanCheng);
				gengXinKongZhi.FilesValidationFailed += new UpdaterActionEventHandler(gengXinKongZhi_FilesValidationFailed); 
				//MUAB启动
				this.gengXinXC =  new Thread(new ThreadStart(this.gengXinKongZhi.StartUpdater) );
				this.gengXinXC.Name="应用程序更新线程";
				gengXinXC.Start(); 
				//修改标识
				shifouGengXin = true;
			}
		}		

		/// <summary>
		/// 停止组件更新
		/// </summary>
		private void TingZhiZuJianGengXin()
		{
			if(this.shifouGengXin) 
			{
				//MUAB销毁
				this.gengXinKongZhi.StopUpdater();

				gengXinKongZhi = null;			
				//程序组件更新线程销毁			
				if( null != this. gengXinXC)
				{
					//  阻塞线程
					bool isThreadJoined = gengXinXC.Join( clsChangLiang.XIANCHENGZHUSAISHIJIAN);
					if( !isThreadJoined )
					{
						gengXinXC.Interrupt();
					
					}				
					gengXinXC = null;
				}
				//修改标识
				shifouGengXin = false;
			}
		}

		/// <summary>
		/// 重新发送需求
		/// </summary>
		private void ChongFaShuJu()
		{
			System.Data.DataSet chongfaShuJu = shujuGuanLi.ChongXinFaSong() ;
			//2004-11-22.&& chongfaShuJu.Tables["ShuJu"].Rows.Count>0 
			if(chongfaShuJu.Tables.Count > 0 && chongfaShuJu.Tables["ShuJu"].Rows.Count>0) 
			{
				XuQiuTiJiao(chongfaShuJu,0) ;
			}
		}

		#endregion

		#region 公有方法区域
		/// <summary>
		/// 构造器
		/// </summary>
		/// <param name="jieMian">需求查询界面引用</param> 
		public clsXuQiuChaXunKongZhi(XuQiuChaXunForm jieMian)
		{
			this.jieMian = jieMian;
			//获得MOAB实例
			lixianKongZhi = OfflineBlockBuilder.Instance; 
			//注册离线和在线事件			
			lixianKongZhi.ConnectionManager.ConnectionStateChangedEvent += 
				new ConnectionStateChangedEventHandler(
				ConnectionManagerConnectionStateChangedEvent);
			//注册错误处理
			FailsafeServiceAgent cuowuChuLi = lixianKongZhi.FailsafeServiceAgent;
			cuowuChuLi.ErrorEvent += new MethodExecutionFailureReportEventHandler(FailSafeServiceAgentErrorEvent);			
			//载入驻留在本地硬盘中的数据
			shujuGuanLi =  new clsShuJuGuanLi();
			shujuGuanLi.ZaiRuShuJu();			   
			//获得业务代表实例
			yewuDaiBiao = new clsYeWuDaiBiao(); 
			//注册业务代表的消息处理
			yewuDaiBiao.ReportErrorEvent += new ReportErrorEventHandler(YeWuDaiBiaoReportErrorEvent);			
			yewuDaiBiao.XuQiuTiJiaoFanHuiShiJian += new XuQiuTiJiaoFanHuiShiJianHandler(XuQiuTiJiaoFanHui);
			yewuDaiBiao.XuQiuChaXunFanHuiShiJian += new XuQiuChaXunFanHuiShiJianHandler(XuQiuChaXunFanHui);
			yewuDaiBiao.HuoDeJiBenShuJuFanHuiShiJian += new HuoDeJiBenShuJuFanHuiShiJianHandler(HuoDeJiBenShuJuFanHui);
			yewuDaiBiao.HuoDePeiZhiXinXiFanHuiShiJian += new HuoDePeiZhiXinXiFanHuiShiJianHandler(HuoDePeiZhiFanHui);

		}

		/// <summary>
		/// 控制器运行
		/// </summary>
		public void YunXin() 
		{
			try 
			{
				//界面填充数据,2.0.0.0
				jieMian.SheZhiShuJuYuan_WeiDaFu(this.shujuGuanLi.HuoDeShuJu(clsChangLiang.SHUJU_XUQIU_WEIDAFU));
				jieMian.SheZhiShuJuYuan_YiDaFu(this.shujuGuanLi.HuoDeShuJu(clsChangLiang.SHUJU_XUQIU_YIDAFU)); 
				//MOAB启动
				lixianKongZhi.Start();
				//zhangwj 11-23 增加对为提交数据的重新提交
				this.ChongFaShuJu() ;	
			}
			catch(Exception genException)
			{
				gengXinXC = null;
				throw new Exception("应用程序更新线程"+genException.Message) ;
			}

		}

		/// <summary>
		/// 控制器销毁
		/// </summary>
		public void XiaoHui() 
		{
			
			try
			{
				//存放参考数据到本地文件
				shujuGuanLi.CunRuShuJu();
				shujuGuanLi = null;
				//停止数据更新
				this.TingZhiShuJuGengXin(); 
				
			}
			catch(Exception genException)
			{
				new Exception("数据更新线程停止错误！"+genException.Message); 
				throw;

			}			

			
			try 
			{
				//停止应用程序组件更新
				TingZhiZuJianGengXin();
			}
			catch(Exception genException)
			{
				new Exception("应用程序组件停止错误！"+genException.Message); 
				throw;
			}

		}

		/// <summary>
		/// 需求提交
		/// </summary>
		public void XuQiuTiJiao(DataSet XuQiu) 
		{
			this.yewuDaiBiao.XuQiuTiJiao(XuQiu);  
			//界面显示
			try 
			{		
				//2.0.0.0修改
				DataSet shuJu = this.shujuGuanLi.XuQiuTianJian(XuQiu.Tables["ShuJu"]); 								
				this.jieMian.GengXinXuQiu(this.shujuGuanLi.HuoDeShuJu(clsChangLiang.SHUJU_XUQIU_WEIDAFU),
					this.shujuGuanLi.HuoDeShuJu(clsChangLiang.SHUJU_XUQIU_YIDAFU));
			}
			catch(Exception e)
			{
				Console.WriteLine(e.Message);
			}
		}

		/// <summary>
		/// 需求提交  不更新界面
		/// </summary>
		public void XuQiuTiJiao(DataSet XuQiu,int BiaoZhi) 
		{
			this.yewuDaiBiao.XuQiuTiJiao(XuQiu);  
		}
		
		/// <summary>
		/// 需求查询
		/// </summary>
		public void XuQiuChaXun() 
		{
			yewuDaiBiao.XuQiuChaXun();  			
		}

		

		/// <summary>
		/// 获得基本数据
		/// </summary>
		public void HuoDeJiBenShuJu() 
		{
			yewuDaiBiao.HuoDeJiBenShuJu();  
			
		}
		
		/// <summary>
		/// 获得配置信息
		/// </summary>
		public void HuoDePeiZhi() 
		{
			yewuDaiBiao.HuoDePeiZhi();  			

		}		
		
		/// <summary>
		/// 数据查询，发出数据查询请求
		/// </summary>
		public void ShuJuChaXun() 
		{				
			if(this.shifouLianJie) //连接状态下查询最新的数据
			{ 
				this.XuQiuChaXun();
				this.HuoDeJiBenShuJu();
				this.HuoDePeiZhi(); 			
			}
			
		}

		/// <summary>
		/// 获得界面描述数据
		/// zhangwj  11.8
		/// </summary>
		/// <param name="Jian">键</param>
		/// <param name="Hang">行号</param> 
		/// <returns></returns>
		public System.Data.DataSet HuoDeShuJu(string Jian,int Hang)
		{
			System.Data.DataSet fanHui = null;
			System.Collections.Hashtable table = new System.Collections.Hashtable() ;
			fanHui = this.shujuGuanLi.HuoDeShuJu(Jian) ;
			if(Hang < 0 ) return null;
				
			DataTable shujuBiao = fanHui.Tables[0];
			DataRow   shujuHang = shujuBiao.Rows[Hang];
			DataTable xinShuJuBiao = shujuBiao.Copy(); 
			DataRow   xinShuJuHang =  xinShuJuBiao.NewRow();

			for (int i=0;i<xinShuJuBiao.Columns.Count;i++)
				table.Add(xinShuJuBiao.Columns[i].ColumnName,"") ;

			for(int Loop=0;Loop<shujuBiao.Columns.Count;Loop++) 
			{
				if (table.ContainsKey(shujuBiao.Columns[Loop].ColumnName))
				{
					if (!shujuHang.IsNull(shujuBiao.Columns[Loop].ColumnName))
						xinShuJuHang[shujuBiao.Columns[Loop].ColumnName]  = shujuHang[shujuBiao.Columns[Loop].ColumnName].ToString();
				}
			}
			xinShuJuBiao.Rows.Clear();
			xinShuJuBiao.Rows.Add(xinShuJuHang);
			fanHui = new DataSet() ;
			fanHui.Merge(xinShuJuBiao);
			return fanHui ;
		}
		
		/// <summary>
		/// 获得数据
		/// </summary>
		/// <param name="Jian"></param>
		/// <returns></returns>
		public System.Data.DataSet HuoDeShuJu(string Jian)
		{
			return this.shujuGuanLi.HuoDeShuJu(Jian);
			
		}
		/// <summary>
		/// 定时数据更新程序，线程序工作函数
		/// </summary>
		public void DingShiShuJuChaXun() 
		{						
			if(this.shifouLianJie) //连接状态下查询最新的数据
			{ 
				this.XuQiuChaXun();
				this.HuoDeJiBenShuJu();
				this.HuoDePeiZhi(); 
				
			}
		}
		/// <summary>
		/// 是否需要等待数据刷新
		/// </summary>
		/// <returns>true：需要数据刷新 false:不需要数据刷新</returns>
		public bool ShiFouXuYaoXiaZai() 
		{
			return this.shujuGuanLi.ShiFouXuYaoXiaZai(); 
		}
		/// <summary>
		/// 强制上线
		/// </summary>
		public void QiangZhiShangXian() 
		{
			try 
			{
				this.lixianKongZhi.ConnectionManager.GoOnline(); 
			}
			catch(Exception e) 
			{
				clsRiZhiChuLi.JiLuRiZhi("强制上线失败"+e.Message);
			}
		}
		
		/// <summary>
		/// 强制离线
		/// </summary>
		public void QiangZhiLiXian() 
		{
			try 
			{
				this.lixianKongZhi.ConnectionManager.GoOffline();
			}
			catch(Exception e) 
			{
				clsRiZhiChuLi.JiLuRiZhi("强制离线失败"+e.Message);
			}
		}


		#endregion

	}
}
