//>>***************************************************************************
//                              UNCLASSIFIED
//
//                COPYRIGHT 2017 RAYTHEON MISSILE SYSTEMS 
//                         ALL RIGHTS RESERVED
//   This data was developed pursuant to Contract Number HQ0147-12-C-0004/1088370
//     with the US Government. The US Government's rights in and to this 
//        copyrighted data are as specified in DFAR 252.227-7013 
//               which was made part of the above contract.
//
//    Distribution Statement: D -Distribution authorized to the DoD and DoD 
//       contractors only based on Critical Technology Requirements, May 2001.
//       Other requests shall be referred to PEO THEATER AIR DEFENSE (PMS 422).
//    Warning: - This document contains technical data whose export is restricted
//       by the Arms Export Control Act (Title 22, U.S.C.) or Export 
//       Administration Act of 1979, as amended (Title 50, U.S.C.). Violations 
//       of these laws are subject to severe criminal penalties. Disseminate in 
//       accordance with provisions of DoD 5230.25.
//    Destruction Notice: - For unclassified, limited distribution information, 
//       destroy by any method that will prevent disclosure of contents or 
//       reconstruction of the document. Classified information, destroy in 
//       accordance with DoD-5220.22-M or OPNAVINST 5510.1h.
//>>***************************************************************************

using System;
using NLog;
using Raytheon.Common;

namespace Raytheon.Instruments
{
	/// <summary>
	/// </summary>
	public class SpecAnSim : ISpecAnalyzer
	{
		#region PublicMembers
		#endregion

		#region PrivateMembers

		private State _state;
		private SelfTestResult _selfTestResult;
		private string _name;

		/// <summary>
		/// NLog logger
		/// </summary>
		private readonly ILogger _logger;
		/// <summary>
		/// Raytheon configuration
		/// </summary>
		private readonly IConfigurationManager _configurationManager;
		private readonly IConfiguration _configuration;

		#endregion

		#region PrivateFunctions

		/// <summary>
		/// The Finalizer which will release resources if required
		/// </summary>
		~SpecAnSim()
		{
			Dispose(false);
		}

		/// <summary>
		/// Dispose of this object
		/// </summary>
		/// <param name="disposing"></param>
		protected virtual void Dispose(bool disposing)
		{
			try
			{
				if (disposing)
				{
					if (_state == State.Ready)
					{
						Reset();

						_state = State.Uninitialized;
					}
				}
			}
			catch (Exception)
			{
				try
				{
					//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
				}
				catch (Exception)
				{
					//Do not rethrow. Exception from error logger that has already been garbage collected
				}
			}
		}

		#endregion

		/// <summary>
		/// SpecAnSim factory constructor
		/// </summary>
		/// <param name="deviceName"></param>
		/// <param name="configurationManager"></param>
		public SpecAnSim(string deviceName, IConfigurationManager configurationManager, ILogger logger)
		{
			Name = deviceName;

			_logger = logger;

			_configurationManager = configurationManager;
			_configuration = _configurationManager.GetConfiguration(Name);

			_state = State.Uninitialized;
			_selfTestResult = SelfTestResult.Unknown;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="name"></param>
		public SpecAnSim(string name)
		{
			_name = name;
			_logger = LogManager.GetCurrentClassLogger();
			_state = State.Uninitialized;
			_selfTestResult = SelfTestResult.Unknown;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="type"></param>
		/// <param name="numOfAverages"></param>
		public void ConfigureAveraging(SpecAnAveragingType type, int numOfAverages)
		{

		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="rbw"></param>
		/// <param name="vbw"></param>
		public void ConfigureBandwidth(int rbw, int vbw)
		{

		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="centerFreq"></param>
		/// <param name="span"></param>
		public void ConfigureFrequency(int centerFreq, int span)
		{

		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="referanceLevel"></param>
		/// <param name="attenuation"></param>
		public void ConfigurePowerLevel(/*int referanceLevel, */int attenuation)
		{

		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public bool ClearErrors()
		{
			throw new NotImplementedException();
		}

		/// <summary>
		/// 
		/// </summary>
		public string DetailedStatus
		{
			get
			{
				return "This is a Scpi Spec An ";
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public bool DisplayEnabled
		{
			get
			{
				throw new NotImplementedException();
			}

			set
			{
				throw new NotImplementedException();
			}
		}

		/// <summary>
		/// Dispose of this objects resources
		/// </summary>
		public void Dispose()
		{
			try
			{
				Dispose(true);

				GC.SuppressFinalize(this);
			}
			catch (Exception)
			{
				try
				{
					//ErrorLogger.Instance().Write(err.Message + "\r\n" + err.StackTrace);
				}
				catch (Exception)
				{
					//Do not rethrow. Exception from error logger that has already been garbage collected
				}
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public bool FrontPanelEnabled
		{
			get
			{
				throw new NotImplementedException();
			}

			set
			{
				throw new NotImplementedException();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public InstrumentMetadata Info
		{
			get
			{
				throw new NotImplementedException();
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public void Initialize()
		{
			// if we have not yet been initialized, go ahead and create the socket
			if (_state == State.Uninitialized)
			{
				Reset();

				// we already connected to the instrument in the constructor
				_state = State.Ready;
			}
			else
			{
				throw new Exception("expected the state of System " + _name + " to be Uninitialized, state was: " + _state.ToString());
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="command"></param>
		/// <returns></returns>
		public string IOQuery(string command, int timeout = 10000)
		{
			return "100";
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="command"></param>
		public void IOWrite(string command, bool shallWeCheckForError = true)
		{
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public double MeasurePeakAmplitude()
		{
			return 0.0;
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public double MeasurePeakFrequency()
		{
			return 0.0;
		}

		/// <summary>
		/// 
		/// </summary>
		public string Name
		{
			get
			{
				return _name;
			}
			set
			{
				_name = value;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public SelfTestResult SelfTestResult
		{
			get
			{
				return _selfTestResult;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public State Status
		{
			get
			{
				return _state;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		public SelfTestResult PerformSelfTest()
		{
			try
			{
				_selfTestResult = SelfTestResult.Pass;

				return SelfTestResult.Pass;
			}
			catch (Exception)
			{
				throw;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		public void Reset()
		{
		}

		/// <summary>
		/// 
		/// </summary>
		public void Shutdown()
		{
			string errorMsg = "";

			if (_state == State.Ready)
			{
				try
				{
					//Reset System
					Reset();
				}
				catch (Exception err)
				{
					errorMsg += err.Message + " ";
				}

				_state = State.Uninitialized;
			}
		}
	}
}
