/*
 *  TLV - Trace Log Visualizer
 *
 *  Copyright (C) 2008-2010 by Nagoya Univ., JAPAN
 *
 *  上記著作権者は，以下の(1)〜(4)の条件を満たす場合に限り，本ソフトウェ
 *  ア（本ソフトウェアを改変したものを含む．以下同じ）を使用・複製・改
 *  変・再配布（以下，利用と呼ぶ）することを無償で許諾する．
 *  (1) 本ソフトウェアをソースコードの形で利用する場合には，上記の著作
 *      権表示，この利用条件および下記の無保証規定が，そのままの形でソー
 *      スコード中に含まれていること．
 *  (2) 本ソフトウェアを，ライブラリ形式など，他のソフトウェア開発に使
 *      用できる形で再配布する場合には，再配布に伴うドキュメント（利用
 *      者マニュアルなど）に，上記の著作権表示，この利用条件および下記
 *      の無保証規定を掲載すること．
 *  (3) 本ソフトウェアを，機器に組み込むなど，他のソフトウェア開発に使
 *      用できない形で再配布する場合には，次のいずれかの条件を満たすこ
 *      と．
 *    (a) 再配布に伴うドキュメント（利用者マニュアルなど）に，上記の著
 *        作権表示，この利用条件および下記の無保証規定を掲載すること．
 *    (b) 再配布の形態を，別に定める方法によって，TOPPERSプロジェクトに
 *        報告すること．
 *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
 *      害からも，上記著作権者およびTOPPERSプロジェクトを免責すること．
 *      また，本ソフトウェアのユーザまたはエンドユーザからのいかなる理
 *      由に基づく請求からも，上記著作権者およびTOPPERSプロジェクトを
 *      免責すること．
 *
 *  本ソフトウェアは，無保証で提供されているものである．上記著作権者お
 *  よびTOPPERSプロジェクトは，本ソフトウェアに関して，特定の使用目的
 *  に対する適合性も含めて，いかなる保証も行わない．また，本ソフトウェ
 *  アの利用により直接的または間接的に生じたいかなる損害に関しても，そ
 *  の責任を負わない．
 *
 *  @(#) $Id: SubWindow.cs 87 2011-04-05 10:30:40Z nagasima $
 */
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using NU.OJL.MPRTOS.TLV.Base;
using WeifenLuo.WinFormsUI.Docking;
using SimBase;

namespace NU.OJL.MPRTOS.TLV.Third
{
	/// <summary>
	/// WindowManagerで使用されるサブウィンドウの情報を管理するクラス
	/// </summary>
	public class SubWindow : ISubWindow, IDockContent, IViewForm
	{
		private Form m_Form;
		private DockContentHandler m_DockHandler;
		private IWindowSank m_WindowSank;
		private NU.OJL.MPRTOS.TLV.Base.DockState m_DockState = NU.OJL.MPRTOS.TLV.Base.DockState.Unknown;
		private bool m_Visible = true;
		private bool m_Enabled = true;
		private IUnitSim m_UnitSim;

		/// <summary>
		/// SubWindowのインスタンスを生成
		/// </summary>
		/// <param name="form">サブウィンドウにFillされるForm</param>
		/// <param name="dockState">サブウィンドウのドッキング状態</param>
		public SubWindow(Form form, NU.OJL.MPRTOS.TLV.Base.DockState dockState)
		{
			m_Form = form;
			m_WindowSank = form as IWindowSank;
			DockState = dockState;
			Visible = true;
			m_DockHandler = new DockContentHandler(m_Form, this, new GetPersistStringCallback(GetPersistString));
			// Suggested as a fix by bensty regarding form resize
			m_Form.ParentChanged += new EventHandler(DockContent_ParentChanged);
		}

		protected virtual string GetPersistString()
		{
			return m_Form.Name;
		}

