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

namespace Medivators.Common.Logging
{
	#region ILogProvider interface

	public interface ILogProvider : IDisposable
	{
		void Initialize ();
		bool WriteLog(string Text);
		bool WriteLog(string Text, EventLogEntryType LogType);
		bool WriteLog(string Text, EventLogEntryType LogType, byte[] Data);
		bool WriteLog(LogEntryType Criticality, string Text);
		bool WriteLog(LogEntryType Criticality, string Text, EventLogEntryType LogType);
		bool WriteLog(LogEntryType Criticality, string Text, EventLogEntryType LogType, byte[] Data);
	}

	#endregion

	/// <summary>
	/// Summary description for Log.
	/// </summary>
	public class Log : IDisposable
	{
		private		   ILogProvider			_provider = null;
		private static Log					_instance = null;
		private static Enums.LoggingLevels  _defaultLogLevel = Enums.LoggingLevels.Verbose;

		#region construct/init/dispose

		private Log() {	}

		public static Log GetInstance()
		{
			if ( _instance == null )
				_instance = new Log();
			return _instance;
		}
		public void Dispose()
		{
			this._provider.Dispose();
		}

		#endregion
		
		public ILogProvider Provider 
		{
			get { return this._provider;  }
			set { this._provider = value; }
		}

		public bool WriteLog(string Text)
		{
			return this.WriteLog ( Text, EventLogEntryType.Information, null );
		}
		public bool WriteLog(string Text, EventLogEntryType LogEntryType )
		{
			return this.WriteLog ( Text, LogEntryType, null );
		}
		public bool WriteLog(string Text, EventLogEntryType LogEntryType, byte[] Data )
		{
			bool rtnVal = true;
			try
			{
				this._provider.WriteLog( Text, LogEntryType, Data );
			}
			catch 
			{
				//	maybe no provider was initialized? If so,
				//	use app log
				if (_provider == null)
				{
					_provider = new Logging.ApplicationLog();
					try
					{
						_provider.WriteLog(Text, LogEntryType, Data);
					}
					catch
					{
						rtnVal = false;
					}
				}
				// cannot raise exception here, this method
				// is commonly used by error handlers
				rtnVal = false;	
			}
			return rtnVal;
		}
		public bool WriteLog(LogEntryType Criticality, string Text)
		{
			return this.WriteLog(Criticality, Text, EventLogEntryType.Information, null);
		}
		public bool WriteLog(LogEntryType Criticality, string Text, EventLogEntryType LogType)
		{
			return this.WriteLog(Criticality, Text, LogType, null);
		}
		public bool WriteLog(LogEntryType Criticality, string Text, EventLogEntryType LogType, byte[] Data)
		{
			bool rtnVal = true;
			byte EntryValue = Convert.ToByte(Criticality);

			LoggingLevels lvl = _defaultLogLevel;
			try
			{
				 lvl = (LoggingLevels)Enum.Parse(typeof(LoggingLevels),
					TextSettings.GetInstance()[Medivators.Common.Enums.SettingTypes.Application,
					"LoggingLevel"]);
			}
			catch {}
						
			byte LogValue = Convert.ToByte(lvl);
			if (EntryValue > LogValue || LogValue == 0)
				rtnVal = false;
			else
				rtnVal = this.WriteLog(Text, LogType, Data);
			return rtnVal;
		}
		public bool WriteLog(string Text, bool IgnoreLoggingLevel)
		{
			bool rtnVal = true;
			try
			{
				if (IgnoreLoggingLevel)
					rtnVal = this.WriteLog(Text, EventLogEntryType.Information, null);
				else
					this.WriteLog(Text);
			}
			catch
			{
				rtnVal = false;
			}
			return rtnVal;
		}
	}
}
