using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;

namespace Salamax
{
  public partial class LogListBox : ListBox
  {
    private int _lastItemCount;
    private int _lastClientWidth;
    private int _lastImageSize;
    private int _maxStringHeight;
    private ImageList _imageList;

    public ImageList ImageList
    {
      get
      {
        return _imageList;
      }
      set
      {
        _imageList = value;
      }
    }

    public LogListBox()
    {
      InitializeComponent();

      DrawMode = DrawMode.OwnerDrawFixed;
    }

    protected override void OnDrawItem(DrawItemEventArgs e)
    {
      ImageListBoxItem item = e.Index < 0 || this.DesignMode ? null : Items[e.Index] as ImageListBoxItem;
      bool draw = _imageList != null && (item != null);

      if (draw)
      {
        e.DrawBackground();
        e.DrawFocusRectangle();

        Size imageSize = _imageList.ImageSize;
        if (this.ItemHeight != imageSize.Height + 2) this.ItemHeight = imageSize.Height + 2;

        CheckHorizonalScroll(e.Graphics, e.Font);

        Rectangle bounds = e.Bounds;
        string strTextToDraw = item.ToString();
        Color color = e.ForeColor;

        if (item.ImageIndex > -1 && item.ImageIndex < _imageList.Images.Count)
        {
          _imageList.Draw(e.Graphics, bounds.Left, bounds.Top, item.ImageIndex);
          if (item.Color != Color.Empty) color = item.Color;
        }

        e.Graphics.DrawString(strTextToDraw, e.Font, new SolidBrush(color),
          /*bounds.Left*/0 + imageSize.Width, bounds.Top + (int)((this.ItemHeight - _maxStringHeight) / 2));
      }
      else
      {
        base.OnDrawItem(e);
      }
    }

    private void CheckHorizonalScroll(Graphics g, Font f)
    {
      int maxStringWidth = 0;
      int maxStringHeight = 0;
      foreach (object item in Items)
      {
        string s = item.ToString();
        SizeF size = g.MeasureString(s, f);
        if (maxStringHeight < size.Height) maxStringHeight = (int)size.Height;
        if (maxStringWidth < size.Width) maxStringWidth = (int)size.Width;
      }

      _lastImageSize = _imageList.ImageSize.Width;
      _lastClientWidth = ClientSize.Width;
      _lastItemCount = Items.Count;
      _maxStringHeight = maxStringHeight;

      int he = maxStringWidth + _lastImageSize;
      if (HorizontalExtent != he) HorizontalExtent = he;

    }

    public class ImageListBoxItem
    {
      private int _imageIndex;
      private object _item;
      private Color _color;

      public int ImageIndex
      {
        get
        {
          return _imageIndex;
        }
        set
        {
          _imageIndex = value;
        }
      }

      public object Item
      {
        get
        {
          return _item;
        }
        set
        {
          _item = value;
        }
      }

      public Color Color
      {
        get
        {
          return _color;
        }
        set
        {
          _color = value;
        }
      }

      public ImageListBoxItem() : this(null) { }

      public ImageListBoxItem(object item) : this(-1, item) { }

      public ImageListBoxItem(int imageIndex, object item) : this(imageIndex, Color.Empty, item) { }

      public ImageListBoxItem(int imageIndex, Color color, object item)
      {
        _imageIndex = imageIndex;
        _color = color;
        _item = item;
      }

      public override string ToString()
      {
        if (_item == null)
          return String.Empty;

        return _item.ToString();
      }
    }
  }
}