		//Suggested as a fix by bensty regarding form resize
		private void DockContent_ParentChanged(object Sender, EventArgs e)
		{
			if (m_Form.Parent != null)
				m_Form.Font = m_Form.Parent.Font;
		}

		#region ISubWindow メンバ

		/// <summary>
		/// DockStateが変ったときに発生するイベント
		/// </summary>
		public event EventHandler<GeneralChangedEventArgs<NU.OJL.MPRTOS.TLV.Base.DockState>> DockStateChanged = null;
		/// <summary>
		/// Visibleが変ったときに発生するイベント
		/// </summary>
		public event EventHandler<GeneralChangedEventArgs<bool>> VisibleChanged = null;
		/// <summary>
		/// Enabledが変ったときに発生するイベント
		/// </summary>
		public event EventHandler<GeneralChangedEventArgs<bool>> EnabledChanged = null;

		/// <summary>
		/// サブウィンドウのForm
		/// </summary>
		public Form Form { get { return m_Form; } }

		/// <summary>
		/// ドッキング状態
		/// </summary>
		public NU.OJL.MPRTOS.TLV.Base.DockState DockState
		{
			get { return m_DockState; }
			set
			{
				if (m_DockState != value)
				{
					NU.OJL.MPRTOS.TLV.Base.DockState old = m_DockState;

					m_DockState = value;

					if (DockStateChanged != null)
						DockStateChanged(this, new GeneralChangedEventArgs<NU.OJL.MPRTOS.TLV.Base.DockState>(old, m_DockState));
				}
			}
		}

		/// <summary>
		/// サブウィンドウが表示されているかどうかを示す値
		/// </summary>
		public bool Visible
		{
			get { return m_Visible; }
			set
			{
				if (m_Visible != value)
				{
					bool old = m_Visible;

					m_Visible = value;

					if (VisibleChanged != null)
						VisibleChanged(this, new GeneralChangedEventArgs<bool>(old, m_Visible));
				}
			}
		}

		/// <summary>
		/// サブウィンドウの名前。識別子として使われる
		/// </summary>
		public string Name { get { return m_Form.Name; } }

		/// <summary>
		/// サブウィンドウのタイトルバーに表示されるテキスト
		/// </summary>
		public string Text { get { return m_Form.Text; } set { m_Form.Text = value; } }

		/// <summary>
		/// サブウィンドウが有効かどうか
		/// </summary>
		public bool Enabled
		{
			get { return m_Enabled; }
			set
			{
				if (m_Enabled != value)
				{
					bool old = m_Enabled;

					m_Enabled = value;

					if (EnabledChanged != null)
						EnabledChanged(this, new GeneralChangedEventArgs<bool>(old, m_Enabled));

					if (!m_Enabled && Visible)
					{
						Visible = false;
					}
				}
			}
		}

		public object Handler { get { return m_DockHandler; } }

		#endregion

		#region IViewForm メンバ

		public IUnitSim UnitSim
		{
			get { return m_UnitSim; }
			set { m_UnitSim = value; }
		}

		public IControlWrapper this[string key]
		{
			get
			{
				Control[] controls = m_Form.Controls.Find(key, true);

				if ((controls == null) || (controls.Length != 1))
					throw new IndexOutOfRangeException(key + "コントロールが見つかりません。");

				return new ControlWrapper(controls[0]);
			}
		}

		void IViewForm.OnShown(EventArgs e)
		{
			if (m_WindowSank != null)
				m_WindowSank.OnShown(e);
		}

		public void Activate()
		{
			m_DockHandler.Activate();
		}

		#endregion

		#region IDockContent メンバ

		public DockContentHandler DockHandler
		{
			get { return m_DockHandler; }
		}

		void IDockContent.OnActivated(EventArgs e)
		{
			if (m_WindowSank != null)
				m_WindowSank.OnActivated(e);
		}

		void IDockContent.OnDeactivate(EventArgs e)
		{
			if (m_WindowSank != null)
				m_WindowSank.OnDeactivate(e);
		}

		#endregion
	}
}
