using System;
using System.Data;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using JXC_MIS.Interface;

using JXC_MIS.DataTier;

namespace JXC_MIS.UserTier.RefertoInput
{
	/// <summary>
	/// 网格参照选择，指定DataSource（Sql或存储过程）后可以直接选择数据并返回选择的DataTable。指定DataSourceKey关键字后不会重复选择同一行。
	/// </summary>
	public class frmGridRefertoSelect : JXC_MIS.UserTier.BaseForm.frmTreeWindows,IReferto
	{
		//模块级变量、属性字段
		private DataTable m_TopDataTable = new DataTable();				//上面网格绑定的表
		private DataTable m_BottomDataTable = new DataTable();			//下面网格用于存选择的结果
		private DataGridAccess m_dataGridAccess = new DataGridAccess();	//网格操作

		private string _DataSource = "";								//数据源，Sql、存储过程
		private string _DataSourceKey = "";								//数据源的主键，用于标记唯一行
		private string _OtherFilter = "";


		private CommandType _CommandType = CommandType.StoredProcedure;	//数据源命令形式，Sql、存储过程
		
		private bool mblnSelect = false;								//确定最终选择是否有效标志

		#region 字段属性、方法，IReferto接口成员
		/// <summary>
		/// 获取或设置网格的数据源
		/// </summary>
		public string DataSource
		{
			get
			{
				return _DataSource;
			}
			set
			{
				_DataSource = value;
			}
		}

		/// <summary>
		/// 获取或设置网格的数据源的主键，用于标记唯一行
		/// </summary>
		public string DataSourceKey
		{
			get
			{
				return _DataSourceKey;
			}
			set
			{
				_DataSourceKey = value;
			}
		}

		/// <summary>
		/// 获取或设置网格的数据源命令类型
		/// </summary>
		public CommandType CommandType
		{
			get
			{
				return _CommandType;
			}
			set
			{
				_CommandType = value;
			}
		}

		/// <summary>
		/// 设置网格的数据源并指定命令类型
		/// </summary>
		public void SetDataSource(string p_SqlOrStoredProcedure,CommandType p_commandType)
		{
			this.DataSource = p_SqlOrStoredProcedure;
			this.CommandType = p_commandType;
		}

		/// <summary>
		/// 初始默认值
		/// </summary>
		public string DefaultValue 
		{
			set{}
			get{return null;}
		}
		/// <summary>
		/// 参照类型，网格列表参照=0,日期参照=1,ListBox列表参照=2,树型列表参照=3,树型文件路径参照=4。
		/// 也可以用_RefertoTypeFlag顾名思义
		/// </summary>
		public int RefertoType 
		{
			set{}
			get{return 0;}
		}

		#endregion


		/// <summary>
		/// 参照其他过滤条件
		/// </summary>
		public string OtherFilter 
		{
			set
			{
				_OtherFilter = value;
			}
			get
			{
				return _OtherFilter;
			}
		}


		#region 方法 DataTable GetSelect()
		/// <summary>
		/// 获取选择的结果集
		/// </summary>
		/// <returns></returns>
		public DataTable GetReturnDataTable()
		{
			if (mblnSelect)
			{
				return m_BottomDataTable;
			}
			else
			{
				return null;			
			}
		}

		/// <summary>
		/// 获取参照返回值，取第一行
		/// </summary>
		/// <returns></returns>
		public Hashtable GetReturnHashtable()
		{
			if (mblnSelect)
			{
				Hashtable htReturn = new Hashtable();
			
				for(int i = 0 ; i < m_BottomDataTable.Columns.Count ; i++)
				{
					htReturn.Add(i,m_BottomDataTable.Rows[0][i]);
				}

				return htReturn;
			}
			else
			{
				return null;
			}
		}
		#endregion


		#region 设计器生成的代码

		private System.Windows.Forms.Button btnSelectAll;
		private System.Windows.Forms.Button btnClearAll;				
		private System.Windows.Forms.Button btnCancel;
		private System.Windows.Forms.Button btnOK;						//数据源的主键，用于标记唯一行

		private System.ComponentModel.IContainer components = null;

