using System;
using System.Windows.Forms;
using Microsoft.Win32;
using System.ComponentModel;
using System.Collections;
using System.Diagnostics;
using System.IO;

namespace LLNet.Controls
{
	/// <summary>
	/// Summary description for LLEventLog.
	/// </summary>
	public class LLEventLog : System.ComponentModel.Component
	{
		public event OnLogEndedEventHandler OnLogEnded;
		public event OnWriteLogEventHandler OnWriteLog;

		/// <summary>
		/// tamaño máximo del archivo de log (default 2MB).
		/// </summary>
		private long fileSize = 2097152; 
		public static string ExeDir;

		
		public LLEventLog(System.ComponentModel.IContainer container)
		{
			///
			/// Required for Windows.Forms Class Composition Designer support
			///
			container.Add(this);
			InitializeComponent();
		}

		
		public LLEventLog(string exeDir)
		{
			///
			/// Required for Windows.Forms Class Composition Designer support
			///
			InitializeComponent();

			ExeDir = exeDir;



			LoadConfig();
		}

		
		public void LoadConfig()
		{
			loaded = false;
			ds = new EventLog();

			if (!File.Exists(ExeDir + "EventLog.xml"))
			{
				ds.Config.Clear();
				ds.Config.AddConfigRow("ON",2500,"");
				ds.AcceptChanges();
				ds.WriteXml(ExeDir + "EventLog.xml",System.Data.XmlWriteMode.IgnoreSchema);
			}

			try
			{
				ds.Clear();
				ds.ReadXml(ExeDir + "EventLog.xml");
				
				if (ds.Config.Rows.Count > 0)
				{
					state = ds.Config.Rows[0]["State"].ToString();
					maxSize = int.Parse(ds.Config.Rows[0]["MaxSize"].ToString());
					currentLog = ds.Config.Rows[0]["CurrentLog"].ToString();

					loaded = true;
				}
			}
			catch(Exception e)
			{
				Console.WriteLine(e.Message);
				loaded = false;
			}
		}

		
		public void WriteLog(string errorType, string message)
		{
			if (!loaded) LoadConfig();

			if ( state.ToUpper() != "OFF" && (state.ToUpper() == "ON" || (state.ToUpper() == "ONLY_ERRORS" && errorType == Utils.Types.ErrorTypes.ERROR) ) )
			{
				StreamWriter sw = null;
				try
				{
					checkLogExistence();
					
					sw = new StreamWriter(currentLog,true);	

					if (sw.BaseStream.Length > fileSize)
					{
						string oldCurrentLog = currentLog;
						
						currentLog = "";
						checkLogExistence();

						if (OnLogEnded != null) OnLogEnded(oldCurrentLog);

						sw = new StreamWriter(currentLog,true);	
					}

					if (OnWriteLog != null) 
					{	
						OnWriteLog(sw,message);
					}
					else
					{
						sw.WriteLine(DateTime.Now.ToString() + "   " + message);
					}
				}
				catch(Exception e)
				{
					Console.WriteLine(e.Message);
				}
				finally
				{
					if (sw != null) sw.Close();
				}
			}
		}

		
		public void WriteLog(Exception e)
		{
			//TODO: implementar que info guardo de la excepcion
			//WriteLog(Utils.Types.ErrorTypes.ERROR,e.Message + " - " + e.StackTrace);
			WriteLog(Utils.Types.ErrorTypes.ERROR, e.ToString());
		}


			
		/// <summary>
		/// Required designer variable.
		/// </summary>
		private System.ComponentModel.Container components = null;

		private bool loaded;
		private EventLog ds;

		private string state;  	/*	ON,OFF,ONLY_ERRORS  */
		private int maxSize;
		private string currentLog;

		private void checkLogExistence()
		{
			if (currentLog == "")
			{
				//creo el fichero
				string filename = ExeDir + "EventLog " + DateTime.Now.Year.ToString() + "-" + DateTime.Now.Month.ToString() + "-" + DateTime.Now.Day.ToString() + " " + DateTime.Now.Hour.ToString() + "-" + DateTime.Now.Minute.ToString()+ "-" + DateTime.Now.Second.ToString() + ".log";
		
				FileStream fs = File.Create(filename);	
			
				ds.Config.Rows[0]["CurrentLog"] = filename;
				currentLog = filename;

				ds.WriteXml(ExeDir + "EventLog.xml");
			}
		}


	

		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}


		#region Component Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{

		}
		#endregion
	}

	public delegate void OnLogEndedEventHandler(string logFileName);
	public delegate void OnWriteLogEventHandler(StreamWriter sw, string toWrite);
}
