using System;
using Medivators.Common;
using Medivators.Common.Settings;
using Medivators.Common.Enums;

namespace Medivators.Comm
{
	/// <summary>
	/// SimulatedSerialPort allows for testing of software that supports 
	/// serial devices without actually having the serial device hooked up
	/// </summary>
	public class CommPortSimulation: ICommDevice
	{
		private const SupportedCommDevices	_device = SupportedCommDevices.CommPortSoftwareSimulation;
		private CommPortSettings			_settings;
		private CommPorts					_port = CommPorts.COM1;
		private bool						_isOpen = false;

		#region construct/init/dispose

		public CommPortSimulation()
		{
		}
		public void Dispose()
		{
		}

		#endregion

		#region common COMM device methods - implments ICommDevice

		public SupportedCommDevices		Device
		{
			get { return _device; }
		}
		public CommPortSettings			Settings
		{
			get { return this._settings;  }
			set { this._settings = value; }
		}
		public CommPorts Port
		{
			get { return this._port; }
			set { this._port = value; }
		}
		public bool IsOpen	
		{
			get { return _isOpen ; }
		}
		public void	OpenCommPort()
		{
			_isOpen = true;
		}
		public void	CloseCommPort()
		{
			_isOpen = false;
		}
		public System.Windows.Forms.DialogResult			 ShowControlDialog()
		{
			using (dlgCommPort dlg = new dlgCommPort())
			{
				dlg.Device = this;
				return dlg.ShowDialog();
			}
		}
		public void WriteByte(Byte Value) 
		{
			if (!_isOpen)
				this.OpenCommPort();
			byte[] buffer = new byte[1];
			buffer[0] = Value;
			OnDataArrived( new DataArrivedEventArgs(buffer) );
		}
		public void WriteString( string Value )
		{
			if (!_isOpen)
				this.OpenCommPort();
			OnDataArrived(new DataArrivedEventArgs(Utilities.StringToByteArray(Value)));			
		}

		#endregion

		public event DataArrivedEventHandler	 DataArrived;
		public event CommErrorEventHandler		 CommError;
		public event SettingsChangedEventHandler SettingsChanged;

		internal virtual void OnDataArrived ( DataArrivedEventArgs e )
		{
			DataArrived(this, e);
		}
		internal virtual void OnCommError ( CommErrorEventArgs e )
		{
			CommError(this, e);
		}
		internal virtual void OnSettingsChanged ( SettingsChangedEventArgs e )
		{
			SettingsChanged(this, e);
		}
	}
}
