#region Copyright and GPL
/*************************************************************************
 * dataMagus - The open source database learning software
 * Copyright (C) 2007 by all authors
 * Authors: Monika Schwitter (monsy@gmx.ch)
 *          Jürg Zgraggen (j.zgraggen@ejaz.net)
 *          HSLU (Hochschule Luzern - Technik+Architektur)
 * 
 *     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 3 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, see <http://www.gnu.org/licenses/>.
 *************************************************************************/
#endregion
#region Using
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using dataMagus.Common;
using dataMagus.Forms.Handlers;
using dataMagus.Common.Logical;
using dataMagus.Common.Physical;
using dataMagus.Common.Physical.Relational;
using dataMagus.Common.Physical.Objectoriented;
#endregion

namespace dataMagus.Forms.Controls
{
	/// <summary>
	/// Control to naviagte within a schema with.
	/// </summary>
	public partial class SchemaNavigationControl : UserControl
	{
		#region Members
		/// <summary>
		/// Current drawn schema.
		/// </summary>
		private ISchema _schema = null;

        /// <summary>
        /// Handler instance for the schema navigation control.
        /// </summary>
		private SchemaNavigationControlHandler _handler = null;
		#endregion
		
		#region Constructors / Destructors
		/// <summary>
		/// Default constructor.
		/// </summary>
		public SchemaNavigationControl()
		{
			InitializeComponent();
			this._handler = new SchemaNavigationControlHandler(this, this.navigationTree);
		}
		#endregion
		
		#region Properties
		/// <summary>
		/// Current drawn schema.
		/// </summary>
		public ISchema Schema 
		{
			get { return this._schema; }
			set 
			{
				if (this._schema != value)
				{
                    if (null != this._schema)
                    {
                        this._schema.SchemaChanged -= new SchemaChangedHandler(this.OnSchemaChanged);
                    }
                    
                    this._schema = value;
                    
                    if (null != this._schema)
                    {
	                    this._schema.SchemaChanged += new SchemaChangedHandler(this.OnSchemaChanged);
						this._handler.SetSchemaHandler();
						this._handler.BuildSchemaTree(this._schema);
                    }
				}
			}
		}
		#endregion
		
		#region Delegates
		/// <summary>
		/// Handler when a group will be selected.
		/// </summary>
		public delegate void SelectGroupHandler(object sender, EventArgs e);
		
		/// <summary>
		/// Handler when an element will be selected.
		/// </summary>
		public delegate void SelectElementHandler(object sender, ElementEventArgs e);
		#endregion
		
		#region Events
		/// <summary>
		/// Event will be fired when a group will be selected.
		/// </summary>
		public event SelectGroupHandler SelectGroup;
		
		/// <summary>
		/// Event will be fired when an element will be selected.
		/// </summary>
		public event SelectElementHandler SelectElement;
		#endregion
		
		#region Methodes
		/// <summary>
		/// Rebuild the navigation tree.
		/// </summary>
		public void Rebuild()
		{
			this._handler.RebuildTree();
		}

		/// <summary>
		/// Event handler.
		/// </summary>
		/// <param name="sender">Sender object.</param>
		/// <param name="e">SchemaEventArgs</param>
        public virtual void OnSchemaChanged(object sender, SchemaEventArgs e)
        {
        	try
        	{
	        	if (SchemaChangedAction.ExchangeSchema == e.Action)
	        	{
	        		// exchange and rebuilded it (handler and tree will be rebuilded automatically)
	        		this.Schema = e.Schema;
	        	}
	        	else if (SchemaChangedAction.RebuildedSchema == e.Action)
	        	{
	        		// rebuild completely when the schema has been rebuilded
					this._handler.SetSchemaHandler();
					this._handler.BuildSchemaTree(e.Schema);
	        	}
	        	else
	        	{
	    			// just redirect the event (ex. when a new entitiy joins)
					this._handler.HandleOnSchemaChanged(e);
	        	}
        	}
			catch (Exception ex)
			{
				MessageForm.ShowDialog(ex);
			}
        }

		/// <summary>
		/// Event handler.
		/// </summary>
		/// <param name="sender">Sender object.</param>
		/// <param name="e">TreeViewEventArgs</param>
		private void NavigationTreeAfterSelect(object sender, TreeViewEventArgs e)
		{
			try
			{
				if (null != e.Node && null != this.SelectElement)
				{
					this._handler.BuildContextMenu(this.contextMenu, e.Node);
					if (null != e.Node.Tag)
					{
						SchemaNavigationControlHandler.NodeInfo info = (SchemaNavigationControlHandler.NodeInfo)e.Node.Tag;
						if (info.IsGroup)
						{
							this.SelectGroup(this, EventArgs.Empty);
						}
						else if (null != info.Element)
						{
							this.SelectElement(this, new ElementEventArgs(info.Element, ElementChangedAction.Undefined));
						}
					}
				}
			}
            catch (Exception ex)
            {
            	MessageForm.ShowDialog(ex);
            }
		}
		
		/// <summary>
		/// Event handler.
		/// </summary>
		/// <param name="sender">Sender object.</param>
		/// <param name="e">TreeNodeMouseClickEventArgs</param>
		void NavigationTreeNodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
		{
			try
			{
				this.navigationTree.SelectedNode = e.Node;
			}
			catch (Exception ex)
			{
				MessageForm.ShowDialog(ex);
			}
		}
		#endregion
	}
}
