using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
 
namespace Salamax
{
  public partial class LogViewer : Form
  {
    private bool _forceClose = false;
    private Queue<KeyValuePair<Logger.Type, string>> _events;
    private System.Threading.Thread _th;

    public LogViewer()
    {
      InitializeComponent();

      lstItems.ImageList = imlMain;

      _events = new Queue<KeyValuePair<Logger.Type, string>>();

      Logger.ItemAdded += Logger_ItemAdded;

      _th = new System.Threading.Thread(new System.Threading.ThreadStart(_UpdateListThread));
      _th.IsBackground = true;
      _th.Start();
    }

    public void ForceClose()
    {
      _forceClose = true;
      this.Close();
    }

    private void Logger_ItemAdded(object sender, LogEventArgs e)
    {
      lock (_events)
      {
        _events.Enqueue(new KeyValuePair<Logger.Type, string>(e.Type, e.Message));
      }
    }

    private void _UpdateListThread()
    {
      while (true)
      {
        if (_events.Count > 0)
          _UpdateList();

        System.Threading.Thread.Sleep(100);
      }
    }

    private void _UpdateList()
    {
      if (this.InvokeRequired)
      {
        this.Invoke(new MethodInvoker(_UpdateList));
      }
      else
      {
        lstItems.BeginUpdate();

        var items = new Queue<KeyValuePair<Logger.Type, string>>();
        lock (_events)
        {
          while (_events.Count > 0)
            items.Enqueue(_events.Dequeue());
        }
        while (items.Count > 0)
        {
          //Add this to the ListView
          var item = items.Dequeue();
          lstItems.Items.Insert(0, new LogListBox.ImageListBoxItem((int)item.Key, item.Value));
        }

        lstItems.EndUpdate();
      }
    }

    private void LogViewer_FormClosing(object sender, FormClosingEventArgs e)
    {
      if (!_forceClose)
      {
        //No closing for you!
        e.Cancel = true;
      }
      else
      {
        _th.Abort();
        _th = null;
      }
    }

    private void mniExit_Click(object sender, EventArgs e)
    {
      this.Hide();
    }

    private void LogViewer_Load(object sender, EventArgs e)
    {
      var asm = System.Reflection.Assembly.GetExecutingAssembly();
      var name = asm.GetName();

      this.Text = name.Name + " v" + name.Version.ToString(3) + " - Application Log";
    }
  }
}
