/******************************************************************************
 * GODSAccessDBWrapper.cs 
 * 
 * <Copyright and License> 
 * 
 * This file is part of GODS, a package for annotating medical images. 
 * 
 * Copyright (C) 2004 
 * Xuedong Chen 
 * Heri Mariwa 
 * Kimmy (Hsiang-ling) Lin 
 * Rui Yu 
 * 
 * This program is free software; you can redistribute it and/or 
 * modify it under the terms of the GNU General Public License 
 * as published by the Free Software Foundation; either version 2 
 * of the License, or (at your option) any later version. 
 * 
 * This program is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
 * GNU General Public License for more details. 
 * 
 * You should have received a copy of the GNU General Public License 
 * along with this program; if not, write to the Free Software 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
 *  
 * For further questions about this file, please send email to 
 * gods@cs.umb.edu or visit us at http://gods.sourceforge.net.  
 ******************************************************************************/

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

namespace GODS.DBHandler
{
	/// <summary>
	/// GODSDBWrapper wraps the GodsDbDataSet operation
	/// </summary>
	public class GodsAccessDBWrapper : IGodsDBWrapper, IGodsDBMarkSetWrapper
	{
		private System.Data.OleDb.OleDbConnection godsDBConn;
		private System.Data.OleDb.OleDbDataAdapter godsImageTBAdapt;
		private System.Data.OleDb.OleDbDataAdapter godsImageMarkTBAdapt;
		private System.Data.OleDb.OleDbDataAdapter godsMarkSetTBAdapt;
		private System.Data.OleDb.OleDbDataAdapter godsMarkTBAdapt;
		private System.Data.OleDb.OleDbDataAdapter godsMarkValueListTBAdapt;

		private System.Data.DataSet godsDs;
		private String dbPath;

		public GodsAccessDBWrapper()
		{
			dbPath = GODS.GODSMain.ExecDir + "GODS2.mdb";
			initDBWrapper();
		}

		//constructor takes GODS2.mdb path for initialized the connection
		public GodsAccessDBWrapper(String path)
		{
			dbPath = path;
			initDBWrapper();
		}
		
		private void initDBWrapper()
		{
			//init the connection string for all adapters
			this.godsDBConn = new System.Data.OleDb.OleDbConnection();
			String connPrefix = @"Jet OLEDB:Global Partial Bulk Ops=2;Data Source=""";
			String connPostfix = @""";Jet OLEDB:Engine Type=5;Provider=""Microsoft.Jet.OLEDB.4.0""";
			this.godsDBConn.ConnectionString = connPrefix + dbPath + connPostfix; 

			SetupImagesTBAdapter();
			SetupImageMarksTBAdapter();
			SetupMarkSetTBAdapter();
			SetupMarkTBAdapter();
			SetupMarkValueListTBAdapter();
			godsDs = new DataSet();

			this.godsImageTBAdapt.FillSchema(godsDs, SchemaType.Source, "DiagnosticImgesTB");
			this.godsImageMarkTBAdapt.FillSchema(godsDs, SchemaType.Source, "ImageMarkTB");
			this.godsMarkSetTBAdapt.FillSchema(godsDs, SchemaType.Source, "MarkSetTB");
			this.godsMarkTBAdapt.FillSchema(godsDs, SchemaType.Source, "MarkTB");
			this.godsMarkValueListTBAdapt.FillSchema(godsDs, SchemaType.Source, "MarkValueListTB");
			LoadData();
		}

		private void LoadData()
		{
			//fill the GODS dataset and sort them
			try
			{
				this.godsImageTBAdapt.Fill(godsDs,"DiagnosticImgesTB");
				this.godsImageMarkTBAdapt.Fill(godsDs,"ImageMarkTB");
				this.godsMarkSetTBAdapt.Fill(godsDs,"MarkSetTB");
				this.godsMarkTBAdapt.Fill(godsDs,"MarkTB");
				this.godsMarkValueListTBAdapt.Fill(godsDs,"MarkValueListTB");
			}			
			catch (OleDbException dbex)
			{
				Console.WriteLine(dbex.Message);
				MessageBox.Show("\n Default Database isn't setup correctly please check it again!" );
			}
			//Toref:
			//if has dataview, need to sort first
			//this.imageDataViewer.Sort = "MRN";
			//this.markDataViewer.Sort = "MRN";
		}

		private void SetupImagesTBAdapter()
		{
			String cmdText;
			// 
			// godsImageTBAdapt
			// 
			godsImageTBAdapt=new OleDbDataAdapter();
			this.godsImageTBAdapt.TableMappings.AddRange(new System.Data.Common.DataTableMapping[] {	
																									   new System.Data.Common.DataTableMapping("Table", "DiagnosticImgesTB", 
																									   new System.Data.Common.DataColumnMapping[] {
																																					  new System.Data.Common.DataColumnMapping("ImageID", "ImageID"),
																																					  new System.Data.Common.DataColumnMapping("Category", "Category"), 
																																					  new System.Data.Common.DataColumnMapping("LibraryFlag", "LibraryFlag"),
																																					  new System.Data.Common.DataColumnMapping("AnnotImgPath", "AnnotImgPath"),
																																					  new System.Data.Common.DataColumnMapping("OrigImgPath", "OrigImgPath"),
																																					  new System.Data.Common.DataColumnMapping("OrigImgRectX", "OrigImgRectX"),
																																					  new System.Data.Common.DataColumnMapping("OrigImgRectY", "OrigImgRectY"),
																																					  new System.Data.Common.DataColumnMapping("OrigImgRectWidth", "OrigImgRectWidth"),
																																					  new System.Data.Common.DataColumnMapping("OrigImgRectHeight", "OrigImgRectHeight"),
																																					  new System.Data.Common.DataColumnMapping("Summary", "Summary"),
																																					  new System.Data.Common.DataColumnMapping("Reason", "Reason"),
																																					  new System.Data.Common.DataColumnMapping("AppDate", "AppDate"),
																																					  new System.Data.Common.DataColumnMapping("UpdateDate", "UpdateDate"),
																																					  new System.Data.Common.DataColumnMapping("MRN", "MRN"),
																																					  new System.Data.Common.DataColumnMapping("MarkSetID", "MarkSetID"),
																																					  new System.Data.Common.DataColumnMapping("FinalFlag", "FinalFlag")
																																						  
																								   })
																								   });

			// 
			// set up select cmd
			// 
			cmdText = "SELECT * FROM DiagnosticImgesTB";
			this.godsImageTBAdapt.SelectCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);


			cmdText = "DELETE FROM DiagnosticImagesTB WHERE (MRN = ?)";
			


			this.godsImageTBAdapt.DeleteCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);
			this.godsImageTBAdapt.DeleteCommand.Parameters.Add(new OleDbParameter("Original_MRN", OleDbType.VarWChar, 50, ParameterDirection.Input, false, ((Byte)(0)), ((Byte)(0)), "MRN", DataRowVersion.Original, null));
			
			// 
			// set up insert command
			// 
			cmdText = "INSERT INTO DiagnosticImgesTB(ImageID, MRN,Category, LibraryFlag, AnnotImgPath, OrigImgPath, OrigImgRectX, OrigImgRectY, OrigImgRectWidth, OrigImgRectHeight, Summary, Reason, AppDate, UpdateDate, MarkSetID, FinalFlag" +
				") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";

