Imports Mercury.Mobile.Collections
Imports System.Text

''' <summary>
''' Represents a 1-tuple, or singleton.
''' </summary>
''' <typeparam name="T1">The type of the tuple's only component.</typeparam>
''' <remarks></remarks>
Public Class Tuple(Of T1)
    Implements IStructuralEquatable, IStructuralComparable, IComparable, ITuple

    ''' <summary>
    ''' Initializes a new instance of the specified <see cref="Mercury.Mobile.Tuple(Of T1)"/> class.
    ''' </summary>
    ''' <param name="item1">The value of the tuple's only component.</param>
    ''' <remarks></remarks>
    Public Sub New(ByVal item1 As T1)
        Me.m_item1 = item1
    End Sub

    Private ReadOnly m_item1 As T1

    ''' <summary>
    ''' Gets the value of the <see cref="Mercury.Mobile.Tuple(Of T1)"/> object's single component.
    ''' </summary>
    ''' <returns>The value of the <see cref="Mercury.Mobile.Tuple(Of T1)"/> object's single component.</returns>
    ''' <remarks></remarks>
    Public ReadOnly Property Item1() As T1
        Get
            Return Me.m_item1
        End Get
    End Property

    Private ReadOnly Property Size() As Integer Implements ITuple.Size
        Get
            Return 1
        End Get
    End Property

    ''' <summary>
    ''' Returns a value that indicates whether the current <see cref="Mercury.Mobile.Tuple(Of T1)"/> object is equal to a specified object.
    ''' </summary>
    ''' <param name="obj">The object to compare with this instance.</param>
    ''' <returns>True if the current instance is equal to the specified object; otherwise, false.</returns>
    ''' <remarks></remarks>
    Public Overrides Function Equals(ByVal obj As Object) As Boolean
        Return CType(Me, IStructuralEquatable).Equals(obj, EqualityComparer(Of Object).Default)
    End Function

    Private Function Equals1(ByVal other As Object, ByVal comparer As System.Collections.IEqualityComparer) As Boolean Implements Collections.IStructuralEquatable.Equals
        If other Is Nothing Then _
            Return False
        Dim tuple = TryCast(other, Tuple(Of T1))
        Return tuple IsNot Nothing AndAlso comparer.Equals(Me.m_item1, tuple.m_item1)
    End Function

    Private Function CompareTo1(ByVal obj As Object) As Integer Implements System.IComparable.CompareTo
        Return CType(Me, IStructuralComparable).CompareTo(obj, EqualityComparer(Of Object).Default)
    End Function

    Private Function CompareTo(ByVal other As Object, ByVal comparer As System.Collections.IComparer) As Integer Implements Collections.IStructuralComparable.CompareTo
        If other Is Nothing Then _
            Return 1
        Dim tuple = TryCast(other, Tuple(Of T1))
        If tuple Is Nothing Then
            Throw New ArgumentException(String.Format(My.Resources.Culture, _
                My.Resources.ArgumentException_IncorrectType, "other", MyBase.GetType().ToString()))
        End If
        Return comparer.Compare(Me.m_item1, tuple.m_item1)
    End Function

    ''' <summary>
    ''' Returns the hash code for the current <see cref="Mercury.Mobile.Tuple(Of T1)"/> object.
    ''' </summary>
    ''' <returns>A 32-bit signed integer hash code.</returns>
    ''' <remarks></remarks>
    Public Overrides Function GetHashCode() As Integer
        Return CType(Me, IStructuralEquatable).GetHashCode(EqualityComparer(Of Object).Default)
    End Function

    Private Function GetHashCode1(ByVal comparer As System.Collections.IEqualityComparer) As Object Implements Collections.IStructuralEquatable.GetHashCode
        Return comparer.GetHashCode(Me.m_item1)
    End Function

    Private Function GetHashCode2(ByVal comparer As System.Collections.IEqualityComparer) As Integer Implements ITuple.GetHashCode
        Return CType(Me, IStructuralEquatable).GetHashCode(comparer)
    End Function

    ''' <summary>
    ''' Returns a string that represents the value of this <see cref="Mercury.Mobile.Tuple(Of T1)"/> instance.
    ''' </summary>
    ''' <returns>The string representation of this <see cref="Mercury.Mobile.Tuple(Of T1)"/> object.</returns>
    ''' <remarks></remarks>
    Public Overrides Function ToString() As String
        Dim sb = New StringBuilder()
        sb.Append("(")
        Return CType(Me, ITuple).ToString(sb)
    End Function

    Private Function ToString1(ByVal sb As System.Text.StringBuilder) As String Implements ITuple.ToString
        sb.Append(Me.m_item1)
        sb.Append(")")
        Return sb.ToString()
    End Function

End Class