		public frmGridRefertoSelect()
		{
			// 该调用是 Windows 窗体设计器所必需的。
			InitializeComponent();

			// TODO: 在 InitializeComponent 调用后添加任何初始化
		}

		/// <summary>
		/// 清理所有正在使用的资源。
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}
		#endregion

		#region 设计器生成的代码
		/// <summary>
		/// 设计器支持所需的方法 - 不要使用代码编辑器修改
		/// 此方法的内容。
		/// </summary>
		private void InitializeComponent()
		{
			this.btnSelectAll = new System.Windows.Forms.Button();
			this.btnClearAll = new System.Windows.Forms.Button();
			this.btnCancel = new System.Windows.Forms.Button();
			this.btnOK = new System.Windows.Forms.Button();
			((System.ComponentModel.ISupportInitialize)(this.grd_Bottom)).BeginInit();
			((System.ComponentModel.ISupportInitialize)(this.grd_Top)).BeginInit();
			this.SuspendLayout();
			// 
			// cbo_SetupName
			// 
			this.cbo_SetupName.Name = "cbo_SetupName";
			// 
			// sbr_StatusBar
			// 
			this.sbr_StatusBar.Name = "sbr_StatusBar";
			this.sbr_StatusBar.Size = new System.Drawing.Size(800, 25);
			// 
			// tbr_Toolbar
			// 
			this.tbr_Toolbar.Name = "tbr_Toolbar";
			this.tbr_Toolbar.Size = new System.Drawing.Size(800, 41);
			// 
			// panel1
			// 
			this.panel1.Name = "panel1";
			this.panel1.Size = new System.Drawing.Size(800, 387);
			// 
			// spt_H
			// 
			this.spt_H.Location = new System.Drawing.Point(3, 0);
			this.spt_H.Name = "spt_H";
			this.spt_H.Size = new System.Drawing.Size(603, 3);
			// 
			// grd_Bottom
			// 
			this.grd_Bottom.Location = new System.Drawing.Point(0, 0);
			this.grd_Bottom.Name = "grd_Bottom";
			this.grd_Bottom.Size = new System.Drawing.Size(802, 384);
			this.grd_Bottom.Click += new System.EventHandler(this.grd_Top_Click);
			// 
			// grd_Top
			// 
			this.grd_Top.Location = new System.Drawing.Point(3, 0);
			this.grd_Top.Name = "grd_Top";
			this.grd_Top.Size = new System.Drawing.Size(797, 178);
			this.grd_Top.Click += new System.EventHandler(this.grd_Top_Click);
			this.grd_Top.DoubleClick += new System.EventHandler(this.grd_Top_DoubleClick);
			// 
			// spt_V
			// 
			this.spt_V.Location = new System.Drawing.Point(0, 0);
			this.spt_V.Name = "spt_V";
			this.spt_V.Size = new System.Drawing.Size(3, 387);
			// 
			// tv_Tree
			// 
			this.tv_Tree.Name = "tv_Tree";
			this.tv_Tree.Size = new System.Drawing.Size(0, 387);
			// 
			// pnl_Filter
			// 
			this.pnl_Filter.Name = "pnl_Filter";
			// 
			// cmd_Cancel
			// 
			this.cmd_Cancel.Name = "cmd_Cancel";
			// 
			// cmd_ExeQuery
			// 
			this.cmd_ExeQuery.Name = "cmd_ExeQuery";
			// 
			// grd_Filter
			// 
			this.grd_Filter.Name = "grd_Filter";
			// 
			// btnSelectAll
			// 
			this.btnSelectAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.btnSelectAll.Location = new System.Drawing.Point(520, 8);
			this.btnSelectAll.Name = "btnSelectAll";
			this.btnSelectAll.Size = new System.Drawing.Size(48, 23);
			this.btnSelectAll.TabIndex = 20;
			this.btnSelectAll.Text = "全选";
			this.btnSelectAll.Click += new System.EventHandler(this.btnSelectAll_Click);
			// 
			// btnClearAll
			// 
			this.btnClearAll.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.btnClearAll.Location = new System.Drawing.Point(576, 8);
			this.btnClearAll.Name = "btnClearAll";
			this.btnClearAll.Size = new System.Drawing.Size(48, 23);
			this.btnClearAll.TabIndex = 21;
			this.btnClearAll.Text = "全清";
			this.btnClearAll.Click += new System.EventHandler(this.btnClearAll_Click);
			// 
			// btnCancel
			// 
			this.btnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.btnCancel.Location = new System.Drawing.Point(744, 8);
			this.btnCancel.Name = "btnCancel";
			this.btnCancel.Size = new System.Drawing.Size(48, 23);
			this.btnCancel.TabIndex = 23;
			this.btnCancel.Text = "取消";
			this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
			// 
			// btnOK
			// 
			this.btnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
			this.btnOK.Location = new System.Drawing.Point(688, 8);
			this.btnOK.Name = "btnOK";
			this.btnOK.Size = new System.Drawing.Size(48, 23);
			this.btnOK.TabIndex = 22;
			this.btnOK.Text = "确定";
			this.btnOK.Click += new System.EventHandler(this.btnOK_Click);
			// 
			// frmGridRefertoSelect
			// 
			this.AcceptButton = this.btnSelectAll;
			this.AutoScaleBaseSize = new System.Drawing.Size(6, 14);
			this.ClientSize = new System.Drawing.Size(800, 453);
			this.Controls.Add(this.btnCancel);
			this.Controls.Add(this.btnOK);
			this.Controls.Add(this.btnClearAll);
			this.Controls.Add(this.btnSelectAll);
			this.KeyPreview = true;
			this.Name = "frmGridRefertoSelect";
			this.Load += new System.EventHandler(this.frmGridRefertoSelect_Load);
			this.Controls.SetChildIndex(this.tbr_Toolbar, 0);
			this.Controls.SetChildIndex(this.sbr_StatusBar, 0);
			this.Controls.SetChildIndex(this.pnl_Filter, 0);
			this.Controls.SetChildIndex(this.panel1, 0);
			this.Controls.SetChildIndex(this.btnSelectAll, 0);
			this.Controls.SetChildIndex(this.btnClearAll, 0);
			this.Controls.SetChildIndex(this.btnOK, 0);
			this.Controls.SetChildIndex(this.btnCancel, 0);
			((System.ComponentModel.ISupportInitialize)(this.grd_Bottom)).EndInit();
			((System.ComponentModel.ISupportInitialize)(this.grd_Top)).EndInit();
			this.ResumeLayout(false);

		}
		#endregion