			this.godsImageTBAdapt.InsertCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);

			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("ImageID", System.Data.OleDb.OleDbType.Integer, 0, "ImageID"));
			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MRN", System.Data.OleDb.OleDbType.VarWChar, 50, "MRN"));
			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("Category", System.Data.OleDb.OleDbType.VarWChar, 100, "Category"));
			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("LibraryFlag", System.Data.OleDb.OleDbType.Boolean, 0, "LibraryFlag"));	
			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("AnnotImgPath", System.Data.OleDb.OleDbType.VarWChar, 255, "AnnotImgPath"));
			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("OrigImgPath", System.Data.OleDb.OleDbType.VarWChar, 255, "OrigImgPath"));
			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("OrigImgRectX", System.Data.OleDb.OleDbType.Integer, 0, "OrigImgRectX"));
			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("OrigImgRectY", System.Data.OleDb.OleDbType.Integer, 0, "OrigImgRectY"));
			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("OrigImgRectWidth", System.Data.OleDb.OleDbType.Integer, 0, "OrigImgRectWidth"));
			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("OrigImgRectHeight", System.Data.OleDb.OleDbType.Integer, 0, "OrigImgRectHeight"));
			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("Summary", System.Data.OleDb.OleDbType.VarWChar, 5000, "Summary"));
			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("Reason", System.Data.OleDb.OleDbType.VarWChar, 255, "Reason"));
			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("AppDate", System.Data.OleDb.OleDbType.Date, 0, "AppDate"));
			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("UpdateDate", System.Data.OleDb.OleDbType.Date, 0, "UpdateDate"));
			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MarkSetID", System.Data.OleDb.OleDbType.Integer, 0, "MarkSetID"));
			this.godsImageTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("FinalFlag", System.Data.OleDb.OleDbType.Boolean, 0, "FinalFlag"));	

			// 
			// oleDbUpdateCommand2
			// 
			cmdText = "UPDATE DiagnosticImgesTB SET ImageID=?, MRN=?,Category=?, LibraryFlag=?, AnnotImgPath=?,OrigImgPath=?, OrigImgRectX=?, OrigImgRectY=?, OrigImgRectWidth=?, OrigImgRectHeight=?, Summary=?, Reason=?, AppDate=?, UpdateDate=?, MarkSetID=?, FinalFlag=? WHERE (ImageID = ?)";
			this.godsImageTBAdapt.UpdateCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("ImageID", System.Data.OleDb.OleDbType.Integer, 0, "ImageID"));
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MRN", System.Data.OleDb.OleDbType.VarWChar, 50, "MRN"));
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("Category", System.Data.OleDb.OleDbType.VarWChar, 100, "Category"));
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("LibraryFlag", System.Data.OleDb.OleDbType.Boolean, 0, "LibraryFlag"));
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("AnnotImgPath", System.Data.OleDb.OleDbType.VarWChar, 255, "AnnotImgPath"));
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("OrigImgPath", System.Data.OleDb.OleDbType.VarWChar, 255, "OrigImgPath"));
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("OrigImgRectX", System.Data.OleDb.OleDbType.Integer, 0, "OrigImgRectX"));
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("OrigImgRectY", System.Data.OleDb.OleDbType.Integer, 0, "OrigImgRectY"));
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("OrigImgRectWidth", System.Data.OleDb.OleDbType.Integer, 0, "OrigImgRectWidth"));
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("OrigImgRectHeight", System.Data.OleDb.OleDbType.Integer, 0, "OrigImgRectHeight"));
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("Summary", System.Data.OleDb.OleDbType.VarWChar, 5000, "Summary"));
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("Reason", System.Data.OleDb.OleDbType.VarWChar, 255, "Reason"));
			//uaw OleDbType.Date instead of OleDbType.DBDate which has only date without time, the OleDbType.DBTimeStamp also won't work since it is only integer
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("AppDate", System.Data.OleDb.OleDbType.Date, 0, "AppDate"));
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("UpdateDate", System.Data.OleDb.OleDbType.Date, 0, "UpdateDate"));
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MarkSetID", System.Data.OleDb.OleDbType.Integer, 0, "MarkSetID"));
			
			//must keep the ordering of the parameter
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("FinalFlag", System.Data.OleDb.OleDbType.Boolean, 0, "FinalFlag"));
			this.godsImageTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("ImageID", System.Data.OleDb.OleDbType.Integer, 0, "ImageID"));
		
		}

		
		private void SetupImageMarksTBAdapter()
		{
			String cmdText;
			godsImageMarkTBAdapt=new OleDbDataAdapter();
			this.godsImageMarkTBAdapt.TableMappings.AddRange(
				new DataTableMapping[] 
				{
					new DataTableMapping(
					"Table", 
					"ImageMarkTB", 
					new DataColumnMapping[] 
								{
									new DataColumnMapping("ImageID", "ImageID"),
									new DataColumnMapping("MarkID", "MarkID"),
									new DataColumnMapping("Position_X", "Position_X"),
									new DataColumnMapping("Position_Y", "Position_Y"),
									new DataColumnMapping("EstimateWidth", "EstimateWidth"),
									new DataColumnMapping("EstimateHeight", "EstimateHeight"),
									new DataColumnMapping("Comment", "Comment"),
									new DataColumnMapping("ValueIndex", "ValueIndex"),
									new DataColumnMapping("Ratio", "Ratio")
								})
				});

			// 
			// set up select cmd
			// 
			cmdText = "SELECT * FROM ImageMarkTB";
			this.godsImageMarkTBAdapt.SelectCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);

			// 
			// set up insert cmd
			// 
			cmdText =  "INSERT INTO ImageMarkTB(Comment, MarkID" +
				", ImageID, Position_X, Position_Y, EstimateWidth, EstimateHeight,  Ratio, ValueIndex) VALUE" +
				"S (?, ?, ?, ?, ?, ?, ?, ?, ?)";
			this.godsImageMarkTBAdapt.InsertCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);

			this.godsImageMarkTBAdapt.InsertCommand.Parameters.Add(new OleDbParameter("Comment", OleDbType.VarWChar, 255, "Comment"));
			this.godsImageMarkTBAdapt.InsertCommand.Parameters.Add(new OleDbParameter("MarkID", OleDbType.Integer, 0, "MarkID"));
			this.godsImageMarkTBAdapt.InsertCommand.Parameters.Add(new OleDbParameter("ImageID", OleDbType.Integer, 0, "ImageID"));
			this.godsImageMarkTBAdapt.InsertCommand.Parameters.Add(new OleDbParameter("Position_X", OleDbType.Integer, 0, "Position_X"));
			this.godsImageMarkTBAdapt.InsertCommand.Parameters.Add(new OleDbParameter("Position_Y", OleDbType.Integer, 0, "Position_Y"));
			this.godsImageMarkTBAdapt.InsertCommand.Parameters.Add(new OleDbParameter("EstimateWidth", OleDbType.Double, 8, "EstimateWidth"));
			this.godsImageMarkTBAdapt.InsertCommand.Parameters.Add(new OleDbParameter("EstimateHeight", OleDbType.Double, 8, "EstimateHeight"));
			this.godsImageMarkTBAdapt.InsertCommand.Parameters.Add(new OleDbParameter("Ratio", OleDbType.Double, 8, "Ratio"));
			this.godsImageMarkTBAdapt.InsertCommand.Parameters.Add(new OleDbParameter("ValueIndex", OleDbType.Integer, 0, "ValueIndex"));
			

			// 
			// No need for update command
			// 
			
			// 
			// set up delete command
			// 
			cmdText = @"DELETE FROM ImageMarkTB WHERE (ImageID = ?) AND (MarkID = ?) AND (Position_X = ?) AND (Position_Y = ?)" ;
			this.godsImageMarkTBAdapt.DeleteCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);

			this.godsImageMarkTBAdapt.DeleteCommand.Parameters.Add(new OleDbParameter("ImageID", OleDbType.Integer, 0, "ImageID"));
			this.godsImageMarkTBAdapt.DeleteCommand.Parameters.Add(new OleDbParameter("Original_MarkID", OleDbType.Integer, 0, ParameterDirection.Input, false, ((Byte)(0)), ((Byte)(0)), "MarkID", DataRowVersion.Original, null));
			this.godsImageMarkTBAdapt.DeleteCommand.Parameters.Add(new OleDbParameter("Original_Position_X", OleDbType.Integer, 0, ParameterDirection.Input, false, ((Byte)(0)), ((Byte)(0)), "Position_X", DataRowVersion.Original, null));
			this.godsImageMarkTBAdapt.DeleteCommand.Parameters.Add(new OleDbParameter("Original_Position_Y", OleDbType.Integer, 0, ParameterDirection.Input, false, ((Byte)(0)), ((Byte)(0)), "Position_Y", DataRowVersion.Original, null));
			
		}
		
		
		private void SetupMarkSetTBAdapter()
		{
			String cmdText;
			// 
			// godsDschgTBAdapt
			// 
			godsMarkSetTBAdapt=new OleDbDataAdapter();
			this.godsMarkSetTBAdapt.TableMappings.AddRange(new System.Data.Common.DataTableMapping[] {
																										 new System.Data.Common.DataTableMapping("Table", "MarkSetTB", 
																										 new System.Data.Common.DataColumnMapping[] {
																																						new System.Data.Common.DataColumnMapping("MarkSetID", "MarkSetID"),
																																						new System.Data.Common.DataColumnMapping("MarkSetName", "MarkSetName"),
																																						new System.Data.Common.DataColumnMapping("Category", "Category"),
																																						new System.Data.Common.DataColumnMapping("SampleImagePath", "SampleImagePath"),
																																						new System.Data.Common.DataColumnMapping("Status", "Status")
																																					})
																									 });

			// 
			// set up select cmd
			// 
			cmdText = "SELECT * FROM MarkSetTB";
			this.godsMarkSetTBAdapt.SelectCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);

			// 
			// set up delete command
			// 
			//Toconfirm: whether adapter command is arbitrary
			cmdText = "DELETE FROM MarkSetTB WHERE (MarkSetID = ?)";
			
			this.godsMarkSetTBAdapt.DeleteCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);
			this.godsMarkSetTBAdapt.DeleteCommand.Parameters.Add(new OleDbParameter("MarkSetID", OleDbType.Integer, 0, "MarkSetID"));
			
			// 
			// set up insert command
			// 
			cmdText = "INSERT INTO MarkSetTB(MarkSetID, MarkSetName, Category, SampleImagePath, Status" +
				") VALUES (?, ?, ?, ?, ?)";

			this.godsMarkSetTBAdapt.InsertCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);

			this.godsMarkSetTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MarkSetID", System.Data.OleDb.OleDbType.Integer, 0, "MarkSetID"));
			this.godsMarkSetTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MarkSetName", System.Data.OleDb.OleDbType.VarWChar, 100, "MarkSetName"));
			this.godsMarkSetTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("Category", System.Data.OleDb.OleDbType.VarWChar, 100, "Category"));
			this.godsMarkSetTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("SampleImagePath", System.Data.OleDb.OleDbType.VarWChar, 255, "SampleImagePath"));
			this.godsMarkSetTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("Status", System.Data.OleDb.OleDbType.VarWChar, 50, "Status"));
		
					
			cmdText = "UPDATE MarkSetTB SET MarkSetID=?, MarkSetName=?, Category=?, SampleImagePath=?, Status=? WHERE (MarkSetID = ?)";
			this.godsMarkSetTBAdapt.UpdateCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);

			this.godsMarkSetTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MarkSetID", System.Data.OleDb.OleDbType.Integer, 0, "MarkSetID"));
			this.godsMarkSetTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MarkSetName", System.Data.OleDb.OleDbType.VarWChar, 100, "MarkSetName"));
			this.godsMarkSetTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("Category", System.Data.OleDb.OleDbType.VarWChar, 100, "Category"));
			this.godsMarkSetTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("SampleImagePath", System.Data.OleDb.OleDbType.VarWChar, 255, "SampleImagePath"));
			this.godsMarkSetTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("Status", System.Data.OleDb.OleDbType.VarWChar, 50, "Status"));
			this.godsMarkSetTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MarkSetID", System.Data.OleDb.OleDbType.Integer, 0, "MarkSetID"));
		}

		private void SetupMarkTBAdapter()
		{
			String cmdText;
			// 
			// godsDschgTBAdapt
			// 
			godsMarkTBAdapt=new OleDbDataAdapter();
			this.godsMarkTBAdapt.TableMappings.AddRange(new System.Data.Common.DataTableMapping[] {
																									  new System.Data.Common.DataTableMapping("Table", "MarkTB", 
																									  new System.Data.Common.DataColumnMapping[] {
																																					 new System.Data.Common.DataColumnMapping("MarkID", "MarkID"),
																																					 new System.Data.Common.DataColumnMapping("MarkName", "MarkName"),
																																					 new System.Data.Common.DataColumnMapping("MarkSetID", "MarkSetID"),
																																					 new System.Data.Common.DataColumnMapping("GroupName", "GroupName"),
																																					 new System.Data.Common.DataColumnMapping("Description", "Description"),
																																					 new System.Data.Common.DataColumnMapping("ImageWidth", "ImageWidth"),
																																					 new System.Data.Common.DataColumnMapping("ImageHeight", "ImageHeight"),
																																					 new System.Data.Common.DataColumnMapping("IsSingleton", "IsSingleton"),
																																					 new System.Data.Common.DataColumnMapping("ImagePath", "ImagePath"),
	

																								  })
																								  });

			// 
			// set up select cmd
			// 
			cmdText = "SELECT * FROM MarkTB";
			this.godsMarkTBAdapt.SelectCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);

			// 
			// set up delete command
			// 
				
			cmdText = "DELETE FROM MarkTB WHERE (MarkID = ?)";
			
			this.godsMarkTBAdapt.DeleteCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);
			this.godsMarkTBAdapt.DeleteCommand.Parameters.Add(new OleDbParameter("MarkID", OleDbType.Integer, 0, "MarkID"));
			

			//!!!Extremely careful about the field name
			//Even for insert, and update query, if you put some field name same as keyword, it will cause
			//the error reporting syntax error
			//For example if you use "INSERT INTO(MarkTB(MarkID, MarkName, MarkSetID, Group, ....)..."
			//It will report insert syntax error due to the 'Group'.
			//What a stupid parser!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
			//I have change fieldName Group to GroupName, for consistancy, access db MarkTB use GroupName as well.

			// 
			// set up insert command
			// 
			cmdText = "INSERT INTO MarkTB(MarkID, MarkName, MarkSetID, GroupName, Description, ImageWidth, ImageHeight, ImagePath, IsSingleton" +
				") VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)";

			this.godsMarkTBAdapt.InsertCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);

			this.godsMarkTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MarkID", System.Data.OleDb.OleDbType.Integer, 0, "MarkID"));
			this.godsMarkTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MarkName", System.Data.OleDb.OleDbType.VarWChar, 100, "MarkName"));
			this.godsMarkTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MarkSetID", System.Data.OleDb.OleDbType.Integer, 0, "MarkSetID"));
			this.godsMarkTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("GroupName", System.Data.OleDb.OleDbType.VarWChar, 100, "GroupName"));
			this.godsMarkTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("Description", System.Data.OleDb.OleDbType.VarWChar, 255, "Description"));
			this.godsMarkTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("ImageWidth", System.Data.OleDb.OleDbType.Integer, 0, "ImageWidth"));
			this.godsMarkTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("ImageHeight", System.Data.OleDb.OleDbType.Integer, 0, "ImageHeight"));
			this.godsMarkTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("ImagePath", System.Data.OleDb.OleDbType.VarWChar, 255, "ImagePath"));
			this.godsMarkTBAdapt.InsertCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("IsSingleton", System.Data.OleDb.OleDbType.Boolean, 0, "IsSingleton"));

		
					
			cmdText = "UPDATE MarkTB SET MarkID=?, MarkName=?, MarkSetID=?, GroupName=?, Description=?, ImageWidth=?, ImageHeight=?, ImagePath=?, IsSingleton=? WHERE (MarkID = ?)";
			this.godsMarkTBAdapt.UpdateCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);

			this.godsMarkTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MarkID", System.Data.OleDb.OleDbType.Integer, 0, "MarkID"));
			this.godsMarkTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MarkName", System.Data.OleDb.OleDbType.VarWChar, 100, "MarkName"));
			this.godsMarkTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MarkSetID", System.Data.OleDb.OleDbType.Integer, 0, "MarkSetID"));
			this.godsMarkTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("GroupName", System.Data.OleDb.OleDbType.VarWChar, 100, "GroupName"));
			this.godsMarkTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("Description", System.Data.OleDb.OleDbType.VarWChar, 255, "Description"));
			this.godsMarkTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("ImageWidth", System.Data.OleDb.OleDbType.Integer, 0, "ImageWidth"));
			this.godsMarkTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("ImageHeight", System.Data.OleDb.OleDbType.Integer, 0, "ImageHeight"));
			this.godsMarkTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("ImagePath", System.Data.OleDb.OleDbType.VarWChar, 255, "ImagePath"));
			this.godsMarkTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("IsSingleton", System.Data.OleDb.OleDbType.Boolean, 0, "IsSingleton"));
			this.godsMarkTBAdapt.UpdateCommand.Parameters.Add(new System.Data.OleDb.OleDbParameter("MarkID", System.Data.OleDb.OleDbType.Integer, 0, "MarkID"));
		}

		private void SetupMarkValueListTBAdapter()
		{
			String cmdText;
			godsMarkValueListTBAdapt=new OleDbDataAdapter();
			this.godsMarkValueListTBAdapt.TableMappings.AddRange(
				new DataTableMapping[] 
				{
					new DataTableMapping(
					"Table", 
					"MarkValueListTB", 
					new DataColumnMapping[] 
								{
									new DataColumnMapping("MarkID", "MarkID"),
									new DataColumnMapping("ListValue", "ListValue")	
								})
				});

			// 
			// set up select cmd
			// 
			cmdText = "SELECT * FROM MarkValueListTB";
			this.godsMarkValueListTBAdapt.SelectCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);

			// 
			// set up insert cmd
			// 
			cmdText =  "INSERT INTO MarkValueListTB(MarkID, ListValue) VALUE" +
				"S (?, ?)";
			this.godsMarkValueListTBAdapt.InsertCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);

			this.godsMarkValueListTBAdapt.InsertCommand.Parameters.Add(new OleDbParameter("MarkID", OleDbType.Integer, 0, "MarkID"));
			this.godsMarkValueListTBAdapt.InsertCommand.Parameters.Add(new OleDbParameter("ListValue", OleDbType.VarWChar, 255, "ListValue"));
				
			

			// 
			// No need for update command
			// 
			
			// 
			// set up delete command
			// 
			cmdText = @"DELETE FROM MarkValueListTB WHERE (MarkID = ?) AND (ListValue = ?)" ;
			this.godsMarkValueListTBAdapt.DeleteCommand = new System.Data.OleDb.OleDbCommand(cmdText,godsDBConn);

			this.godsMarkValueListTBAdapt.DeleteCommand.Parameters.Add(new OleDbParameter("MarkID", OleDbType.Integer, 0, "MarkID"));
			this.godsMarkValueListTBAdapt.DeleteCommand.Parameters.Add(new OleDbParameter("ListValue", OleDbType.VarWChar,255, "ListValue"));
				
		}

		#region IGodsDBWrapper interface implementation

		/// <summary>
		/// Get all distinct mrns from image table
		/// return null if no image
		/// </summary>
		public string[] getAllMrn()
		{
			DataView dv = new DataView(godsDs.Tables["DiagnosticImgesTB"]);			
			dv.Sort = "MRN";
			
			if(dv.Count ==0)
			{
				//no such category info
				return null;
			}
		
			ArrayList mrnData = new ArrayList();
			for(int i=0; i<dv.Count; i++)
			{
				if(i==0)
				{
					mrnData.Add((string)dv[i]["MRN"]);
				}
				else
				{
					if((string)dv[i]["MRN"] != (string)dv[i-1]["MRN"])
					{
						mrnData.Add((string)dv[i]["MRN"]);
					}
				}
			}
			return (string[])mrnData.ToArray(Type.GetType("System.String"));
		}
			
		/// <summary>
		/// Get all rows with the specified mrn from image table
		/// return null if no image
		/// </summary>
		public ImageData[] getImgData(string mrn)
		{
			//DataView dv = new DataView(godsDs.Tables["DiagnosticImagesTB"], "MRN = "+mrn, "MRN", DataViewRowState.CurrentRows);
			DataView dv = godsDs.Tables["DiagnosticImgesTB"].DefaultView;
			dv.Sort="MRN";
			DataRowView[] data = dv.FindRows(mrn);
			if (data.Length ==0)
			{
				//no such mrn image
				return null;
			}
		
			ImageData[] imgData = new ImageData[data.Length];
			for(int i=0; i<data.Length; i++)
			{
				imgData[i] = 
					new ImageData(
					(int)data[i]["ImageID"],
					(string)data[i]["MRN"],
					(int)data[i]["MarkSetID"],
					(string)data[i]["Category"],
					(string)data[i]["AnnotImgPath"],

					(string)data[i]["OrigImgPath"],
					(int)data[i]["OrigImgRectX"],
					(int)data[i]["OrigImgRectY"],
					(int)data[i]["OrigImgRectWidth"],
					(int)data[i]["OrigImgRectHeight"],

					data[i]["Summary"]==DBNull.Value?"":(string)data[i]["Summary"],
					data[i]["Reason"]==DBNull.Value?"":(string)data[i]["Reason"],
					(bool)data[i]["LibraryFlag"],
					(DateTime)data[i]["AppDate"],
					(DateTime)data[i]["UpdateDate"],
					(bool)data[i]["FinalFlag"]);
			}
			return imgData;
		}

		/// <summary>
		/// Get all rows with the specified mrn from image table
		/// return null if no image
		/// </summary>
		public ImageData getImgDataByDate(string mrn, DateTime appDate)
		{
			//DataView dv = new DataView(godsDs.Tables["DiagnosticImagesTB"], "MRN = "+mrn, "MRN", DataViewRowState.CurrentRows);
			DataView dv = godsDs.Tables["DiagnosticImgesTB"].DefaultView;
			dv.Sort="MRN";
			DataRowView[] data = dv.FindRows(mrn);
			if (data.Length ==0)
			{
				//no such mrn image
				return null;
			}
		
			for(int i=0; i<data.Length; i++)
			{
				if (appDate.Equals((DateTime)data[i]["AppDate"])) 
				{
					return new ImageData(
						(int)data[i]["ImageID"],
						(string)data[i]["MRN"],
						(int)data[i]["MarkSetID"],
						(string)data[i]["Category"],
						(string)data[i]["AnnotImgPath"],

						(string)data[i]["OrigImgPath"],
						(int)data[i]["OrigImgRectX"],
						(int)data[i]["OrigImgRectY"],
						(int)data[i]["OrigImgRectWidth"],
						(int)data[i]["OrigImgRectHeight"],

						data[i]["Summary"]==DBNull.Value?"":(string)data[i]["Summary"],
						data[i]["Reason"]==DBNull.Value?"":(string)data[i]["Reason"],
						(bool)data[i]["LibraryFlag"],
						(DateTime)data[i]["AppDate"],
						(DateTime)data[i]["UpdateDate"],
						(bool)data[i]["FinalFlag"]);
				}
			}
			return null;
		}

		/// <summary>
		/// Get the most recent editing image have the MRN
		/// </summary>
		/// <param name="mrn"></param>
		/// <returns></returns>
		public ImageData getLatestImgData(string mrn)
		{
			DataView dv = godsDs.Tables["DiagnosticImgesTB"].DefaultView;
			dv.Sort="MRN";
			DataRowView[] data = dv.FindRows(mrn);
			if(data.Length ==0)
			{
				//no such mrn image
				return null;
			}
			
			int latestImageID = 0;
			int latestIdx = 0;
			for(int i=0; i<data.Length; i++)
			{
				if((int)data[i]["ImageID"] > latestImageID)
				{
					latestImageID = (int)data[i]["ImageID"];
					latestIdx = i;
				}
			}

			return new ImageData(
				(int)data[latestIdx]["ImageID"],
				(string)data[latestIdx]["MRN"],
				(int)data[latestIdx]["MarkSetID"],
				(string)data[latestIdx]["Category"],
				(string)data[latestIdx]["AnnotImgPath"],
				(string)data[latestIdx]["OrigImgPath"],
				(int)data[latestIdx]["OrigImgRectX"],
				(int)data[latestIdx]["OrigImgRectY"],
				(int)data[latestIdx]["OrigImgRectWidth"],
				(int)data[latestIdx]["OrigImgRectHeight"],

				(string)data[latestIdx]["Summary"],
				(string)data[latestIdx]["Reason"],
				(bool)data[latestIdx]["LibraryFlag"],
				(DateTime)data[latestIdx]["AppDate"],
				(DateTime)data[latestIdx]["UpdateDate"],
				(bool)data[latestIdx]["FinalFlag"]);

		}
		/// <summary>
		/// get existing max Image ID for insert new image
		/// return 0 means no image yet
		/// </summary>
		public int getMaxImgID()
		{
			DataView dv = godsDs.Tables["DiagnosticImgesTB"].DefaultView;
			dv.Sort="ImageID";
			//in case of not Img
			if(dv.Count == 0)
			{
				return 0;
			}

			int maxId = (int)dv[dv.Count-1]["ImageID"];
			return maxId;
		}

		/// <summary>
		/// insert a row of image data to image table
		/// </summary>		
		public void insertImgTB(ImageData imgData)
		{
			DataRow newRow  = godsDs.Tables["DiagnosticImgesTB"].NewRow();
			newRow["ImageID"] = imgData.ImageId;
			newRow["MRN"] = imgData.Mrn;
			newRow["MarkSetID"] = imgData.MarkSetID;
			newRow["Category"] = imgData.Category;
			newRow["AnnotImgPath"] = imgData.AnnotImgPath;

			newRow["OrigImgPath"] = imgData.OrigImgPath;
			newRow["OrigImgRectX"] = imgData.OrigImgRectX;
			newRow["OrigImgRectY"] = imgData.OrigImgRectY;
			newRow["OrigImgRectWidth"] = imgData.OrigImgRectWidth;
			newRow["OrigImgRectHeight"] = imgData.OrigImgRectHeight;

			newRow["Summary"] = imgData.Summary;
			newRow["Reason"] = imgData.Reason;
			newRow["LibraryFlag"] = imgData.LibFlag;
			newRow["AppDate"] = imgData.AppDate;
			newRow["UpdateDate"] = imgData.UpdateDate;
			newRow["FinalFlag"] = imgData.Final;
			godsDs.Tables["DiagnosticImgesTB"].Rows.Add(newRow);


			godsImageTBAdapt.Update(godsDs,"DiagnosticImgesTB");

		}
		/// <summary>
		/// update a row in image table
		/// </summary>
		public void updateImgTB(ImageData imgData)
		{
			DataView dv = godsDs.Tables["DiagnosticImgesTB"].DefaultView;
			dv.Sort="ImageId";
			DataRowView[] data = dv.FindRows(imgData.ImageId);
			if(data.Length==1)
			{
				DataRow newRow  = data[0].Row;
				newRow["ImageID"] = imgData.ImageId;
				newRow["MRN"] = imgData.Mrn;
				newRow["MarkSetID"] = imgData.MarkSetID;
				newRow["Category"] = imgData.Category;
				newRow["AnnotImgPath"] = imgData.AnnotImgPath;
				newRow["OrigImgPath"] = imgData.OrigImgPath;
				newRow["OrigImgRectX"] = imgData.OrigImgRectX;
				newRow["OrigImgRectY"] = imgData.OrigImgRectY;
				newRow["OrigImgRectWidth"] = imgData.OrigImgRectWidth;
				newRow["OrigImgRectHeight"] = imgData.OrigImgRectHeight;
				newRow["Summary"] = imgData.Summary;
				newRow["Reason"] = imgData.Reason;
				newRow["LibraryFlag"] = imgData.LibFlag;
				newRow["AppDate"] = imgData.AppDate;
				newRow["UpdateDate"] = imgData.UpdateDate;
				newRow["FinalFlag"] = imgData.Final;
				
				godsImageTBAdapt.Update(godsDs,"DiagnosticImgesTB");
				
			}
		}
	
		/// <summary>
		/// get all marks for an image
		/// </summary>	
		public ImageMarkData[] getImageMarks(int imgId)
		{
			DataView dv = new DataView(godsDs.Tables["ImageMarkTB"], "ImageID = "+imgId, null, DataViewRowState.CurrentRows);
			if(dv.Count ==0)
			{
				return null;
			}
			ImageMarkData[] imgMarkDataArr = new ImageMarkData[dv.Count];
			
			for(int i=0; i<dv.Count; i++)
			{
				//int m = (int)dv[i]["ImageID"];
				//int x = (int)dv[i]["EstimateWidth"];
				//string v = (string)dv[i]["Comment"];
				
				imgMarkDataArr[i] = 
					new ImageMarkData(
					(int)dv[i]["ImageID"],
					(int)dv[i]["MarkID"],
					(int)dv[i]["Position_X"],
					(int)dv[i]["Position_Y"],
					(double)dv[i]["EstimateWidth"],
					(double)dv[i]["EstimateHeight"],
					dv[i]["Comment"]==DBNull.Value?"":(string)dv[i]["Comment"],
					dv[i]["ValueIndex"]==DBNull.Value?-1:(int)dv[i]["ValueIndex"],
					dv[i]["Ratio"]==DBNull.Value?1:(double)dv[i]["Ratio"]
					);
			}
			return imgMarkDataArr;
		}

		public void insertMark(ImageMarkData imgMarkData)
		{		
			DataRow newRow  = godsDs.Tables["ImageMarkTB"].NewRow();
			newRow["ImageID"] = imgMarkData.ImageId;
			newRow["MarkID"] = imgMarkData.MarkId; 
			newRow["Position_X"] = imgMarkData.Position_X;
			newRow["Position_Y"] = imgMarkData.Position_Y;	
			newRow["EstimateWidth"] = imgMarkData.EstimateWidth;
			newRow["EstimateHeight"] = imgMarkData.EstimateHeight;	
			newRow["Comment"] = imgMarkData.Comment;
			newRow["ValueIndex"] = imgMarkData.ValueIndex;
			newRow["Ratio"] = imgMarkData.Ratio;
			godsDs.Tables["ImageMarkTB"].Rows.Add(newRow);			
			this.godsImageMarkTBAdapt.Update(godsDs,"ImageMarkTB");			
		}
		/// <summary>
		/// delete all marks for an image
		/// </summary>	
		public void deleteMarks(int imageID)
		{
			DataView markViewer = new DataView(godsDs.Tables["ImageMarkTB"], "ImageID = "+imageID, null, DataViewRowState.CurrentRows);
			
			//!!!! Be Careful, don't use markViewer.Count as the criteria since it changes
			//row get added or deleted Thus following will give wrong result.
			//for(int i=0; i<markViewer.Count; i++)
			
			int count = markViewer.Count;
			for(int i=0; i<count; i++)
			{
				markViewer[0].Row.Delete();	//always delete the first one
			}
			
			this.godsImageMarkTBAdapt.Update(godsDs,"ImageMarkTB");	
		}
		/// <summary>
		/// Get all rows with the specified mrn from PatientInfo table
		/// return null if no image
		/// </summary>
		/*
		public PatientInfoData[] getPatientInfoData(int mrn)
		{
			DataView dv = godsDs.Tables["PatientInfoTB"].DefaultView;
			dv.Sort="MRN";
			DataRowView[] data = dv.FindRows(mrn);
			if(data.Length ==0)
			{
				//no such mrn image
				return null;
			}
		
			PatientInfoData[] patientInfoData = new PatientInfoData[data.Length];
			for(int i=0; i<data.Length; i++)
			{
				patientInfoData[i] = 
					new PatientInfoData(
					(int)data[i]["MRN"],
					(DateTime)data[i]["ApptDT"],
					(DateTime)data[i]["DOB"],
					(string)data[i]["ApptProvider"]);
			}
			return patientInfoData;
		}*/

		public void finalizeRecord(int imageID)
		{
		}

		#endregion

		#region IGodsDBMarkSetWrapper
		/// <summary>
		/// Get all categories name as a string array
		/// return null if no category
		/// </summary>
		public string[] getAllCategory()
		{
			DataView dv = godsDs.Tables["MarkSetTB"].DefaultView;
			dv.Sort="Category";
			

			if(dv.Count ==0)
			{
				//no such category info
				return null;
			}
		
			ArrayList catData = new ArrayList();
			for(int i=0; i<dv.Count; i++)
			{
				if(i==0)
				{
					catData.Add((string)dv[i]["Category"]);
				}
				else
				{
					if((string)dv[i]["Category"] != (string)dv[i-1]["Category"])
					{
						catData.Add((string)dv[i]["Category"]);
					}
				}
			}
			return (string [])catData.ToArray(Type.GetType("System.String"));
		}

		/// <summary>
		/// Get all mark sets in a category
		/// </summary>
		public MarkSetData[] getMarkSets(string category)
		{
			DataView dv=godsDs.Tables["MarkSetTB"].DefaultView;
			dv.Sort="Category";
			DataRowView[] data = dv.FindRows(category);
			if(data.Length ==0)
			{
				//no such MarkSet record
				return null;
			}
		
			MarkSetData[] msData = new MarkSetData[data.Length];
			for(int i=0; i<data.Length; i++)
			{
				msData[i] = 
					new MarkSetData(
					(int)data[i]["MarkSetID"],
					(string)data[i]["MarkSetName"],
					(string)data[i]["Category"],
					(string)data[i]["SampleImagePath"],
					(string)data[i]["Status"]);
			}
			return msData;
		}
		/// <summary>
		/// get all GroupName as string array through MarkTB
		/// </summary>
		/// <param name="markSetID"></param>
		/// <returns></returns>
		public string[] getAllMarkSetGroup(int markSetID)
		{
			DataView dv = new DataView(godsDs.Tables["MarkTB"]);
			dv.RowFilter = "MarkSetID = " + markSetID;
			dv.Sort = "MarkSetID, GroupName";
			
			if(dv.Count ==0)
			{
				//no such category info
				return null;
			}
		
			ArrayList groupData = new ArrayList();
			for(int i=0; i<dv.Count; i++)
			{
				if(i==0)
				{
					groupData.Add((string)dv[i]["GroupName"]);
				}
				else
				{
					if((string)dv[i]["GroupName"] != (string)dv[i-1]["GroupName"])
					{
						groupData.Add((string)dv[i]["GroupName"]);
					}
				}
			}
			return (string[])groupData.ToArray(Type.GetType("System.String"));
		}
	
		
		
		/// <summary>
		/// get all the marks in a markset with the same GroupName name
		/// </summary>
		/// <param name="markSetID"></param>
		/// <param name="groupName"></param>
		/// <returns></returns>
		public MarkData[] getGroupMarks(int markSetID, string groupName)
		{
			DataView dv = new DataView(godsDs.Tables["MarkTB"]);
			dv.RowFilter = "MarkSetID = " + markSetID + " AND GroupName = " + "'" + groupName +"'";
			if(dv.Count == 0)
			{
				return null;
			}

			MarkData[] markData = new MarkData[dv.Count];
			for(int i=0; i<dv.Count; i++)
			{
				markData[i] = buildMarkData(dv[i]);
			}
			return markData;

		}

		/// <summary>
		/// Get all marks in a mark set
		/// </summary>
		public MarkData[] getMarks(int markSetID)
		{
			DataView dv=godsDs.Tables["MarkTB"].DefaultView;
			dv.Sort="MarkSetID";
			DataRowView[] data = dv.FindRows(markSetID);
			if(data.Length ==0)
			{
				return null;
			}
		
			MarkData[] markData = new MarkData[data.Length];
			for(int i=0; i<data.Length; i++)
			{
				markData[i] = buildMarkData(data[i]);
						
			}
			return markData;
		}



		/// <summary>
		/// Insert a mark
		/// </summary>
		public void insertMark(MarkData newMark)
		{
			DataRow newRow  = godsDs.Tables["MarkTB"].NewRow();
			newRow["MarkID"] = newMark.MarkID;
			newRow["MarkName"] = newMark.MarkName; 
			newRow["MarkSetID"] = newMark.MarkSetID;
			newRow["GroupName"] = newMark.Group;
			newRow["Description"] = newMark.Description;
			newRow["ImageWidth"] = newMark.ImageWidth;
			newRow["ImageHeight"] = newMark.ImageHeight;
			newRow["ImagePath"] = newMark.ImagePath;
			newRow["IsSingleton"] = newMark.IsSingleton;
			
			godsDs.Tables["MarkTB"].Rows.Add(newRow);			
			this.godsMarkTBAdapt.Update(godsDs,"MarkTB");

			//then add valueList to MarkValueListTB table
			addMarkValueList(newMark.MarkID, newMark.ValueList);
		}

		/// <summary>
		/// Update a mark
		/// </summary>
		public void updateMark(MarkData newMark)
		{
			DataView dv = godsDs.Tables["MarkTB"].DefaultView;
			dv.Sort="MarkID";
			DataRowView[] data = dv.FindRows(newMark.MarkID);
			//there sould be only one row
			if(data.Length==1)
			{
				DataRow newRow  = data[0].Row;
				newRow["MarkID"] = newMark.MarkID;
				newRow["MarkName"] = newMark.MarkName;
				newRow["MarkSetID"] = newMark.MarkSetID;
				newRow["GroupName"] = newMark.Group;
				newRow["Description"] = newMark.Description;
				newRow["ImageWidth"] = newMark.ImageWidth;
				newRow["ImageHeight"] = newMark.ImageHeight;
				newRow["ImagePath"] = newMark.ImagePath;
				newRow["IsSingleton"] = newMark.IsSingleton;
	
				godsMarkTBAdapt.Update(godsDs,"MarkTB");

				//first delete all row for given MarkID
				//then add all rows reflecting the valuelist for given MarkID
				deleteMarkValueList(newMark.MarkID);
				addMarkValueList(newMark.MarkID, newMark.ValueList);
			}
			else
			{
				throw new Exception("updateMark: MarkID isn't unique");
			}
		}

		/// <summary>
		/// Delete a mark
		/// </summary>
		public void deleteMark(int markID)
		{
			DataView markViewer = new DataView(godsDs.Tables["MarkTB"], "MarkID = "+markID, null, DataViewRowState.CurrentRows);
			
			//!!!! Be Careful, don't use markViewer.Count as the criteria since it changes
			//row get added or deleted Thus following will give wrong result.
			//for(int i=0; i<markViewer.Count; i++)
			
			int count = markViewer.Count;
			for(int i=0; i<count; i++)
			{
				deleteMarkValueList((int)markViewer[0]["MarkID"]);
				markViewer[0].Row.Delete();	//always delete the first one
			}
			
			this.godsMarkTBAdapt.Update(godsDs,"MarkTB");	
		}
			
		private MarkData buildMarkData(System.Data.DataRowView dv)
		{
			return
				new MarkData(
				(int)dv["MarkID"],
				(string)dv["MarkName"],
				(int)dv["MarkSetID"],
				(string)dv["GroupName"],
				(string)dv["Description"],
				(int)dv["ImageWidth"],
				(int)dv["ImageHeight"],
				dv["ImagePath"]==DBNull.Value?"":(string)dv["ImagePath"],
				(bool)dv["IsSingleton"],
				getValueList((int)dv["MarkID"])
				);
		}
		/// <summary>
		/// method that get a value list from MarkValueListTB with given MarkID
		/// </summary>
		/// <param name="markId"></param>
		/// <returns></returns>
		private ArrayList getValueList(int markId)
		{
			ArrayList vals = new ArrayList();

			DataView dv = new DataView(godsDs.Tables["MarkValueListTB"], "MarkID = "+markId, null, DataViewRowState.CurrentRows);
				
			for(int i=0; i<dv.Count; i++)
			{
				vals.Add((string)dv[i]["ListValue"]); 
			}
				
			return vals;
		}	
		/// <summary>
		/// add value list to MarkValueListTB table
		/// </summary>
		/// <param name="markId"></param>
		/// <param name="valueList"></param>
		private void addMarkValueList(int markID, ArrayList valueList)
		{
			if (valueList != null) 
			{
				for (int i = 0; i < valueList.Count; i++)
				{
					DataRow newRow  = godsDs.Tables["MarkValueListTB"].NewRow();
					newRow["MarkID"] = markID;
					newRow["ListValue"] = (string)valueList[i];
 
					godsDs.Tables["MarkValueListTB"].Rows.Add(newRow);
				}
				this.godsMarkValueListTBAdapt.Update(godsDs, "MarkValueListTB");
			}
		}

		/// <summary>
		/// delete all marks for an image
		/// </summary>	
		private void deleteMarkValueList(int markID)
		{
			DataView valueListViewer = new DataView(godsDs.Tables["MarkValueListTB"], "MarkID = "+markID, null, DataViewRowState.CurrentRows);
			
			//!!!! Be Careful, don't use markViewer.Count as the criteria since it changes
			//row get added or deleted Thus following will give wrong result.
			//for(int i=0; i<markViewer.Count; i++)
			
			int count = valueListViewer.Count;
			for(int i=0; i<count; i++)
			{
				valueListViewer[0].Row.Delete();	//always delete the first one
			}
			
			this.godsMarkValueListTBAdapt.Update(godsDs,"MarkValueListTB");	
		}


		/// <summary>
		/// Get the maximum mark id in the Mark table
		/// </summary>
		public int getMaxMarkID()
		{
			DataView dv = godsDs.Tables["MarkTB"].DefaultView;
			dv.Sort="MarkID";
			//in case of not Img
			if(dv.Count == 0)
			{
				return 0;
			}

			int maxId = (int)dv[dv.Count-1]["MarkID"];
			return maxId;
		}

		/// <summary>
		/// Insert a mark set
		/// </summary>
		public void insertMarkSet(MarkSetData newMarkSet)
		{
			DataRow newRow  = godsDs.Tables["MarkSetTB"].NewRow();
			newRow["MarkSetID"] = newMarkSet.MarkSetID;
			newRow["MarkSetName"] = newMarkSet.MarkSetName;
			newRow["Category"] = newMarkSet.Category;
			newRow["SampleImagePath"] = newMarkSet.SampleImagePath;
			newRow["Status"] = newMarkSet.Status;
			
			godsDs.Tables["MarkSetTB"].Rows.Add(newRow);			
			this.godsMarkSetTBAdapt.Update(godsDs,"MarkSetTB");
		}

		/// <summary>
		/// Delete a mark set
		/// </summary>
		public void deleteMarkSet(int markSetID)
		{
			DataView markViewer = new DataView(godsDs.Tables["MarkTB"], "MarkSetID = "+markSetID, null, DataViewRowState.CurrentRows);
			
			int count = markViewer.Count;
				
			//Toconfirm: use 0 instead i
			for(int i=0; i<count; i++)
			{
				deleteMark((int)markViewer[0]["MarkID"]);	//always delete the first one
			}

			DataView markSetViewer = new DataView(godsDs.Tables["MarkSetTB"], "MarkSetID = "+markSetID, null, DataViewRowState.CurrentRows);
			
			count = markSetViewer.Count;
				
			for(int i=0; i<count; i++)
			{
				markSetViewer[0].Row.Delete();	//always delete the first one
			}
			
			this.godsMarkSetTBAdapt.Update(godsDs,"MarkSetTB");	
		}
		/// <summary>
		/// Update a mark set
		/// </summary>
		public void updateMarkSet(MarkSetData newMarkSet)
		{
			DataView dv = godsDs.Tables["MarkSetTB"].DefaultView;
			dv.Sort="MarkSetID";
			DataRowView[] data = dv.FindRows(newMarkSet.MarkSetID);
			//there sould be only one row
			if(data.Length==1)
			{
				DataRow newRow  = data[0].Row;
				newRow["MarkSetID"] = newMarkSet.MarkSetID;
				newRow["MarkSetName"] = newMarkSet.MarkSetName;
				newRow["Category"] = newMarkSet.Category;
				newRow["SampleImagePath"] = newMarkSet.SampleImagePath;
				newRow["Status"] = newMarkSet.Status;
				
				this.godsMarkSetTBAdapt.Update(godsDs,"MarkSetTB");
			}
		}
		/// <summary>
		/// Get the maximum mark set id in the MarkSet table
		/// </summary>
		public int getMaxMarkSetID()
		{
			DataView dv = godsDs.Tables["MarkSetTB"].DefaultView;
			dv.Sort="MarkSetID";
			//in case of not Img
			if(dv.Count == 0)
			{
				return 0;
			}

			int maxId = (int)dv[dv.Count-1]["MarkSetID"];
			return maxId;
		}

		#endregion

		//		static void Main(string[] args) 
		//		{
		//			GodsAccessDBWrapper.test();
		//		}

		/// <summary>
		/// 
		/// </summary>
