Imports System.Reflection
Imports System.ComponentModel

''' <summary>
''' A default property sort comparer
''' </summary>
''' <remarks></remarks>
Public Class PropertySortComparer(Of T)
    Implements IComparer(Of T)

    Public Sub New()
    End Sub

    Private _info As PropertyInfo
    Private _propertyName As String

    Public Property PropertyName() As String
        Get
            Return Me._propertyName
        End Get
        Set(ByVal value As String)
            If Me._propertyName <> value Then
                Me._propertyName = value
                SetPropertyInfo(value)
            End If
        End Set
    End Property

    Private _direction As ListSortDirection

    Public Property Direction() As ListSortDirection
        Get
            Return Me._direction
        End Get
        Set(ByVal value As ListSortDirection)
            If Me._direction <> value Then
                Me._direction = value
            End If
        End Set
    End Property

    Private Sub SetPropertyInfo(ByVal propertyName As String)
        If Not (String.IsNullOrEmpty(propertyName)) Then
            Dim current = GetType(T)
            Me._info = current.GetProperty(propertyName, BindingFlags.Instance Or BindingFlags.Public)
        End If
    End Sub

    Public Function Compare(ByVal x As T, ByVal y As T) As Integer Implements System.Collections.Generic.IComparer(Of T).Compare
        If Me._info Is Nothing Then _
            Return 0

        Dim xValue = Me._info.GetValue(x, Nothing)
        Dim yValue = Me._info.GetValue(y, Nothing)

        Dim comparison = Comparer.Default.Compare(xValue, yValue)
        If comparison <> 0 Then
            If Me.Direction = ListSortDirection.Descending Then _
                Return -comparison
        End If
        Return comparison
    End Function
End Class