		private void frmGridRefertoSelect_Load(object sender, System.EventArgs e)
		{
			//强制再部局一下，有时不写就乱放了
			tv_Tree.Width =140;
			spt_H.Visible =true;
			spt_H.BringToFront() ;
			this.ShowResize();

			//绑定数据
			this.BindRefertoGrid();
			
			//使两表的结构相同
			m_BottomDataTable = m_TopDataTable.Clone();		
			this.grd_Bottom.DataSource = m_BottomDataTable;

			this.grd_Top.ReadOnly = true;
			//this.grd_Bottom.ReadOnly = true;
	
			SetDataGridCellTextBoxNoVisible(this.grd_Top);

			//设置行序列
			//			grd_Top.AllowShowRowHeaderSerialNo = true; 
			//			grd_Top.AllowShowColHeaderSerialNo = true;
			//			grd_Bottom.AllowShowRowHeaderSerialNo = true; 			
		}


		//为所有的行增加选择标记并增加到选择结果集中
		private void btnSelectAll_Click(object sender, System.EventArgs e)
		{
			//增加行
			for(int i=0 ; i<m_TopDataTable.Rows.Count ;i++)
			{
				AddSelectedRow(i);
			}

			//添加行选择标记
			SetGridRowSelectFlag(this.grd_Top,true);

			this.grd_Bottom.DataSource = m_BottomDataTable;
		}

		//清除所有行选择标记并在选择结果集中移除
		private void btnClearAll_Click(object sender, System.EventArgs e)
		{
			//删除行
			for(int i=0 ; i<m_TopDataTable.Rows.Count ;i++)
			{
				DelSelectedRow(i);
			}

			//清除行选择标记
			SetGridRowSelectFlag(this.grd_Top,false);

			this.grd_Bottom.DataSource = m_BottomDataTable;
		}

		private void btnOK_Click(object sender, System.EventArgs e)
		{
			mblnSelect = true;
			this.Close();
		}