//		public static void test()
//		{
//			string testResult = "=============GodsAccessDBWrapper Unit Test Result: ===========\n";
//			bool allPass = true;
//			try
//			{
//				GodsAccessDBWrapper dbHandler = new GodsAccessDBWrapper("..\\GODS2.mdb");
//			
//				/// <summary>
//				/// test insert a row of image data to image table
//				/// </summary>
//				testResult += "insertion to DiagnosticImageTB and retrieve it\n";
//				int maxImgID = dbHandler.getMaxImgID() +1;
//				int mrn = maxImgID;
//				int markSetID = 1;
//				string catagory = "Breast";
//			
//				ImageData imgData = new ImageData(maxImgID,mrn,markSetID,catagory,"annotImgPath",
//					"origImgPath",0,0,100,200,"summary","reason",false,
//					new DateTime(2005,1,1),new DateTime(2005,1,1));
//				dbHandler.insertImgTB(imgData);
//
//				ImageData[] imgDataArr= dbHandler.getImgData(mrn); 
//				if(imgDataArr.Length != 1 || !imgDataArr[0].Equals(imgData))
//				{
//					testResult += "----Inserted and retrieved not match\n";
//					allPass = false;
//				}
//				else
//				{
//					testResult += "----pass\n";
//				}
//
//				//Todo: insert another with same imageID to see whether exception is throwed and
//				//in the DiagnosticImageTB there is no such duplicate
//
//
//				/// <summary>
//				/// test get max Image ID
//				/// </summary>
//				testResult += "Test getMaxImgID\n";
//				if(dbHandler.getMaxImgID() == maxImgID)
//				{
//					testResult += "----pass\n";	
//				}
//				else
//				{
//					testResult += "----fail\n";
//					allPass = false;
//				}
//
//			
//				/// <summary>
//				/// test update a row in image table
//				/// </summary>
//				testResult += "update image table\n";	
//				ImageData upImgData = new ImageData(imgData.ImageId,imgData.Mrn,imgData.MarkSetID+2,imgData.Category, "update annot path",
//					imgData.OrigImgPath,imgData.OrigImgRectX, imgData.OrigImgRectY,
//					imgData.OrigImgRectWidth, imgData.OrigImgRectHeight,
//					"update summary","update reason",true,
//					new DateTime(2005,2,21),new DateTime(2005,2,22));
//				dbHandler.updateImgTB(upImgData);
//			
//				imgDataArr= dbHandler.getImgData(mrn);
//				if(imgDataArr.Length != 1 || !imgDataArr[0].Equals(upImgData))
//				{
//					testResult += "----fail\n";
//					allPass = false;
//				}
//				else
//				{
//					testResult += "----pass\n";
//				}
//			
//				/// <summary>
//				/// test insert a mark for an image
//				/// </summary>	
//				testResult += "Mark table insert and retrieve\n";
//
//				ImageMarkData[] imgMarkDataArr = new ImageMarkData[2];
//				
//				imgMarkDataArr[0] = new ImageMarkData(imgData.ImageId,3,10,20,2,3,"mark id 3","ListValue",1.0);
//				dbHandler.insertMark(imgMarkDataArr[0]);
//				imgMarkDataArr[1] = new ImageMarkData(imgData.ImageId,2,10,20,3,4,"mark id 2","ListValue",2.0);
//				dbHandler.insertMark(imgMarkDataArr[1]);
//		
//				ImageMarkData[] retImgMarkDataArr = dbHandler.getImageMarks(imgData.ImageId);
//				if(retImgMarkDataArr.Length != 2)
//				{
//					testResult += "----fail\n";
//					allPass = false;
//				}
//				else
//				{
//					bool match= true;
//					for	(int i=0; i<retImgMarkDataArr.Length; i++)
//					{
//						if(!retImgMarkDataArr[i].Equals(imgMarkDataArr[i]))
//						{
//							match = false;
//						}
//					}
//					if(match)
//					{
//						testResult += "----pass\n";
//					}
//					else
//					{
//						testResult += "----fail\n";
//						allPass = false;
//					}
//				}
//				/// <summary>
//				/// delete all marks for an image
//				/// </summary>	
//				testResult += "image mark table delete\n";
//				dbHandler.deleteMarks(imgData.ImageId);
//				retImgMarkDataArr = dbHandler.getImageMarks(imgData.ImageId);
//				if(retImgMarkDataArr == null)
//				{
//					testResult += "----pass\n";
//				}
//				else
//				{
//					testResult += "----fail\n";
//					allPass = false;
//				}
//				/// <summary>
//				/// test insert a row of discharge data to discharge table
//				/// </summary>
//					
//				/// <summary>
//				/// test retrieve data from PatientInfo table
//				/// To: do full unit tests for insert, update, search
//				/// </summary>
//				testResult += "retrieve from PatientInfo table\n";
//				
//				PatientInfoData[] patientInfoDataArr= dbHandler.getPatientInfoData(78887); 
//				Console.WriteLine(patientInfoDataArr.Length+" lines of data retrieved.");
//				testResult += "----pass\n";
//				
//
//				testResult += "Test MarkSetTB APIs\n";
//				int maxMarkSet = dbHandler.getMaxMarkSetID();
//				catagory += maxMarkSet;
//				MarkSetData msData1 = new MarkSetData(maxMarkSet+1,"Breast sketch mark set",catagory,"samPath","Valid");
//				MarkSetData msData2 = new MarkSetData(maxMarkSet+2,"Breast mamogram mark set",catagory,"samPath","InValid");
//				MarkSetData msData1Update = new MarkSetData(maxMarkSet+1,"Breast sketch mark set",catagory,"sample MarkSet image template","Valid");
//				dbHandler.insertMarkSet(msData1);
//				dbHandler.insertMarkSet(msData2);
//				dbHandler.updateMarkSet(msData1Update);
//				MarkSetData[] msArr = dbHandler.getMarkSets(msData1Update.Category);
//				if(msArr.Length ==2 && msArr[0].Equals(msData1Update)
//					&&msArr[1].Equals(msData2))
//				{
//					
//					testResult += "----pass\n";
//				}
//				else
//				{
//					testResult += "----fail\n";
//					allPass = false;
//				}
//				
//				testResult += "Test MarkTB APIs\n";
//				string group1 = "breast Node";
//				string group2 = "nipple Node";
//				int maxMark = dbHandler.getMaxMarkID();
//				ArrayList valueList = new ArrayList();
//				valueList.Add("value1");
//				valueList.Add("value2");
//				valueList.Add("value3");
//				MarkData markData1 = new MarkData(maxMark+1,"Node1",maxMarkSet+1,group1,"desc",10,10,"markImagePath",false,(ArrayList)valueList.Clone());
//				MarkData markData2 = new MarkData(maxMark+2,"Node2",maxMarkSet+1,group2,"desc",10,10,"markImagePath",false,(ArrayList)valueList.Clone());
//					
//				ArrayList valueList2 = new ArrayList();
//				valueList2.Add("value4");
//				valueList2.Add("value5");
//				MarkData markData1Update = new MarkData(maxMark+1,"Node1_1",maxMarkSet+1,group1,"desc",20,20,"markImagePath",false,(ArrayList)valueList2.Clone());
//				dbHandler.insertMark(markData1);
//				dbHandler.insertMark(markData2);
//				dbHandler.updateMark(markData1Update);
//				MarkData[] msArr2 = dbHandler.getMarks(markData1Update.MarkSetID);
//				if(msArr2.Length ==2 && msArr2[0].Equals(markData1Update)
//					&&msArr2[1].Equals(markData2))
//				{
//					testResult += "----pass\n";
//				}
//				else
//				{
//					testResult += "----fail\n";
//					allPass = false;
//				}
//				
//				testResult += "Test getAllMarkSetGroup\n";
//				string[] allGroup = dbHandler.getAllMarkSetGroup(markData1Update.MarkSetID);
//				if(allGroup != null && allGroup.Length ==2 &&
//					allGroup[0]==group1 && allGroup[1]==group2)
//				{
//					testResult += "----pass\n";
//				}
//				else
//				{
//					testResult += "----fail\n";
//					allPass = false;
//				}
//
//				testResult += "Test getGroupMarks\n";
//				MarkData[] msArr3 = dbHandler.getGroupMarks(markData1Update.MarkSetID, group1);
//				if(msArr3.Length ==1 && msArr3[0].Equals(markData1Update))
//				{
//					testResult += "----pass\n";
//				}
//				else
//				{
//					testResult += "----fail\n";
//					allPass = false;
//				}
//
//				testResult += "Test MarkTB delete\n";
//				dbHandler.deleteMark(markData1Update.MarkID);
//				dbHandler.deleteMark(markData2.MarkID);
//				if(dbHandler.getMarks(markData1Update.MarkSetID) ==null)
//				{
//					testResult += "----pass\n";
//				}
//				else
//				{
//					testResult += "----fail\n";	
//					allPass = false;
//				}
//				
//				testResult += "Test MarkSetTB delete\n";
//				dbHandler.deleteMarkSet(msData1Update.MarkSetID);
//				dbHandler.deleteMarkSet(msData2.MarkSetID);
//				if(dbHandler.getMarkSets(msData1Update.Category) ==null)
//				{
//					testResult += "----pass\n";
//				}
//				else
//				{
//					testResult += "----fail\n";
//					allPass = false;
//				}
//				
//
//				testResult += "Test getAllCategory\n";
//				catagory += maxMarkSet;
//				string cat1 = catagory +1;
//				string cat2 = catagory +2;
//				MarkSetData msData3 = new MarkSetData(maxMarkSet+1,"Breast sketch mark set",cat1,"samPath","Valid");
//				MarkSetData msData4 = new MarkSetData(maxMarkSet+2,"Breast mamogram mark set",cat2,"samPath","InValid");
//				
//				dbHandler.insertMarkSet(msData3);
//				dbHandler.insertMarkSet(msData4);
//
//				string[] allCats = dbHandler.getAllCategory();
//				if(allCats != null && allCats.Length == 2 &&
//					allCats[0]== cat1 && allCats[1] ==cat2)
//				{
//
//					testResult += "----pass\n";
//				}
//				else
//				{
//					testResult += "----fail\n";
//					allPass = false;
//				}
//				dbHandler.deleteMarkSet(msData3.MarkSetID);
//				dbHandler.deleteMarkSet(msData4.MarkSetID);
//
//				if(allPass)
//					testResult += "================All unit tests pass ============\n";
//				else
//					testResult += "================Some unit tests fail ============\n";
//				MessageBox.Show(testResult);
//			}
//			catch(Exception e)
//			{
//				testResult += e.ToString();
//				testResult += "================Some unit tests fail ============\n";
//			}
//		}
	}
}
