/******************************************************************************
 * GODSDBManager.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.IO;
using System.Collections;
using System.Windows.Forms;

namespace GODS.DBHandler
{
	/// <summary>
	/// Summary description for GODSDBManager.
	/// </summary>
	public class GODSDBManager
	{
		private IGodsDBWrapper dbWrapper;
		private IGodsDBMarkSetWrapper marksetWrapper;
		private  int maxImgID;
		private  int maxMarkID;
		private int maxMarksetID;

		public GODSDBManager()
		{
			dbWrapper = new GODS.DBHandler.GodsAccessDBWrapper();
			marksetWrapper = (IGodsDBMarkSetWrapper) dbWrapper;
			this.maxImgID = this.dbWrapper.getMaxImgID();
			this.maxMarkID = this.marksetWrapper.getMaxMarkID();
			this.maxMarksetID = this.marksetWrapper.getMaxMarkSetID();
		}

		public ArrayList getAllMrn()
		{
			string[] mrns = this.dbWrapper.getAllMrn();
			if(mrns == null)
			{
				return new ArrayList();
			}
			else
			{
				return new ArrayList(mrns);
			}
		}

		public ImageData[] getImgData(string mrn)
		{
			return this.dbWrapper.getImgData(mrn);
		}

		public int NextImageID
		{
			get 
			{
				//use prefix increment instead!
				//otherwise it won't get correcty incremented.
				return ++this.maxImgID;
			}
		}

		public int NextMarkID
		{
			get 
			{
				//use prefix increment instead!
				//otherwise it won't get correcty incremented.
				return ++this.maxMarkID;
			}
		}

		public int NextMarksetID
		{
			get
			{
				//use prefix increment instead!
				//otherwise it won't get correcty incremented.
				return ++this.maxMarksetID;
			}
		}

		public void saveAnnotatedImage(ImageData imageData, ArrayList imgMarkDataList)
		{
			int imageID = imageData.ImageId;
			if (imageID == -1) 
			{
				imageID = this.NextImageID;
				imageData.ImageId = imageID;
				dbWrapper.insertImgTB(imageData);
			}
			else
			{
				dbWrapper.updateImgTB(imageData);
				//just delete all marks associate to old one
				dbWrapper.deleteMarks(imageID);
			}
			//in both case add all the new marks
			foreach (ImageMarkData imgMarkData in imgMarkDataList) 
			{
				imgMarkData.ImageId = imageID;
				this.dbWrapper.insertMark(imgMarkData);
			}
		}

		public ImageData getImgDataByDate(string mrn, DateTime appDate)
		{
			if(mrn == null)
			{
				return null;
			}
			return this.dbWrapper.getImgDataByDate(mrn, appDate);
		}

		public ImageMarkData[] getImageMarks(int imgId)
		{
			return this.dbWrapper.getImageMarks(imgId);
		}

		public void saveMarkSet(MarkSetData markSetData, ArrayList markList)
		{
			if(markSetData.MarkSetID == -1)
			{
				markSetData.MarkSetID = this.NextMarksetID;
			}
			
			//handle marks that associated with the MarkSet table
			foreach (GODS.DBHandler.MarkData mData in markList)
			{
				if(mData.MarkSetID == -1)
					mData.MarkSetID = markSetData.MarkSetID;
				if(mData.MarkID == -1)
				{
					mData.MarkID = this.NextMarkID;
					
				}
				
				
			}

			//delete all marks that associate to the Markset
			//then reinsert all from the marklist
			marksetWrapper.deleteMarkSet(markSetData.MarkSetID);
			marksetWrapper.insertMarkSet(markSetData);
			foreach (GODS.DBHandler.MarkData mData in markList)
			{
			   //assign new location for mark image if needed
				mData.ImagePath =  createNewMarkImageLocation(mData.ImagePath,mData.MarkID);
				marksetWrapper.insertMark(mData);
			}


		}



		public string[] getAllCategory()
		{
			return this.marksetWrapper.getAllCategory();
		}

		public MarkSetData[] getMarkSets(string category)
		{
			return this.marksetWrapper.getMarkSets(category);
		}

		public string[] getAllMarkSetGroup(int markSetID)
		{
			return this.marksetWrapper.getAllMarkSetGroup(markSetID);
		}

		public MarkData[] getMarks(int markSetID)
		{
			return this.marksetWrapper.getMarks(markSetID);
		}

		//method will return appropiate location for the mark image
		//where the image will be stored permanently.
		//the image name  will be append by markid to make it unique
		private string createNewMarkImageLocation(string userInputlocation, int markid)
		{
		
			//check if the image path is in the same path format as in database 
			//thus if it's in the form of .\marks\someimage.gif then there wasn't any change or it isn't a new image
			if(userInputlocation.Length > 0 && userInputlocation[0] != '.')
			{
				string oldpath = @userInputlocation;
				string fileName =  Path.GetFileNameWithoutExtension(oldpath);
				string newFileName = fileName + markid;
				string extention = Path.GetExtension(oldpath);
				newFileName = newFileName+extention;
				string newlocation = ".\\"+ GODS.MarkConfig.MarkSetHandler.MARK_IMG_DIR+newFileName;
				string newpath = GODSMain.ExecDir+GODS.MarkConfig.MarkSetHandler.MARK_IMG_DIR+newFileName;
				try 
				{
					// Ensure that the target does not exist.
					File.Delete(newpath);
					// Copy the file.
					File.Copy(oldpath, newpath);
				
				} 
				catch
				{
					return userInputlocation;
				}

				return newlocation;
			}
			return userInputlocation;
		}
	}
}