		private void btnCancel_Click(object sender, System.EventArgs e)
		{
			mblnSelect = false;
			this.Close();
		}

		private new void grd_Top_Click(object sender, System.EventArgs e)
		{
			int lngCurrentRowIndex = grd_Top.CurrentCell.RowNumber;//CurrentRowIndex

			//高亮选择当前行
			grd_Top.CurrentCell = new DataGridCell(lngCurrentRowIndex,0);
			grd_Top.Select(lngCurrentRowIndex);		



			DataGrid.ControlCollection cs = grd_Top.Controls;
			foreach(Control c in cs)
			{
				if (c.GetType().ToString() == "System.Windows.Forms.DataGridTextBox")
				{					
					//焦点优先于单击
					c.GotFocus += new EventHandler(DataGridCellTextBox_GotFocus);					
				}
			}
		
		}

		//网格双击置标记或去除标记并增加/移除行
		private void grd_Top_DoubleClick(object sender, System.EventArgs e)
		{						
			int lngCurrentRowIndex = grd_Top.CurrentCell.RowNumber;//CurrentRowIndex

			bool blnRowsChange = false;
			if (this.grd_Top[lngCurrentRowIndex,0].ToString() =="√")
			{
				//将当前选择的行在选择结果集中删除
				blnRowsChange = DelSelectedRow(lngCurrentRowIndex);	

				//将选择标记改为行号或空
				//this.grd_Top[lngCurrentRowIndex,0] = (lngCurrentRowIndex + 1).ToString();
				this.grd_Top[lngCurrentRowIndex,0] = "";
			}
			else
			{
				//将当前选择的行增加到选择结果集中
				blnRowsChange = AddSelectedRow(lngCurrentRowIndex);	

				//选择标
				this.grd_Top[lngCurrentRowIndex ,0]="√";
				
			}		

			if(blnRowsChange)
			{
				//只要增加或删除了行，则重新绑定
				this.grd_Bottom.DataSource = m_BottomDataTable;
			}

			//高亮选择当前行
			grd_Top.CurrentCell = new DataGridCell(lngCurrentRowIndex,0);
			grd_Top.Select(lngCurrentRowIndex);		

		}

		//用数据源绑定参照网格
		private void BindRefertoGrid()
		{	
			if (_DataSource != "")
			{
				string strDataSource = _DataSource.ToLower();

				//m_TopDataTable = newADO.GetDataSet(_DataSource,_CommandType).Tables[0];
				//改成自动判断
				if (strDataSource.IndexOf("select")>=0 && strDataSource.IndexOf("from")>0)
				{
					m_TopDataTable = newADO.GetDataSet(_DataSource,System.Data.CommandType.Text).Tables[0];
				}
				else
				{
					m_TopDataTable = newADO.GetDataSet(_DataSource,System.Data.CommandType.StoredProcedure).Tables[0];				
				}

				if (this.DataSourceKey != "")
				{
					m_TopDataTable.PrimaryKey = new DataColumn[]{m_TopDataTable.Columns[this.DataSourceKey]};
				}

				grd_Top.DataSource = m_TopDataTable;
				//
				//				DataSet ds;
				//
				//				ds = newADO.GetDataSet(_DataSource,_CommandType);
				//
				//				DataTable dtMaster = ds.Tables[0];
				//				DataTable dtDetail = ds.Tables[1];
				//
				//				DataRelation  relation = new DataRelation("Master_Detail",dtMaster.Columns["单据号"],dtDetail.Columns["单据号"],false);
				//				//grd_Top.AllowNavigation = false;		//设置后显示不了关系了
				//				relation.Nested = false;
				//				ds.Relations.Add(relation);
				//				
				//				grd_Top.DataSource = dtMaster;

			}
		}

		///删除存在的行则返回真
		private bool DelSelectedRow(int p_rowIndex)
		{
			return DelDataTableRow(m_BottomDataTable,m_TopDataTable.Rows[p_rowIndex],this.DataSourceKey);
		}

		///增加新的选择行则返回真，如果指定了主键，则不会增加已存在的行
		private bool AddSelectedRow(int p_rowIndex)
		{		
			return AddDataTableRow(m_BottomDataTable,m_TopDataTable.Rows[p_rowIndex],this.DataSourceKey);
		}

