using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;

using System.Text;
using System.Windows.Forms;
using CommonLang.Log;
using System.IO;
using CommonLang;

using Microsoft.Win32;

namespace CommonFroms.Utils
{
    public partial class ConsoleOutput : Form
    {
        private MyLogger log;
        private LoggerFactory old_factory;
        private Form m_DockTo;
        private Form m_OldActive;

        public bool IsDock
        {
            get { return toolDock.Checked; }
        }
        public Form DockTo
        {
            get { return m_DockTo; }
            set
            {
                m_DockTo = value;
            }
        }

        public ConsoleOutput(string name="Output")
        {
            InitializeComponent();
            bool dock = true;
            if (RegistUtils.TryGetAppRegistry("ConsoleOutput.Dock", out dock))
            {
                this.toolDock.Checked = dock;
            }
            this.old_factory = LoggerFactory.CurrentFactory;
            this.log = new MyLogger(name);
            LoggerFactory.SetFactory(new MyLoggerFactory());
            this.Disposed += ConsoleOutput_Disposed;
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            string text = MyLogger.GetLines();
            if (!string.IsNullOrEmpty(text))
            {
                this.textBox1.AppendText(text);
            }
            if (this.IsDock && m_DockTo != null)
            {
                var dsize = m_DockTo.Bounds;
                this.Bounds = new System.Drawing.Rectangle(
                    dsize.X, dsize.Y + dsize.Height,
                    dsize.Width, this.Height);
                if (m_DockTo == Form.ActiveForm)
                {
                    if (m_OldActive != Form.ActiveForm)
                    {
                        this.Activate();
                        m_DockTo.Activate();
                    }
                }
                m_OldActive = Form.ActiveForm;
            }
        }


        private void ConsoleOutput_Disposed(object sender, EventArgs e)
        {
            RegistUtils.PutAppRegistry("ConsoleOutput.Dock", this.toolDock.Checked);
            LoggerFactory.SetFactory(old_factory);
        }

        public Logger GetLogger()
        {
            return log;
        }


        internal class MyLoggerFactory : LoggerFactory
        {
            override protected Logger CreateLogger(string name)
            {
                return new MyLogger(name);
            }
        }

        internal class MyLogger : Logger
        {
            static public List<string> lines = new List<string>();

            public MyLogger(string name)
            {
                base.SetName(name);
            }

            protected override void Print(string text)
            {
                lock (lines)
                {
                    lines.Add(mName + " - " + text);
                }
            }

            static public string GetLines()
            {
                StringBuilder sb = new StringBuilder();
                lock (lines)
                {
                    foreach (string line in lines)
                    {
                        sb.AppendLine(line);
                    }
                    lines.Clear();
                }
                return sb.ToString();
            }
        }
    }
}