' *
' * The project site is at: http://sourceforge.jp/projects/fishbornas/
' *
' * First author tiritomato 2012.
' *
' * Distributed under the FishbornArchiveShelf License (See
' *  file "Licenses/License.txt" contained in a project, or the following link.
' *  http://sourceforge.jp/projects/fishbornas/scm/svn/blobs/head/trunk/Licenses/License.txt)
' *
' * 2012.06.07 Initial Revision (tiritomato)
' *

Partial Public Class Logic
    Partial Public Class SerializableCollections

        <System.Serializable()> _
        <System.Xml.Serialization.XmlRoot("KeyValueItem")> _
        Public Class KeyValueItem(Of TKey, TValue)
            <System.Xml.Serialization.XmlElement("Key")> _
            Public Key As TKey
            <System.Xml.Serialization.XmlElement("Value")> _
            Public Value As TValue
        End Class

        <Serializable()> _
        Public Class Dictionary(Of TKey, TValue)
            Inherits System.Collections.Generic.Dictionary(Of TKey, TValue)
            Implements Xml.Serialization.IXmlSerializable

            Private Function XmlSerializer() As Xml.Serialization.XmlSerializer
                Return New Xml.Serialization.XmlSerializer(GetType(KeyValueItem(Of TKey, TValue)))
            End Function

            Public Function GetSchema() As System.Xml.Schema.XmlSchema Implements System.Xml.Serialization.IXmlSerializable.GetSchema
                Return Nothing
            End Function

            Public Sub ReadXml(ByVal reader As System.Xml.XmlReader) Implements System.Xml.Serialization.IXmlSerializable.ReadXml

                If reader.IsEmptyElement Then
                    reader.Read() ' skip to next node
                    Exit Sub
                End If

                Dim strElementName As String = reader.Name
                Dim objPresetReader As Xml.Serialization.XmlSerializer = XmlSerializer()
                reader.Read() ' enter node
                While True
                    reader.MoveToContent() ' skip white space
                    Select Case reader.NodeType
                        Case Xml.XmlNodeType.EndElement
                            If reader.Name <> strElementName Then
                                MsgBox("SerializableDictionary XML ReadError:Invalid EndElement <" & reader.Name & "/>")
                            End If
                            reader.Read() ' skip to next node
                            Exit While
                        Case Xml.XmlNodeType.Element
                            If reader.Name <> "KeyValueItem" Then Exit While
                            Dim item As KeyValueItem(Of TKey, TValue) = TryCast(objPresetReader.Deserialize(reader), KeyValueItem(Of TKey, TValue))
                            If Not item Is Nothing Then Me.Add(item.Key, item.Value)
                        Case Xml.XmlNodeType.CDATA
                            reader.Read() ' skip
                    End Select
                End While

            End Sub

            Public Sub WriteXml(ByVal writer As System.Xml.XmlWriter) Implements System.Xml.Serialization.IXmlSerializable.WriteXml

                Dim ns As New Xml.Serialization.XmlSerializerNamespaces
                ns.Add(String.Empty, String.Empty)

                Dim serializer As Xml.Serialization.XmlSerializer = XmlSerializer()
                For Each key In Keys
                    Dim item As New KeyValueItem(Of TKey, TValue)
                    item.Key = key
                    item.Value = Me.Item(key)
                    serializer.Serialize(writer, item, ns)
                Next

            End Sub

        End Class ' Dictionary

    End Class
End Class