		private void SetGridRowSelectFlag(DataGrid p_dataGrid,bool p_Selected)
		{
			if (p_Selected)
			{
				m_dataGridAccess.SetColText(p_dataGrid,0,"√");
			}
			else
			{
				m_dataGridAccess.SetColText(p_dataGrid,0,"");			
			}
		}



		#region 增加/删除DataTable中指定的行
		/// <summary>
		/// 删除DataTable中指定的行，如果存在此行则删除并返回真
		/// </summary>
		/// <param name="p_dataTable"></param>
		/// <param name="p_dataRow"></param>
		/// <param name="p_primaryKey"></param>
		/// <returns></returns>
		private bool DelDataTableRow(DataTable p_dataTable,DataRow p_dataRow,string p_primaryKey)
		{	
			bool blnReturn = false;
			DataRow dr = null;

			try
			{

				// 注意：一定要指定主键列，否则不好找。因为是拷贝了主表的结构，而主表已经指定了主键列，所以这里不用再指了
				if (this.DataSourceKey != "")
				{
					p_dataTable.PrimaryKey = new DataColumn[]{p_dataTable.Columns[p_primaryKey]};
			
					dr = p_dataTable.Rows.Find(p_dataRow[p_primaryKey]);
				}

				if(dr != null)
				{
					p_dataTable.Rows.Remove(dr);

					blnReturn = true;
				}
			}
			catch
			{
				//要求主键唯一
			}
			
			return blnReturn;
		}

		/// <summary>
		/// 在DataTable中增加指定的行，如果没指定键则直接增加指定行；如果指定了键且不存在此行也增加。若增加了行返回真
		/// </summary>
		/// <param name="p_dataTable"></param>
		/// <param name="p_dataRow"></param>
		/// <param name="p_primaryKey"></param>
		/// <returns></returns>
		private bool AddDataTableRow(DataTable p_dataTable,DataRow p_dataRow,string p_primaryKey)
		{		
			bool blnReturn = false;
			DataRow dr = null;

			// 注意：一定要指定主键列，否则不好找。因为是拷贝了主表的结构，而主表已经指定了主键列，所以这里不用再指了
			if (p_primaryKey != "")
			{
				p_dataTable.PrimaryKey = new DataColumn[]{p_dataTable.Columns[p_primaryKey]};
			
				dr = p_dataTable.Rows.Find(p_dataRow[p_primaryKey]);
			}
			
			//如果指定了主键，当行已存在就不加了；若没有指定主键，直接复制行
			if ((p_primaryKey == "") || ((p_primaryKey != "") && dr == null))
			{
				//此方法不能啊，原因是一个表的列或行是不能加到另一个表中的	
				//p_dataTable.Rows.Add(p_dataRow);

				//所以复制行
				p_dataTable.ImportRow(p_dataRow); //p_dataTable.Rows.Add(p_dataRow.ItemArray);复制数据也可
			
				blnReturn = true;
			}

			return blnReturn;		
		}
		#endregion

		#region SetDataGridCellTextBoxNoVisible(DataGrid) 使网格单击格里的文本框不再出现
		private void SetDataGridCellTextBoxNoVisible(DataGrid p_dataGrid)
		{
			DataGrid.ControlCollection cs = p_dataGrid.Controls;
			foreach(Control c in cs)
			{
				if (c.GetType().ToString() == "System.Windows.Forms.DataGridTextBox")
				{					
					//焦点优先于单击
					c.GotFocus += new EventHandler(DataGridCellTextBox_GotFocus);					
				}
			}
		}

		private void DataGridCellTextBox_GotFocus(object sender,System.EventArgs e)
		{
			DataGridTextBox tb = (DataGridTextBox)sender;

			//使文本框不可见
			tb.Width=0;
			tb.Visible = false;
		}
		#endregion

		private void grd_Top_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
		{
			//			m_dataGridAccess.SetRowHeaderSerialNo(grd_Top,grd_Top.Font);
			//			m_dataGridAccess.SetRowHeaderSerialNo(grd_Bottom,grd_Top.Font);
			
		}



	}//End Class
}//End NameSpace

