//------------------------------------------------------------------------------
// Embedded Software Simulation Base Classes
// Copyright (C) 2010-2011 Cores Co., Ltd. Japan
//------------------------------------------------------------------------------
// $Id: ScenarioForm.cs 88 2011-04-05 11:03:57Z nagasima $
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using System.Reflection;

namespace SimBase
{
	public partial class ScenarioForm : Form
	{
		List<ScenarioGridItem> m_ScenarioList = new List<ScenarioGridItem>();

		public ScenarioForm()
		{
			InitializeComponent();

			scenarioBindingSource.DataSource = m_ScenarioList;
			scenarioBindingSource.ResetBindings(true);
		}

		public void UpdateScenarioList(Assembly assembly, IScenarioHost scenarioHost)
		{
			Type[] types = assembly.GetTypes();
			foreach (Type type in types)
			{
				if (type.IsSubclassOf(typeof(Scenario)))
				{
					ScenarioGridItem item = new ScenarioGridItem(type, scenarioHost, imageList1);
					m_ScenarioList.Add(item);
				}
			}

			scenarioBindingSource.ResetBindings(false);
		}

		private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
		{
			if ((e.ColumnIndex < 0) && (e.RowIndex < 0))
				return;

			if (RunScenarioColumn == dataGridView1.Columns[e.ColumnIndex])
			{
				ScenarioGridItem item = (ScenarioGridItem)dataGridView1.Rows[e.RowIndex].DataBoundItem;
				Scenario scenario = item.GetScenario();
				scenario.ValueChanged += new EventHandler(Scenario_ValueChanged);
				scenario.ErrorAdded += new ErrorAddedEventHandler(Scenario_ErrorAdded);
				if (scenario.IsRunning)
					scenario.Stop();
				else
					scenario.Run();
			}
		}

		void Scenario_ValueChanged(object sender, EventArgs e)
		{
			dataGridView1.Refresh();
		}

		void Scenario_ErrorAdded(Scenario sender, ErrorAddedEventArgs e)
		{
			ScenarioGridItem row = (ScenarioGridItem)dataGridView1.CurrentRow.DataBoundItem;

			row.ErrorList.Add(new ErrorListItem(e));
			errorListItemBindingSource.ResetBindings(false);
		}

		public void DoEvent(object o)
		{
			foreach (ScenarioGridItem row in m_ScenarioList)
			{
				Scenario scenario = row.Instance;
				if ((scenario == null) || (!scenario.IsRunning))
					continue;

				scenario.DoEvent(o);
			}
		}

		private void dataGridView1_RowEnter(object sender, DataGridViewCellEventArgs e)
		{
			ScenarioGridItem row = (ScenarioGridItem)dataGridView1.Rows[e.RowIndex].DataBoundItem;

			errorListItemBindingSource.DataSource = row.ErrorList;
			errorListItemBindingSource.ResetBindings(true);
		}
	}

	public class ScenarioGridItem
	{
		private Type m_ScenarioType;
		private IScenarioHost m_ScenarioHost;
		private Scenario m_Instance;
		private ImageList m_ImageList;
		private string m_Name;
		private List<ErrorListItem> m_ErrorList = new List<ErrorListItem>();

		public ScenarioGridItem(Type type, IScenarioHost scenarioHost, ImageList imageList)
		{
			m_ScenarioType = type;
			m_ScenarioHost = scenarioHost;
			m_ImageList = imageList;
			m_Name = Scenario.GetName(type);
		}

		public string Name
		{
			get { return m_Name; }
		}

		public Scenario Instance
		{
			get { return m_Instance; }
		}

		public bool IsRunning
		{
			get { return (m_Instance == null) ? false : m_Instance.IsRunning; }
		}

		public int Progress
		{
			get { return (m_Instance == null) ? 0 : (100 * (m_Instance.Step + 1) / (m_Instance.TotalSteps + 1)); }
		}

		public Image Result
		{
			get
			{
				ScenarioResult result = (m_Instance == null) ? ScenarioResult.NoRunning : m_Instance.Result;

				switch (result)
				{
					case ScenarioResult.NoRunning:
						return m_ImageList.Images[0];
					case ScenarioResult.Running:
						return m_ImageList.Images[1];
					case ScenarioResult.OK:
						return m_ImageList.Images[2];
					case ScenarioResult.NG:
						return m_ImageList.Images[3];
					case ScenarioResult.UserStop:
						return m_ImageList.Images[4];
					default:
						return m_ImageList.Images[0];
				}
			}
		}

		public DateTime StartTime
		{
			get { return (m_Instance == null) ? DateTime.MinValue : m_Instance.StartTime; }
		}

		public DateTime EndTime
		{
			get { return (m_Instance == null) ? DateTime.MinValue : m_Instance.EndTime; }
		}

		public List<ErrorListItem> ErrorList
		{
			get { return m_ErrorList; }
		}

		public Scenario GetScenario()
		{
			if (m_Instance != null)
				return m_Instance;

			ConstructorInfo info = m_ScenarioType.GetConstructor(new Type[] { typeof(IScenarioHost) });
			if (info == null)
				return null;

			m_Instance = (Scenario)info.Invoke(new object[] { m_ScenarioHost });

			return m_Instance;
		}
	}

	public class ErrorListItem
	{
		DateTime m_OccuerTime;
		string m_Location;
		string m_Text;

		public ErrorListItem(DateTime occuerTime, string location, string text)
		{
			m_OccuerTime = occuerTime;
			m_Location = location;
			m_Text = text;
		}

		public ErrorListItem(ErrorAddedEventArgs e)
		{
			m_OccuerTime = e.OccuerTime;
			m_Location = e.Location;
			m_Text = e.Text;
		}

		public DateTime OccuerTime
		{
			get { return m_OccuerTime; }
		}

		public string Location
		{
			get { return m_Location; }
		}

		public string Text
		{
			get { return m_Text; }
		}
	}
}
