'*****************************************************************
'Copyright © 2006 ESRI. All Rights Reserved.
'*****************************************************************
'Description: Class wrapping the Project Mgr.
'  It has the capablity to read/load from xml configuration.
'  Implements IMenuType so that the MenuType value can be queried 
'  by whoever needs the info.
'History: z.ye @6/21/2006 4:55:50 PM
'*****************************************************************
Imports System.Reflection
Imports System.xml
<Serializable()> Public Class ApWebFields
  Inherits Hashtable
  Private Const _LoadXMLNode As String = "LoadXMLNode"   'Child Objects need to have LoadXMLNode method:LoadXMLNode(System.XmlNode)
  Private Const _ToXMLNode As String = "ToXMLNode"   'Child Objects need to have LoadXMLNode method:LoadXMLNode(System.XmlNode)
  Private Const _Name As String = "Name"   'Child object need to have Name property = the Name of the parent property refrencing the child object
  Private Const _TagName As String = "TagName"
  Private mName As String = ""
  Private mTagName As String = ""
  Private mDesc As String = ""
  Private mType As Integer
  Private mExtraParams As String   'params may need
  Public Property ExtraParams() As String
    Get
      Return mExtraParams
    End Get
    Set(ByVal Value As String)
      mExtraParams = Value
    End Set
  End Property
  Public Property Desc() As String
    Get
      If mDesc = "" Then
        mDesc = Name
      End If
      Return mDesc
    End Get
    Set(ByVal Value As String)
      mDesc = Value
    End Set
  End Property

  Public Property Name() As String
    Get
      If mName = "" Then
        mName = TagName
      End If
      Return mName
    End Get
    Set(ByVal Value As String)
      mName = Value
    End Set
  End Property
  Public Property TagName() As String
    Get
      Return mTagName
    End Get
    Set(ByVal Value As String)
      mTagName = Value
    End Set
  End Property
  Public Function ToXMLString() As String
    Dim pXMLDoc As XMLDocument
    pXMLDoc = New XMLDocument
    pXMLDoc = ToXMLDoc(pXMLDoc)
    Return pXMLDoc.OuterXml
  End Function
  ''' -----------------------------------------------------------------------------
  ''' <summary>
  '''   Write the ApWebFields to an XMLDoc, if ParentNode is provided, append the ApWebFieldsNode to the parentnode
  ''' </summary>
  ''' <param name="pDoc"> XMLDocument</param>
  ''' <returns>XMLDOC</returns>
  ''' <remarks>
  ''' </remarks>
  ''' <history>
  ''' 	[ye]	4/12/2006	Created
  ''' </history>
  ''' -----------------------------------------------------------------------------
  Public Function ToXMLDoc(Optional ByVal pDoc As XMLDocument = Nothing) As XMLDocument
    '*****************************************************************
    'Copyright © 2006 ESRI. All Rights Reserved.
    '*****************************************************************
    'Description: 
    'History: z.ye @4/12/2006 9:09:27 AM
    '*****************************************************************
    Dim ds As Long = Date.Now.Ticks
    Try
      If pDoc Is Nothing Then
        pDoc = New XMLDocument
      End If
      If Not pDoc Is Nothing Then
        ToXMLNode(pDoc, Nothing)
      End If
    Catch ex As Exception

    End Try
    Return pDoc
  End Function
  ''' <summary>
  ''' Write the HISNetworks to an XMLDoc, if ParentNode is provided, append the HISNetworksNode to the parentnode
  ''' </summary>
  ''' <param name="pDoc"></param>
  ''' <param name="pNodeParent"></param>
  ''' <returns>System.xml.XMLNode</returns>
  ''' <remarks></remarks>
  ''' <history>
  ''' 	[ye]	4/12/2006	Created
  ''' </history>
  Public Function ToXMLNode(ByVal pDoc As XmlDocument, ByVal pNodeParent As XmlNode) As XmlNode
    '*****************************************************************
    'Copyright © 2006 ESRI. All Rights Reserved.
    '*****************************************************************
    'Description: Write the HISNetworks to an XMLDoc, 
    '  if ParentNode is provided, append the HISNetworksNode to the parentnode
    '  Returns the XMLNode
    'History: z.ye @4/12/2006 9:10:03 AM
    '*****************************************************************
    Dim ds As Long = Date.Now.Ticks
    Dim pNode As XmlNode = Nothing
    Dim pElem As XmlElement
    Dim sName As String
    '..GetMemebers info
    Dim pAttribute As XmlAttribute
    Dim pMembers() As System.Reflection.MemberInfo
    Dim pMemberInfo As System.Reflection.MemberInfo
    Dim pFieldInfo As System.Reflection.FieldInfo
    Dim pPropInfo As System.Reflection.PropertyInfo
    Dim pType As Type
    Dim nType As System.Reflection.MemberTypes
    Dim s As String = ""
    Dim o As Object = Nothing
    Dim bOk As Boolean

    If pDoc Is Nothing Then
      pDoc = New XmlDocument
    End If
    If Not pDoc Is Nothing Then
      sName = [GetType].Name
      pElem = pDoc.CreateElement(sName)
      pNode = pElem
      '..Get the attributes.
      pMembers = Me.GetType().GetMembers
      pType = Me.GetType
      For Each pMemberInfo In pMembers
        sName = pMemberInfo.Name
        nType = pMemberInfo.MemberType
        If pMemberInfo.MemberType = Reflection.MemberTypes.Property Or pMemberInfo.MemberType = MemberTypes.Field Then
          Try
            If pMemberInfo.MemberType = Reflection.MemberTypes.Property Then
              pPropInfo = Me.GetType.GetProperty(sName)
              o = pPropInfo.GetValue(Me, Nothing)  ' pType.InvokeMember(pMemberInfo.Name, Reflection.BindingFlags.GetProperty, Nothing, Me, Nothing, Nothing)
            ElseIf pMemberInfo.MemberType = Reflection.MemberTypes.Field Then
              pFieldInfo = Me.GetType.GetField(sName)
              o = pFieldInfo.GetValue(Me)
            End If
            bOk = ApSConfigAHS.IsTypeObject(o, s)
            If bOk = False Then
              pAttribute = pDoc.CreateAttribute(sName)
              pAttribute.Value = s
              pElem.Attributes.Append(pAttribute)
            Else

            End If
          Catch ex As Exception
            'MsgBox("1. " & ex.ToString)
          End Try
        End If
      Next
      If Not pNodeParent Is Nothing Then
        pNodeParent.AppendChild(pNode)
      Else
        pDoc.AppendChild(pNode)
      End If

      Dim oChild As Object
      Dim pMethodInfo As System.Reflection.MethodInfo
      Dim oVals(1) As Object
      For Each oChild In Me.Values
        pMethodInfo = oChild.GetType.GetMethod(_ToXMLNode)
        If Not pMethodInfo Is Nothing Then
          oVals(0) = pDoc
          oVals(1) = pNode
          pMethodInfo.Invoke(oChild, BindingFlags.Instance, Nothing, oVals, Nothing)
        End If
      Next
    End If
    Return pNode
  End Function
  ''' -----------------------------------------------------------------------------
  ''' <summary>
  '''   Load from XMLNode, if pNode is nothing, then try to get it from the pDoc.
  ''' </summary>
  ''' <param name="pNode"></param>
  ''' <returns></returns>
  ''' <remarks>
  ''' </remarks>
  ''' <history>
  ''' 	[ye]	4/12/2006	Created
  ''' </history>
  ''' -----------------------------------------------------------------------------
  Public Function LoadXMLNode(ByVal pNode As XmlNode) As Boolean
    Dim bOk As Boolean = True
    Dim pAttribute As XmlAttribute
    Dim pPropInfo As System.Reflection.PropertyInfo
    Dim pFieldInfo As System.Reflection.FieldInfo
    Dim pType As Type
    Dim strVals(0) As String
    Dim pChildNode As XmlNode
    Try
      pType = Me.GetType
      For Each pAttribute In pNode.Attributes
        Try
          pPropInfo = Me.GetType.GetProperty(pAttribute.Name)
          strVals(0) = pAttribute.Value
          If Not pPropInfo Is Nothing Then
            If pPropInfo.CanWrite = True Then
              Try
                Select Case pPropInfo.PropertyType.Name
                  Case "Object"
                    pType.InvokeMember(pAttribute.Name, BindingFlags.Default Or BindingFlags.SetProperty, Nothing, Me, strVals, Nothing)
                  Case "String"
                    pPropInfo.SetValue(Me, CType(pAttribute.Value, String), Nothing)
                  Case "Int32", "Int16", "Integer", "Int64"
                    pPropInfo.SetValue(Me, CInt(pAttribute.Value), Nothing)
                  Case "Single"
                    pPropInfo.SetValue(Me, CType(pAttribute.Value, Single), Nothing)
                  Case "Double", "Decimal"
                    pPropInfo.SetValue(Me, CType(pAttribute.Value, Double), Nothing)
                  Case "String"
                    pPropInfo.SetValue(Me, pAttribute.Value, Nothing)
                  Case "DateTime"
                    pPropInfo.SetValue(Me, CType(pAttribute.Value, DateTime), Nothing)
                  Case "Boolean"
                    pPropInfo.SetValue(Me, CType(pAttribute.Value, Boolean), Nothing)
                End Select
                'System.Diagnostics.Debug.WriteLine(pPropInfo.Name & ", " & pPropInfo.GetSetMethod.Name & ", " & pPropInfo.GetHashCode & ", " & (pPropInfo.GetType.Equals(GetType(Integer))) & ", " & pPropInfo.GetType.Name)
              Catch ex As Exception
                'pPropInfo.SetValue(Me, CInt(pAttribute.Value), Nothing)
              End Try
            End If
          Else
            pFieldInfo = Me.GetType.GetField(pAttribute.Name)
            If Not pFieldInfo Is Nothing Then
              Try
                Select Case pFieldInfo.FieldType.Name
                  Case "Object"
                    pType.InvokeMember(pAttribute.Name, BindingFlags.Default Or BindingFlags.SetField, Nothing, Me, strVals, Nothing)
                  Case "String"
                    pFieldInfo.SetValue(Me, CType(pAttribute.Value, String))
                  Case "Int32", "Int16", "Integer", "Int64"
                    pFieldInfo.SetValue(Me, CInt(pAttribute.Value))
                  Case "Single"
                    pFieldInfo.SetValue(Me, CType(pAttribute.Value, Single))
                  Case "Double", "Decimal"
                    pFieldInfo.SetValue(Me, CType(pAttribute.Value, Double))
                  Case "String"
                    pFieldInfo.SetValue(Me, pAttribute.Value)
                  Case "DateTime"
                    pFieldInfo.SetValue(Me, CType(pAttribute.Value, DateTime))
                  Case "Boolean"
                    pFieldInfo.SetValue(Me, CType(pAttribute.Value, Boolean))
                End Select
              Catch ex As Exception

              End Try
            End If
          End If
        Catch ex As Exception
          System.Diagnostics.Debug.WriteLine(ex.ToString)
        End Try
      Next
      Dim oChild As Object
      Dim sName As String
      Dim pMethodInfo As System.Reflection.MethodInfo
      Dim oVals(0) As Object

      For Each pChildNode In pNode.ChildNodes
        Try
          oChild = Activator.CreateInstance(Type.GetType(pChildNode.Name))
        Catch ex As Exception
          oChild = Activator.CreateInstance(Type.GetType(ApSConfigAHS.getAppNameBase() & "." & pChildNode.Name))
        End Try
        Try
          If Not oChild Is Nothing Then
            pMethodInfo = oChild.GetType.GetMethod(_LoadXMLNode)   '  "LoadXMLNode")
            If Not pMethodInfo Is Nothing Then
              oVals(0) = pChildNode
              pMethodInfo.Invoke(oChild, BindingFlags.Instance, Nothing, oVals, Nothing)
              pPropInfo = oChild.GetType.GetProperty(_TagName)
              If pPropInfo Is Nothing Then
                pPropInfo = oChild.GetType.GetProperty(_Name)
              End If
              sName = ""
              If Not pPropInfo Is Nothing Then
                sName = pPropInfo.GetValue(oChild, Nothing)
              End If
              If sName = "" Then
                sName = oChild.GetType.Name
              End If
              Me.Add(sName, oChild)
            End If
          End If
        Catch ex As Exception

        End Try
        'pHISNetwork = New HISNetwork
        'pHISNetwork.LoadXMLNode(pChildNode)
        'Me.Add(pHISNetwork.TagName, pHISNetwork)
      Next
    Catch ex As Exception

    End Try
    Return bOk
  End Function
  Public Function LoadXMLDoc(ByVal pDoc As XmlDocument) As Boolean
    Dim pNode As XmlNode
    Dim s As String
    s = Me.GetType.Name
    pNode = pDoc.SelectSingleNode(s)  '"HISNetworks")
    Return LoadXMLNode(pNode)
  End Function
  Public Function LoadXMLFile(ByVal FileName As String) As Boolean
    Dim pDoc As XmlDocument
    pDoc = New XmlDocument
    pDoc.Load(FileName)
    Return LoadXMLDoc(pDoc)
  End Function
  Public Function LoadXMLString(ByVal strXML As String) As Boolean
    Dim pDoc As XmlDocument
    Dim bOk As Boolean
    Try
      pDoc = New XmlDocument
      pDoc.LoadXml(strXML)
      bOk = LoadXMLDoc(pDoc)
    Catch ex As Exception
      bOk = False
    End Try
    Return bOk
  End Function

  Public Function GetApWebFieldByOrder(ByVal FieldOrder As Integer) As ApWebField
    Dim sKey As String
    Dim pApWebField As ApWebField
    Dim pApWebFieldR As ApWebField = Nothing
    Try
      For Each sKey In Me.Keys
        pApWebField = Me.Item(sKey)
        If FieldOrder = pApWebField.FieldOrder Then
          pApWebFieldR = pApWebField
          Exit For
        End If
      Next
    Catch ex As Exception
      pApWebFieldR = Nothing
    End Try
    Return pApWebFieldR

  End Function
  Public Function GetApWebFieldByName(ByVal sName As String) As ApWebField
    Dim sKey As String
    Dim pApWebField As ApWebField
    Dim pApWebFieldR As ApWebField = Nothing
    Try
      sName = sName.Trim.ToUpper
      For Each sKey In Me.Keys
        pApWebField = Me.Item(sKey)
        If UCase(pApWebField.Name) = sName Then
          pApWebFieldR = pApWebField
          Exit For
        End If
      Next
    Catch ex As Exception
      pApWebFieldR = Nothing
    End Try
    Return pApWebFieldR
  End Function
  Public Function GetApWebFieldByFieldAlias(ByVal sAlias As String) As ApWebField
    Dim sKey As String
    Dim pApWebField As ApWebField
    Dim pApWebFieldR As ApWebField = Nothing
    Try
      sAlias = sAlias.Trim.ToUpper
      For Each sKey In Me.Keys
        pApWebField = Me.Item(sKey)
        If UCase(pApWebField.FieldAlias) = sAlias Then
          pApWebFieldR = pApWebField
          Exit For
        End If
      Next
    Catch ex As Exception
      pApWebFieldR = Nothing
    End Try
    Return pApWebFieldR
  End Function
  Public Sub New()
    MyBase.New()
  End Sub
  Public Sub New(ByVal info As System.Runtime.Serialization.SerializationInfo, ByVal context As System.Runtime.Serialization.StreamingContext)
    MyBase.New(info, context)
  End Sub
End Class