#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
using System;
using System.Drawing;
using System.Runtime.Serialization;
using System.Xml.Serialization;

namespace dataMagus.Common
{
	#region Delegates
	/// <summary>
	/// Handler when an element has been changed.
	/// </summary>
	public delegate void ElementChangedHandler(object sender, ElementEventArgs e);
	#endregion

	#region Enumerators
	/// <summary>
	/// Change action on the element.
	/// </summary>
	public enum ElementChangedAction
	{
		/// <summary>
		/// Undefined
		/// </summary>
		Undefined,
		
		/// <summary>
		/// ChangedProperty
		/// </summary>
		ChangedProperty,
		
		/// <summary>
		/// AddedElement
		/// </summary>
		AddedElement,
		
		/// <summary>
		/// RemovedElement
		/// </summary>
		RemovedElement
	}
	#endregion
	
	/// <summary>
	/// Event argument data for ElementChangedHandler.
	/// </summary>
	public class ElementEventArgs : EventArgs
	{
		#region Members
		/// <summary>
		/// The Element on which the action happend. 
		/// </summary>
		private object _element = null;
		
		/// <summary>
		/// The Element which resulted out of the action.
		/// </summary>
		private IElement _actionElement = null;
		
		/// <summary>
		/// The action which happend on the element.
		/// </summary>
		private ElementChangedAction _action = ElementChangedAction.Undefined;
		#endregion
		
        #region Constructors / Destructors
        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="element">The Element on which the action happend.</param>
        /// <param name="action">The action which happend on the element.</param>
		public ElementEventArgs(object element, ElementChangedAction action)
			: this(element, action, null)
		{
		}

		/// <summary>
        /// Constructor.
		/// </summary>
		/// <param name="element">The Element on which the action happend.</param>
		/// <param name="action">The action which happend on the element.</param>
		/// <param name="actionElement">The Element which resulted out of the action.</param>
		public ElementEventArgs(object element, ElementChangedAction action, IElement actionElement)
		{
			this._element = element;
			this._action = action;
			this._actionElement = actionElement;
		}
        #endregion

        #region Properties
		/// <summary>
		/// The Element on which the action happend. 
		/// </summary>
		public object Element 
		{
			get { return this._element; }
		}
		
		/// <summary>
		/// The Element which resulted out of the action.
		/// </summary>
		public IElement ActionElement 
		{
			get { return this._actionElement; }
		}
		
		/// <summary>
		/// The action which happend on the element.
		/// </summary>
		public ElementChangedAction Action 
		{
			get { return this._action; }
		}
        #endregion
	}
	
	/// <summary>
	/// This interface defines an element.
	/// </summary>
	public interface IElement : ICloneable
	{
		#region Properties
		/// <summary>
		/// Id of the element.
		/// </summary>
		string Id	{ get; }
		
		/// <summary>
		/// Name of the element.
		/// </summary>
		string Name { get; set; }
		
		/// <summary>
		/// Location of the element.
		/// </summary>
		Point Location { get; set; }
		
		/// <summary>
		/// Indicates if the element is in InitMode.
		/// </summary>
		/// <remarks>InitMode will suppress all changing events.</remarks>
		bool InitMode { get; }
		
		/// <summary>
		/// Indicates if the element has been cloned.
		/// </summary>
        /// <remarks>Beware: events on clones will be suppressed.</remarks>
		bool IsClone { get; }
		#endregion

		#region Events
		/// <summary>
		/// Event will be fired when the element has changed.
		/// </summary>
		event ElementChangedHandler ElementChanged;
		#endregion
		
		#region Methodes
        /// <summary>
        /// Fires an element changed event.
        /// </summary>
        /// <param name="sender">Sender object.</param>
        /// <param name="args">ElementEventArgs.</param>
		void FireElementChangedEvent(object sender, ElementEventArgs args);
		
        /// <summary>
        /// Gets the parent object.
        /// </summary>
        /// <returns>Parent object or null if has no parent.</returns>
		IElement GetParent();
		
		/// <summary>
		/// Begin initialization mode.
		/// </summary>
		/// <remarks>Prevents event handling.</remarks>
		void BeginInit();
        
		/// <summary>
		/// End initialization mode.
		/// </summary>
		/// <remarks>Event handling will continue.</remarks>
		/// <param name="forceEvent">Indicates if an Undefined event has to be fired to inform other listeners.</param>
		void EndInit(bool forceEvent);
		#endregion
	}
}
