
Public Class FormSettings
    Enum ControlTypes As Byte
        FormCtl = 0
        ListBoxCtl = 1
        ComboBoxCtl = 2
        DatetimePickerCtl = 3
        TabControl = 4
        RadioButtonCtl = 5
        CheckBoxCtl = 6
        TextBoxCtl = 7
    End Enum
    'Setting Parameters
    Public FormSize As Boolean = True
    Public FormPosition As Boolean = True
    Public ListBoxes As Boolean = True
    Public ComboBoxes As Boolean = True
    Public DatetimePickers As Boolean = True
    Public TabControls As Boolean = True
    Public RadioButtons As Boolean = True
    Public CheckBoxes As Boolean = True
    Public TextBoxes As Boolean = False
    'Table of the Settings
    Private DTbl As DataTable

    'Public functions to control the class
    Public Sub SaveForm(ByRef Frmx As Form)
        Try
            Dim Newtbl As DataTable = GetNewTable(Frmx)
            'Checking if there is already a settings Dataset
            If Dir(Application.StartupPath & "\Settings.xml") = "" Then
                'create new
                Dim Dataset1 As New DataSet
                dataset1.Tables.Add(Newtbl)
                'Saving to disk
                Dataset1.WriteXml(Application.StartupPath & "\settings.xml", XmlWriteMode.WriteSchema)
            Else
                'Append to exisintg
                Dim Dataset1 As New DataSet, DeleteTable As DataTable
                Dataset1.ReadXml(Application.StartupPath & "\settings.xml")
                For Each tbl As DataTable In Dataset1.Tables
                    If tbl.TableName = Frmx.Name Then
                        DeleteTable = tbl
                        Exit For
                    End If
                Next
                'Removing old Table if found
                If Not IsNothing(DeleteTable) Then
                    Dataset1.Tables.Remove(DeleteTable)
                End If
                'Adding the New Settings Table to the dataset
                Dataset1.Tables.Add(Newtbl)
                'Writing it to desk
                Dataset1.WriteXml(Application.StartupPath & "\settings.xml", XmlWriteMode.WriteSchema)
            End If
        Catch ex As Exception
            LogError(ex.ToString)
        End Try
    End Sub

    'Load settings into the form
    Public Sub LoadtoForm(ByRef Frmx As Form)
        Dim dataset1 As New DataSet
        Try
            If Dir(Application.StartupPath & "\settings.xml") = "" Then Exit Sub
            'Reading from Xml File
            dataset1.ReadXml(Application.StartupPath & "\settings.xml")
            'Looking Table
            For Each tbl As DataTable In dataset1.Tables
                If tbl.TableName = Frmx.Name Then
                    loadsettingstoForm(tbl, Frmx)
                    Exit Sub
                End If
            Next
        Catch ex As Exception
            LogError(ex.ToString)
        Finally
            dataset1.Dispose()
        End Try
    End Sub



    'Transferrings Settings from Tbl to Form
    Private Sub loadsettingstoForm(ByVal tbl As DataTable, ByVal Frmx As Form)
        DTbl = tbl
        'basic form size
        If FormSize Then
            With Frmx
                .WindowState = Getvalue(ControlTypes.FormCtl, Frmx.Name, "windowstate")
                .Width = CInt(Getvalue(ControlTypes.FormCtl, Frmx.Name, "width"))
                .Height = CInt(Getvalue(ControlTypes.FormCtl, Frmx.Name, "height"))
            End With
        End If
        'Basic Form POS
        If FormPosition Then
            With Frmx
                .Left = Getvalue(ControlTypes.FormCtl, Frmx.Name, "left")
                .Top = Getvalue(ControlTypes.FormCtl, Frmx.Name, "top")
            End With
        End If
        'Processing Form Elements
        UnProcess(Frmx)
    End Sub
    'Function To UnParse down controls
    Private Function UnProcess(ByVal outerctl As Control)
        For Each ctl As Control In outerctl.Controls
            If ctl.Tag <> "dontsave" Then
                'Analyze the control itself
                UnAnalyze(ctl)
                'Process it's inner controls if found
                If ctl.HasChildren Then
                    UnProcess(ctl)
                End If
            End If
        Next
    End Function

    'Analyze down a single control 
    Private Sub UnAnalyze(ByVal ctl As Control)
        'On Error Resume Next
        'listbox
        If ListBoxes And GetType(ListBox).IsInstanceOfType(ctl) Then
            CType(ctl, ListBox).SelectedIndex = Getvalue(ControlTypes.ListBoxCtl, ctl.Name, "selectedindex")
            Exit Sub
        End If
        'Comboboxes
        If ComboBoxes And GetType(ComboBox).IsInstanceOfType(ctl) Then
            CType(ctl, ComboBox).SelectedIndex = Getvalue(ControlTypes.ComboBoxCtl, ctl.Name, "selectedindex")
            Exit Sub
        End If

        'Date time picker
        If DatetimePickers And GetType(DateTimePicker).IsInstanceOfType(ctl) Then
            CType(ctl, DateTimePicker).Value = CDate(Getvalue(ControlTypes.DatetimePickerCtl, ctl.Name, "value")).ToShortDateString
            CType(ctl, DateTimePicker).Checked = Getvalue(ControlTypes.DatetimePickerCtl, ctl.Name, "checked")
            Exit Sub
        End If
        'Tab Controls
        If TabControls And GetType(TabControl).IsInstanceOfType(ctl) Then
            CType(ctl, TabControl).SelectedIndex = Getvalue(ControlTypes.TabControl, ctl.Name, "selectedindex")
            Exit Sub
        End If
        'radio buttons
        If RadioButtons And GetType(RadioButton).IsInstanceOfType(ctl) Then
            CType(ctl, RadioButton).Checked = Getvalue(ControlTypes.RadioButtonCtl, ctl.Name, "checked")
            Exit Sub
        End If
        'CheckBoxes 
        If CheckBoxes And GetType(CheckBox).IsInstanceOfType(ctl) Then
            CType(ctl, CheckBox).Checked = Getvalue(ControlTypes.CheckBoxCtl, ctl.Name, "checked")
            Exit Sub
        End If
        'Textboxes
        If TextBoxes And GetType(TextBox).IsInstanceOfType(ctl) Then
            ctl.Text = Getvalue(ControlTypes.TextBoxCtl, ctl.Name, "text")
            Exit Sub
        End If
    End Sub

    'Locking on Value
    Private Function Getvalue(ByVal ControlType As ControlTypes, ByVal objectname As String, ByVal propertyname As String) As String
        Dim Result As String = ""
        Dim Dview As New DataView(DTbl)
        Try

            Dview.RowFilter = "controlType = " & ControlType & " and controlname = '" & objectname & "' and propertyname = '" & propertyname & "'"
            Result = Dview(0)!valuestr
        Catch ex As Exception
            LogError(ex.ToString)
        Finally
            Dview.Dispose()
        End Try
        Return Result
    End Function

    'Create a settings table on the name of form
    Private Function GetNewTable(ByRef Frmx As Form) As DataTable
        Dim Tbl As New DataTable(Frmx.Name)
        'adding columns
        Tbl.Columns.Add("controltype", GetType(Byte))
        Tbl.Columns.Add("ControlName", GetType(String))
        Tbl.Columns.Add("PropertyName", GetType(String))
        Tbl.Columns.Add("ValueStr", GetType(String))
        'Setting the major table inside the class
        DTbl = Tbl
        'Filling table with Settings
        TransferSettings(Frmx, Tbl)
        'returning result
        Return DTbl
    End Function
    'Function to read settings from form and serialize them into tbl
    Private Sub TransferSettings(ByRef FromForm As Form, ByRef Tbl As DataTable)
        '''Form Size Settings
        If FormSize Then
            Add(ControlTypes.FormCtl, FromForm.Name, "windowstate", FromForm.WindowState)
            Add(ControlTypes.FormCtl, FromForm.Name, "width", FromForm.Width)
            Add(ControlTypes.FormCtl, FromForm.Name, "height", FromForm.Height)
        End If
        '''Form Position Settings
        If FormPosition Then
            Add(ControlTypes.FormCtl, FromForm.Name, "left", FromForm.Left)
            Add(ControlTypes.FormCtl, FromForm.Name, "top", FromForm.Top)
        End If
        '''Loop Controls    (Recursive Loop)
        Process(FromForm)
    End Sub
    'Function to add new Setting row inside the Dtbl
    Private Sub Add(ByVal Controltype As ControlTypes, ByVal controlName As String, ByVal Propertyname As String, ByVal Valuestr As String)
        Try
            Dim Newrow As DataRow = DTbl.NewRow
            With Newrow
                !controltype = Controltype
                !controlname = controlName
                !propertyname = Propertyname
                !valuestr = Valuestr
            End With
            DTbl.Rows.Add(Newrow)
        Catch ex As Exception
            LogError(ex.ToString)
        End Try
    End Sub
    'Function To Parse down controls
    Private Function Process(ByVal outerctl As Control)
        For Each ctl As Control In outerctl.Controls
            If ctl.Tag <> "dontsave" Then
                'Analyze the control itself
                Analyze(ctl)
                'Process it's inner controls if found
                If ctl.HasChildren Then
                    Process(ctl)
                End If
            End If
        Next
    End Function
    'Analyze down a single control 
    Private Sub Analyze(ByVal ctl As Control)
        'listbox
        If ListBoxes And GetType(ListBox).IsInstanceOfType(ctl) Then
            Add(ControlTypes.ListBoxCtl, ctl.Name, "selectedindex", CType(ctl, ListBox).SelectedIndex)
            Exit Sub
        End If
        'Comboboxes
        If ComboBoxes And GetType(ComboBox).IsInstanceOfType(ctl) Then
            Add(ControlTypes.ComboBoxCtl, ctl.Name, "selectedindex", CType(ctl, ComboBox).SelectedIndex)
            Exit Sub
        End If

        'Date time picker
        If DatetimePickers And GetType(DateTimePicker).IsInstanceOfType(ctl) Then
            Add(ControlTypes.DatetimePickerCtl, ctl.Name, "value", CType(ctl, DateTimePicker).Value.ToShortDateString)
            Add(ControlTypes.DatetimePickerCtl, ctl.Name, "checked", CType(ctl, DateTimePicker).Checked)
            Exit Sub
        End If
        'Tab Controls
        If TabControls And GetType(TabControl).IsInstanceOfType(ctl) Then
            Add(ControlTypes.TabControl, ctl.Name, "selectedindex", CType(ctl, TabControl).SelectedIndex)
            Exit Sub
        End If
        'radio buttons
        If RadioButtons And GetType(RadioButton).IsInstanceOfType(ctl) Then
            Add(ControlTypes.RadioButtonCtl, ctl.Name, "checked", CType(ctl, RadioButton).Checked)
            Exit Sub
        End If
        'CheckBoxes 
        If CheckBoxes And GetType(CheckBox).IsInstanceOfType(ctl) Then
            Add(ControlTypes.CheckBoxCtl, ctl.Name, "checked", CType(ctl, CheckBox).Checked)
            Exit Sub
        End If
        'Textboxes
        If TextBoxes And GetType(TextBox).IsInstanceOfType(ctl) Then
            Add(ControlTypes.TextBoxCtl, ctl.Name, "text", ctl.Text)
            Exit Sub
        End If
    End Sub

End Class
