using System;
using System.Windows.Forms;
using System.IO;

namespace iSTP_DebugConsole
{
    /// <summary>
    /// Debugg windows for with detail information for experts
    /// </summary>
    public partial class DebugConsole : Form
    {
        /// <summary>
        /// This class
        /// </summary>
        private static DebugConsole self;
        /// <summary>
        /// Debug file
        /// </summary>
        private static StreamWriter wFile;

        /// <summary>
        /// Constructor. Initialize component, append DebugLogger.txt and write time, date and header into it
        /// </summary>
        public DebugConsole()
        {
            InitializeComponent();
            self = this;
            wFile = new StreamWriter("DebugLogger.txt", true);
            wFile.Write(string.Format("{0}*****************************************************************{0}", Environment.NewLine));
            wFile.Write(DateTime.Now.ToLongDateString());
            wFile.Write('\t');
            wFile.WriteLine(DateTime.Now.ToLongTimeString());
            wFile.Flush();
        }

        /// <summary>
        /// Close DebugLogger.txt
        /// </summary>
        ~DebugConsole()
        {
            if (wFile != null)
            {
                wFile.Flush();
                wFile.Close();
            }
        }

        /// <summary>
        /// Clear window
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        public void clearToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DebugConsole.Clear();
        }

        /// <summary>
        /// Clear window
        /// </summary>
        public static void Clear()
        {
            if (self.DbgConsoleTextBox.InvokeRequired)
            {
                self.DbgConsoleTextBox.Invoke(new MethodInvoker(delegate
                {
                    self.DbgConsoleTextBox.Clear();
                }));
            }
            else
            {
                self.DbgConsoleTextBox.Clear();
            }
        }

        /// <summary>
        /// Write line with end line char
        /// </summary>
        /// <param name="text">Text to write in window</param>
        /// <param name="args">Arguments</param>
        public static void WriteLine(string text, params object[] args)
        {
            if (self.DbgConsoleTextBox.InvokeRequired)
            {
                self.DbgConsoleTextBox.Invoke(new MethodInvoker(delegate
                {
                    self.DbgConsoleTextBox.AppendText(String.Format(text + "\n", args));

                }));
            }
            else
            {
                self.DbgConsoleTextBox.AppendText(String.Format(text + "\n", args));
            }

            if (wFile != null)
            {
                DateTime now = DateTime.Now;
                wFile.Write(string.Format("[{0} {1}:{2}:{3}.{4}] ", now.ToShortDateString(), now.Hour, now.Minute, now.Second, now.Millisecond));
                wFile.Write(string.Format("{0}{1}",text, Environment.NewLine), args);
                wFile.Flush();
            }
        }

        /// <summary>
        /// Write text only
        /// </summary>
        /// <param name="text">Text to write in window</param>
        /// <param name="args">Arguments</param>
        public static void Write(string text, params object[] args)
        {
            if (self.DbgConsoleTextBox.InvokeRequired)
            {
                self.DbgConsoleTextBox.Invoke(new MethodInvoker(delegate
                {
                    self.DbgConsoleTextBox.AppendText(String.Format(text, args));

                }));
            }
            else
            {
                self.DbgConsoleTextBox.AppendText(String.Format(text, args));
            }

            if (wFile != null)
            {
                DateTime now = DateTime.Now;
                wFile.Write(string.Format("[{0} {1}:{2}:{3}.{4}] ", now.ToShortDateString(), now.Hour, now.Minute, now.Second, now.Millisecond));
                wFile.Write(text, args);
                wFile.Flush();
            }
        }

        /// <summary>
        /// Write object into window
        /// </summary>
        /// <param name="o">Object</param>
        public static void Write(Object o)
        {
            if (self.DbgConsoleTextBox.InvokeRequired)
            {
                self.DbgConsoleTextBox.Invoke(new MethodInvoker(delegate
                {
                    self.DbgConsoleTextBox.AppendText(o.ToString());

                }));
            }
            else
            {
                self.DbgConsoleTextBox.AppendText(o.ToString());
            }

            if (wFile != null)
            {
                DateTime now = DateTime.Now;
                wFile.Write(string.Format("[{0} {1}:{2}:{3}.{4}] ", now.ToShortDateString(), now.Hour, now.Minute, now.Second, now.Millisecond));
                wFile.Write(o.ToString());
                wFile.Flush();
            }
        }

        /// <summary>
        /// Write object into window and put end of line
        /// </summary>
        /// <param name="o">Object</param>
        public static void WriteLine(Object o)
        {
            if (self.DbgConsoleTextBox.InvokeRequired)
            {
                self.DbgConsoleTextBox.Invoke(new MethodInvoker(delegate
                {
                    self.DbgConsoleTextBox.AppendText(o.ToString());

                }));
            }
            else
            {
                self.DbgConsoleTextBox.AppendText(o.ToString());
            }

            if (wFile != null)
            {
                DateTime now = DateTime.Now;
                wFile.Write(string.Format("[{0} {1}:{2}:{3}.{4}] ", now.ToShortDateString(), now.Hour, now.Minute, now.Second, now.Millisecond));
                wFile.Write(string.Format("{0}{1}", o.ToString(), Environment.NewLine));
                wFile.Flush();
            }
        }

        /// <summary>
        /// Scroll
        /// </summary>
        /// <param name="sender">Sender object</param>
        /// <param name="e">Arguments</param>
        private void DbgConsoleTextBox_TextChanged(object sender, EventArgs e)
        {
            self.DbgConsoleTextBox.ScrollToCaret();
        }
    }
}
