using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;
using System.Collections;

namespace pcmp
{
    class ListViewItemComparer : IComparer
    {
        private SortOrder _order;
        private ColumnHeader _header;

        /// <summary>
        /// ソートする列
        /// </summary>
        public ColumnHeader ColumnHeader
        {
            get { return _header; }
            set
            {
                if (_header == value)
                {
                    if (_order == SortOrder.Ascending)
                        _order = SortOrder.Descending;
                    else if (_order == SortOrder.Descending)
                        _order = SortOrder.Ascending;
                }
                else
                {
                    _order = SortOrder.Ascending;
                }

                _header = value;
            }
        }

        /// <summary>
        /// 昇順か降順か
        /// </summary>
        public SortOrder Order
        {
            set
            {
                _order = value;
            }
            get
            {
                return _order;
            }
        }

        /// <summary>
        /// ListViewItemクラスのコンストラクタ
        /// </summary>
        /// <param name="ord">ソートする順序</param>
        /// <param name="header">ソートする列</param>
        public ListViewItemComparer(SortOrder ord, ColumnHeader header)
        {
            _order = ord;
            _header = header;
        }

        // IComparerインターフェースの実装
        public int Compare(object x, object y)
        {
            // 並び替えの方法別に、xとyを比較する
            // PropertyDescriptorからChannelクラスのプロパティを取得して比較
            if (x == null || y == null) return 0;
            PropertyDescriptor pd = _header.Tag as PropertyDescriptor;
            if (pd == null) return 0;
            object xValue = pd.GetValue(((ListViewItem)x).Tag);
            object yValue = pd.GetValue(((ListViewItem)y).Tag);

            if (_order == SortOrder.Ascending)
            {
                return CompareAscending(xValue, yValue);
            }
            else
            {
                return CompareDescending(xValue, yValue);
            }
        }

        // Compare two property values of any type
        private int CompareAscending(object xValue, object yValue)
        {
            int result;

            // If values implement IComparer
            if (xValue is IComparable)
            {
                result = ((IComparable)xValue).CompareTo(yValue);
            }
            // If values don't implement IComparer but are equivalent
            else if (xValue.Equals(yValue))
            {
                result = 0;
            }
            // Values don't implement IComparer and are not equivalent, so compare as string values
            else result = xValue.ToString().CompareTo(yValue.ToString());

            // Return result
            return result;
        }

        private int CompareDescending(object xValue, object yValue)
        {
            // Return result adjusted for ascending or descending sort order ie
            // multiplied by 1 for ascending or -1 for descending
            return CompareAscending(xValue, yValue) * -1;
        }
    }
}
