Imports System.Reflection

Namespace SimpleHistory

    Public Class ObjectState
        Inherits ObjectBase

        ''' <summary>
        ''' The Object including the members to patch.
        ''' </summary>
        ''' <returns></returns>
        Public Property [Object] As Object = Nothing
        ''' <summary>
        ''' The name of the Member to patch.
        ''' </summary>
        ''' <returns></returns>
        Public Property MemberName As String = ""
        ''' <summary>
        ''' The Value that should be patched.
        ''' </summary>
        ''' <returns></returns>
        Public Property ValueToPatch As Object = Nothing
        ''' <summary>
        ''' The member types to include at searching for the member.
        ''' </summary>
        ''' <returns></returns>
        Public Property MemberType As ObjectValueType = ObjectValueType.Field
        ''' <summary>
        ''' The Binding Flags that are used at searching for the member.
        ''' </summary>
        ''' <returns></returns>
        Public Property MemberFlags As BindingFlags = BindingFlags.Default

        ''' <summary>
        ''' Creates a new Instance of ObjectState from input.
        ''' </summary>
        ''' <param name="obj">The Object including the members to patch.</param>
        ''' <param name="valname">The name of the Member to patch.</param>
        ''' <param name="valToPatch">The member types to include at searching for the member.</param>
        ''' <param name="valtype">The Binding Flags that are used at searching for the member.</param>
        Public Sub New(obj As Object, valname As String, valToPatch As Object, valtype As ObjectValueType)
            [Object] = obj
            MemberName = valname
            ValueToPatch = valToPatch
            MemberType = valtype
        End Sub

        ''' <summary>
        ''' Creates a new Instance of ObjectState.
        ''' </summary>
        Public Sub New()
        End Sub

        Friend Sub Patch()
            Dim t As Type = [Object].GetType
            Select Case MemberType
                Case ObjectValueType.Field
                    Dim f As FieldInfo = t.GetField(MemberName, MemberFlags)
                    Dim temp As Object = Nothing

                    If f IsNot Nothing Then
                        temp = f.GetValue([Object])
                        f.SetValue([Object], ValueToPatch)
                        ValueToPatch = temp
                    End If

                Case ObjectValueType.Property
                    Dim p As PropertyInfo = t.GetProperty(MemberName, BindingFlags.Instance Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Static)
                    Dim temp As Object = Nothing

                    If p IsNot Nothing Then
                        temp = p.GetValue([Object])
                        p.SetValue([Object], ValueToPatch)
                        ValueToPatch = temp
                    End If

                Case Else
                    Throw New Exception("ValueType is invalid!")
            End Select
        End Sub

    End Class

End Namespace