/******************************************************************************
 * MarkSetHandler.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.Collections;
using System.Drawing;
using System.Windows.Forms;
using GODS.MarkData;
using GODS.MarkGUI;
using GODS.DBHandler;

namespace GODS.MarkConfig
{
	/// <summary>
	/// Summary description for MarksetHandler.
	/// </summary>
	public class MarkSetHandler
	{
		private ArrayList categories;
        public static string MARK_IMG_DIR = "marks\\"; //perhaps be initialized in main config method?
		public MarkSetHandler()
		{
			this.loadAllCategories();
		}

		public ArrayList loadMarkPanel(Panel markPanel, MarkSet markSet, EventHandler handler)
		{
			ArrayList markViews = new ArrayList();
			if (markSet != null)
			{
				MarkGroupView mgView;
				int x = 5;
				int y = 5;
				markPanel.Controls.Clear();
				foreach (MarkGroup group in markSet.MarkGroups)
				{
					mgView = new MarkGroupView(group, handler);
					// don't draw the group if there isn't any mark view in the group
					if (mgView.MarkViews.Count == 0)
						continue;
					markViews.AddRange(mgView.MarkViews);
					mgView.Location = new Point(x, y);
					y += mgView.Height + 10;
					markPanel.Controls.Add(mgView);
				}
			}
			return markViews;
		}

		public ArrayList Categories
		{
			get 
			{
				return this.categories;
			}
		}

		protected MarkCategory addCategory(string cName)
		{
			MarkCategory cat = this.getCategory(cName);
			if (cat == null)
			{
				cat = new MarkCategory(cName);
				this.categories.Add(cat);
				return cat;
			}
			else
			{
				throw new System.Exception("Dupplicate category: Category with the same name already exists.");
			}
		}

		protected void removeCategory(MarkCategory cat)
		{
			this.categories.Remove(cat);
		}

		public MarkCategory getCategory(string cName)
		{
			foreach (MarkCategory cat in this.categories)
			{
				if (cName.Equals(cat.CategoryName))
				{
					return cat;
				}
			}
			return null;
		}
		
		//problem with this one
		public void saveMarkSetInfo(MarkSet ms)
		{
			MarkSetData markSetData = new MarkSetData(
				ms.MarkSetID,
				ms.MarksetName,
				ms.Category.CategoryName,
				"",
				"");
			ArrayList markList = new ArrayList();

			GODS.DBHandler.MarkData mData;
			int width, height;
			foreach (Mark mark in ms.AllMarks)
			{
				width = (mark.HasImage)? mark.Image.Width : -1;
				height = (mark.HasImage)? mark.Image.Height : -1;
				mData = new GODS.DBHandler.MarkData(
					mark.MarkID,
					mark.MarkName, 
					ms.MarkSetID,
					mark.Markgroup.GroupName,
					mark.Description,
					width,
					height,
					mark.ImagePath,
					false,
					mark.PresetValues);
				markList.Add(mData);
			}
			GODS.GODSMain.dbManager.saveMarkSet(markSetData,markList);
			this.reloadMarkSet(markSetData,ms);
		}

		public void loadAllCategories()
		{
			this.categories = new ArrayList();
			string[] cNames = GODS.GODSMain.dbManager.getAllCategory();

			if (cNames == null || cNames.Length == 0)
				return;


			foreach (string cName in cNames)
			{
				this.loadCategory(cName);
			}
		}

		private void loadCategory(string cName)
		{
			MarkCategory cat;
			MarkSetData[] catMarkSetData;


			cat = new MarkCategory(cName);
			this.categories.Add(cat);
			catMarkSetData = GODS.GODSMain.dbManager.getMarkSets(cName);
			foreach (MarkSetData msData in catMarkSetData)
			{
				cat.addMarkSet(this.loadMarkSet(msData,cat));
			}
		}


		private MarkSet loadMarkSet(MarkSetData msData, MarkCategory cat)
		{
			GODS.DBHandler.MarkData[] msMarkData;
			string[] msGroups;
			MarkSet ms;
			Hashtable groups;
			string groupName;
			MarkGroup mg;
			Mark mark;

			ms = new MarkSet(cat, msData.MarkSetID, msData.MarkSetName);
			msGroups = GODS.GODSMain.dbManager.getAllMarkSetGroup(msData.MarkSetID);
			msMarkData = GODS.GODSMain.dbManager.getMarks(msData.MarkSetID);
			groups = new Hashtable();
			foreach (GODS.DBHandler.MarkData mData in msMarkData)
			{
				groupName = mData.Group;
				if ((mg = (MarkGroup) groups[groupName]) == null)
				{
					mg = new MarkGroup(ms, groupName);
					ms.addMarkGroup(mg);
					groups.Add(groupName, mg);
				}
				//mark = new Mark(mData.MarkID, ms, mg, mData.MarkName, mData.ImagePath, mData.Description);
				mark = new Mark(mData.MarkID, ms, mg, mData.MarkName, mData.ImagePath, mData.Description,mData.ValueList);
				mg.addMark(mark);
			}
			return ms;
		}

		public void reloadMarkSet(MarkSetData msData,MarkSet ms)
		{
			MarkSet fromDB = this.loadMarkSet(msData,ms.Category);
			ms.setMarkSetID(fromDB.MarkSetID);
		}
	}
}