Public Class Form1

    Enum SCH_LineFields
        TYPE = 0
        NAME = 1
        DESCR_0 = 2
        DESCR_1 = 3
        ASSOC = 4
        NET = 5
        DEVICE = 6
        INSTANCE = 7

    End Enum
    Enum CAL_LineFields
        TYPE = 0
        NAME = 1
        DESCR_0 = 2
        DESCR_1 = 3
        NET = 4
        DEVICE = 5
        INSTANCE = 6

    End Enum
    Enum Branch_LineFields
        BRANCH = 1
        INSTANCE = 4
        NAME = 5
    End Enum

    Private dic_Devices As New Dictionary(Of String, Device)
    Public xdoc As New Xml.XmlDocument

    Private Sub btn_OpenFile_Click(sender As Object, e As EventArgs) Handles btn_OpenFile.Click

        dlg_OpenFile.FileName = "Schedules.dat"
        Dim ret As DialogResult = dlg_OpenFile.ShowDialog()

        If ret = DialogResult.OK Then
            tbx_Path.Text = dlg_OpenFile.FileName
        End If


    End Sub

    Private Sub btn_Start_Click(sender As Object, e As EventArgs) Handles btn_Start.Click

        Dim r As System.IO.StreamReader
        Dim sTmp() As String
        Dim sKey As String

        dic_Devices.Clear()


        ' First Step - Browse the schedules.dat and store data
        r = My.Computer.FileSystem.OpenTextFileReader(tbx_Path.Text)
        Do While r.EndOfStream = False
            sTmp = Split(r.ReadLine, ",")
            Select Case sTmp(SCH_LineFields.TYPE)
                Case "BACSCHED"
                    If rb_All.Checked Or rb_Schedules.Checked Then
                        Dim d As New Device()
                        d.Net = sTmp(SCH_LineFields.NET)
                        d.Device = sTmp(SCH_LineFields.DEVICE)
                        d.AddSchedule(sTmp(SCH_LineFields.NAME), sTmp(SCH_LineFields.DESCR_0), sTmp(SCH_LineFields.INSTANCE), sTmp(SCH_LineFields.ASSOC))

                        sKey = sTmp(SCH_LineFields.NET) & "." & sTmp(SCH_LineFields.DEVICE)
                        If dic_Devices.ContainsKey(sKey) = False Then    'If this device is read for the first time
                            dic_Devices.Add(sTmp(SCH_LineFields.NET) & "." & sTmp(SCH_LineFields.DEVICE), d)
                        Else
                            dic_Devices.Item(sKey).AddSchedule(sTmp(SCH_LineFields.NAME), sTmp(SCH_LineFields.DESCR_0), sTmp(SCH_LineFields.INSTANCE), sTmp(SCH_LineFields.ASSOC))
                        End If
                    End If

                Case "BACCAL"
                    If rb_All.Checked Or rb_Calendars.Checked Then
                        Dim d As New Device()
                        d.Net = sTmp(CAL_LineFields.NET)
                        d.Device = sTmp(CAL_LineFields.DEVICE)
                        d.AddCalendar(sTmp(CAL_LineFields.NAME), sTmp(CAL_LineFields.DESCR_0), sTmp(CAL_LineFields.INSTANCE))

                        sKey = sTmp(CAL_LineFields.NET) & "." & sTmp(CAL_LineFields.DEVICE)
                        If dic_Devices.ContainsKey(sKey) = False Then    'If this device is read for the first time
                            dic_Devices.Add(sTmp(CAL_LineFields.NET) & "." & sTmp(CAL_LineFields.DEVICE), d)
                        Else
                            dic_Devices.Item(sKey).AddCalendar(sTmp(CAL_LineFields.NAME), sTmp(CAL_LineFields.DESCR_0), sTmp(CAL_LineFields.INSTANCE))
                        End If
                    End If

            End Select
        Loop
        r.Close()

        'Second step - Browse Schedules.txt (For Azbil projects only)
        Dim xSch As Xml.XmlNode

        If chk_AzbilMigration.Checked Then
            r = My.Computer.FileSystem.OpenTextFileReader(tbx_AzbilFilePath.Text)
            r.ReadLine()  'Skip the first line (Header)
            Do While r.EndOfStream = False
                sTmp = Split(r.ReadLine, ",")
                xSch = GetSchedule(sTmp(Branch_LineFields.INSTANCE), sTmp(Branch_LineFields.NAME))
                If xSch.Name <> "NULL" Then
                    xSch.Attributes("id").Value = sTmp(Branch_LineFields.BRANCH) & "." & xSch.Attributes("id").Value & ".Schedule"
                Else
                    rtb_Logs.AppendText("Branch not found for: " & sTmp(Branch_LineFields.NAME) & " - Instance: " & sTmp(Branch_LineFields.INSTANCE) & vbNewLine)
                    Console.WriteLine("Branch not found for: " & sTmp(Branch_LineFields.NAME) & " - Instance: " & sTmp(Branch_LineFields.INSTANCE))
                End If
            Loop
            r.Close()
        End If


        'Third Step - Write XML file

        Dim xColl As Xml.XmlNode
        Dim xAtt As Xml.XmlAttribute

        xdoc.LoadXml("<Import><Group> customRef='Communication'</Group></Import>")
        'Browse Devices dictionnary. For each device get all schedules and put in xmldoc
        For Each dev As KeyValuePair(Of String, Device) In dic_Devices
            'Create BACnetSchedules collection
            xColl = xdoc.DocumentElement.ChildNodes(0).AppendChild(xdoc.CreateElement("Collection"))
            xAtt = xColl.Attributes.Append(xdoc.CreateAttribute("type"))
            xAtt.Value = "BACnetSchedules"
            xAtt = xColl.Attributes.Append(xdoc.CreateAttribute("id"))
            xAtt.Value = dev.Key


            'For Each schedule of the device add the xml node in xmldoc
            For Each sch As KeyValuePair(Of String, Xml.XmlNode) In dev.Value.Schedules

                xColl.AppendChild(sch.Value)

            Next

            'Create BACnetCalendars collection
            xColl = xdoc.DocumentElement.ChildNodes(0).AppendChild(xdoc.CreateElement("Collection"))
            xAtt = xColl.Attributes.Append(xdoc.CreateAttribute("type"))
            xAtt.Value = "BACnetCalendars"
            xAtt = xColl.Attributes.Append(xdoc.CreateAttribute("id"))
            xAtt.Value = dev.Key

            'For Each calendar of the device add the xml node in xmldoc
            For Each sch As KeyValuePair(Of String, Xml.XmlNode) In dev.Value.Calendars

                xColl.AppendChild(sch.Value)

            Next

        Next
        'Save in same folder than schedules.dat
        xdoc.Save(My.Computer.FileSystem.GetFileInfo(tbx_Path.Text).DirectoryName & "\Schedules.xml")

    End Sub

    Private Function GetSchedule(sInstance As String, sName As String) As Xml.XmlNode

        Dim xSch As Xml.XmlNode

        For Each kvDev As KeyValuePair(Of String, Device) In dic_Devices

            For Each kvSch As KeyValuePair(Of String, Xml.XmlNode) In kvDev.Value.Schedules
                If kvSch.Key = sInstance And kvSch.Value.Attributes("id").Value = sName Then
                    Return (kvSch.Value)
                End If
            Next

        Next
        xSch = xdoc.CreateElement("NULL")
        Return (xSch)

    End Function
    Private Sub chk_AzbilMigration_CheckedChanged(sender As Object, e As EventArgs) Handles chk_AzbilMigration.CheckedChanged

        tbx_AzbilFilePath.Visible = chk_AzbilMigration.Checked
        btn_AzbilOpenFile.Visible = chk_AzbilMigration.Checked

    End Sub

    Private Sub btn_AzbilOpenFile_Click(sender As Object, e As EventArgs) Handles btn_AzbilOpenFile.Click

        dlg_OpenFile.FileName = "Schedules.txt"
        Dim ret As DialogResult = dlg_OpenFile.ShowDialog()

        If ret = DialogResult.OK Then
            tbx_AzbilFilePath.Text = dlg_OpenFile.FileName
        End If


    End Sub
End Class
