Imports System.Collections.ObjectModel
Imports EgtUILib
Imports EgtWPFLib5
Imports EgtBEAMWALL.Core

Public Class ConfigurationPageVM
   Inherits VMBase

   Public Enum ConfigSubPages As Integer
      GENERAL = 0
      MACHINE = 1
      VARIABLE = 2
   End Enum

   Private m_SelConfigSubPage As ConfigSubPages = ConfigSubPages.GENERAL
   Public Property SelConfigSubPage As Integer
      Get
         Return m_SelConfigSubPage
      End Get
      Set(value As Integer)
         m_SelConfigSubPage = value
         If m_SelConfigSubPage = ConfigSubPages.GENERAL Then
            SetGeneral_Visibility(Visibility.Visible)
         ElseIf m_SelConfigSubPage = ConfigSubPages.MACHINE Then
            SetGeneral_Visibility(Visibility.Collapsed)
         End If
      End Set
   End Property

   Public ReadOnly Property MachinePanelVM As MachinePanelVM
      Get
         Return Map.refMachinePanelVM
      End Get
   End Property


   ' Contatore delle variabili rimosse per successiva rimozione dal file INI
   Friend m_RemovedVarsCount As Integer = 0

   Private m_LanguageList As New ObservableCollection(Of Language)
   Public ReadOnly Property LanguageList As ObservableCollection(Of Language)
      Get
         Return m_LanguageList
      End Get
   End Property

   Private m_UnitMeasureList As List(Of String) = New List(Of String)({"inch", "mm"})
   Public ReadOnly Property UnitMeasureList As List(Of String)
      Get
         Return m_UnitMeasureList
      End Get
   End Property

   Private m_SelectedLanguage As Language
   Public Property SelectedLanguage As Language
      Get
         Return m_SelectedLanguage
      End Get
      Set(value As Language)
         If value IsNot m_SelectedLanguage Then
            m_SelectedLanguage = value
         End If
      End Set
   End Property

   Public Property SelMeasureUnit As Integer
      Get
         Return If(EgtUiUnitsAreMM(), MeasureUnitOpt.MM, MeasureUnitOpt.INCH)
      End Get
      Set(value As Integer)
         ' salvo unità di misura precedente
         Dim PrevMeasureUnit As MeasureUnitOpt = If(EgtUiUnitsAreMM(), MeasureUnitOpt.MM, MeasureUnitOpt.INCH)
         If value <> PrevMeasureUnit Then
            ' cambio unità di misura
            EgtSetUiUnits(DirectCast(value, MeasureUnitOpt) = MeasureUnitOpt.MM)
         End If
      End Set
   End Property

   Protected m_VariablesColumns As New ObservableCollection(Of EgtDataGridColumn)
   Public Property VariablesColumns As ObservableCollection(Of EgtDataGridColumn)
      Get
         Return m_VariablesColumns
      End Get
      Set(value As ObservableCollection(Of EgtDataGridColumn))
         m_VariablesColumns = value
      End Set
   End Property

   Private m_VariablesList As New ObservableCollection(Of ConfigVariable)
   Public Property VariablesList As ObservableCollection(Of ConfigVariable)
      Get
         Return m_VariablesList
      End Get
      Set(value As ObservableCollection(Of ConfigVariable))
         m_VariablesList = value
      End Set
   End Property

   Private m_SelVariable As ConfigVariable
   Public Property SelVariable As ConfigVariable
      Get
         Return m_SelVariable
      End Get
      Set(value As ConfigVariable)
         m_SelVariable = value
      End Set
   End Property

   Private m_bGeneral_Visibility As Visibility = Visibility.Visible
   Public ReadOnly Property General_Visibility As Visibility
      Get
         Return m_bGeneral_Visibility
      End Get
   End Property
   Friend Sub SetGeneral_Visibility(value As Visibility)
      m_bGeneral_Visibility = value
      NotifyPropertyChanged(NameOf(General_Visibility))
   End Sub

   Private m_bMachine_Visibility As Visibility = Visibility.Collapsed
   Public ReadOnly Property Machine_Visibility As Visibility
      Get
         Return m_bMachine_Visibility
      End Get
   End Property
   Friend Sub SetMachine_Visibility(value As Visibility)
      m_bMachine_Visibility = value
      NotifyPropertyChanged(NameOf(Machine_Visibility))
   End Sub

   Private m_SectionTime As Double
   Public Property SectionTime As String
      Get
         Return DoubleToString(m_SectionTime, 5)
      End Get
      Set(value As String)
         Dim dVal As Double = 0
         If StringToDoubleAdv(value, dVal, True) AndAlso dVal > 0 Then
            m_SectionTime = dVal
         End If
      End Set
   End Property

   Private m_PartTime As Double
   Public Property PartTime As String
      Get
         Return DoubleToString(m_PartTime, 5)
      End Get
      Set(value As String)
         Dim dVal As Double = 0
         If StringToDoubleAdv(value, dVal, True) AndAlso dVal > 0 Then
            m_PartTime = dVal
         End If
      End Set
   End Property

   Private m_ReminderList As New List(Of IdNameStruct)({New IdNameStruct(0, EgtMsg(61988)), New IdNameStruct(1, EgtMsg(61989)), New IdNameStruct(2, EgtMsg(61990)), New IdNameStruct(7, EgtMsg(61991)), New IdNameStruct(14, EgtMsg(61992)), New IdNameStruct(30, EgtMsg(61993))})
   Public ReadOnly Property ReminderList As List(Of IdNameStruct)
      Get
         Return m_ReminderList
      End Get
   End Property

   Private m_SelReminder As IdNameStruct
   Public Property SelReminder As IdNameStruct
      Get
         Return m_SelReminder
      End Get
      Set(value As IdNameStruct)
         m_SelReminder = value
         WriteMainPrivateProfileString(S_BACKUPANDRESTORE, K_REMINDERFREQUENCY, m_SelReminder.Id)
      End Set
   End Property

   Private m_ConfigMachTableList As New ObservableCollection(Of MachTable)
   Public Property ConfigMachTableList As ObservableCollection(Of MachTable)
      Get
         Return m_ConfigMachTableList
      End Get
      Set(value As ObservableCollection(Of MachTable))
         m_ConfigMachTableList = value
      End Set
   End Property

   Friend m_MachineParameter_Visibility As Visibility = Visibility.Collapsed
   Public ReadOnly Property MachineParameter_Visibility As Visibility
      Get
         Return m_MachineParameter_Visibility
      End Get
   End Property
   Friend Sub SetMachineParameter_Visibility(value As Visibility)
      m_MachineParameter_Visibility = value
      NotifyPropertyChanged(NameOf(MachineParameter_Visibility))
   End Sub

   ' Definizione comandi
   Private m_cmdSave As ICommand
   Private m_cmdAddVariable As ICommand
   Private m_cmdRemoveVariable As ICommand

#Region "Messages"

   Public ReadOnly Property L_Msg As String
      Get
         Return EgtMsg(61803)
      End Get
   End Property

   Public ReadOnly Property T_Msg As String
      Get
         Return EgtMsg(61804)
      End Get
   End Property

   Public ReadOnly Property PRC_Msg As String
      Get
         Return EgtMsg(61805)
      End Get
   End Property

   Public ReadOnly Property NAM_Msg As String
      Get
         Return EgtMsg(61608)
      End Get
   End Property

   Public ReadOnly Property Description_Msg As String
      Get
         Return EgtMsg(61603)
      End Get
   End Property

   Public ReadOnly Property Default_Msg As String
      Get
         Return EgtMsg(61802)
      End Get
   End Property

   Public ReadOnly Property Min_Msg As String
      Get
         Return EgtMsg(61616)
      End Get
   End Property
   Public ReadOnly Property Max_Msg As String
      Get
         Return EgtMsg(61617)
      End Get
   End Property
   Public ReadOnly Property CurrentLanguage_Msg As String
      Get
         Return EgtMsg(6501)
      End Get
   End Property
   Public ReadOnly Property LanguageAdvert_Msg As String
      Get
         Return EgtMsg(6502)
      End Get
   End Property
   Public ReadOnly Property MMUnits_Msg As String
      Get
         Return EgtMsg(6540)
      End Get
   End Property

   Public ReadOnly Property DisplayIndex_Msg As String
      Get
         Return EgtMsg(61842)
      End Get
   End Property

   Public ReadOnly Property ColumnName_Msg As String
      Get
         Return EgtMsg(61843)
      End Get
   End Property

   Public ReadOnly Property CanUserReorder_Msg As String
      Get
         Return EgtMsg(61844)
      End Get
   End Property

   Public ReadOnly Property CanUserResize_Msg As String
      Get
         Return EgtMsg(61845)
      End Get
   End Property

   Public ReadOnly Property CanUserSort_Msg As String
      Get
         Return EgtMsg(61846)
      End Get
   End Property

   Public ReadOnly Property IsReadOnly_Msg As String
      Get
         Return EgtMsg(61847)
      End Get
   End Property

   Public ReadOnly Property Visible_Msg As String
      Get
         Return EgtMsg(61848)
      End Get
   End Property

   Public ReadOnly Property Name_Msg As String
      Get
         Return EgtMsg(61808)
      End Get
   End Property

   Public ReadOnly Property VarPath_Msg As String
      Get
         Return EgtMsg(61849)
      End Get
   End Property

   Public ReadOnly Property Type_Msg As String
      Get
         Return EgtMsg(61850)
      End Get
   End Property

   Public ReadOnly Property General_Msg As String
      Get
         Return EgtMsg(62535)
      End Get
   End Property

   Public ReadOnly Property Machine_Msg As String
      Get
         Return EgtMsg(62537)
      End Get
   End Property

   Public ReadOnly Property SectionTime_Msg As String
      Get
         Return EgtMsg(61806)
      End Get
   End Property
   Public ReadOnly Property PartTime_Msg As String
      Get
         Return EgtMsg(61807)
      End Get
   End Property

   Public ReadOnly Property Nesting_Msg As String
      Get
         Return EgtMsg(61829)
      End Get
   End Property

   Public ReadOnly Property PrintLabel_Msg As String
      Get
         Return EgtMsg(61894)
      End Get
   End Property

#End Region    ' Messages

#Region "Constructor"

   Sub New()
      ' imposto riferimento in Map
      Map.SetRefConfigurationPageVM(Me)
      ' Leggo nome lingua corrente
      Dim sLanguage As String = String.Empty
      GetMainPrivateProfileString(S_GENERAL, K_MESSAGES, "", sLanguage)
      ' Leggo elenco lingue disponibili da file ini e imposto lingua corrente
      Dim nIndex As Integer = 1
      While True
         Dim ReadLanguage As Language = GetMainPrivateProfileLanguage(S_LANGUAGES, K_LANGUAGE & nIndex)
         If IsNothing(ReadLanguage) Then Exit While
         m_LanguageList.Add(ReadLanguage)
         If String.Compare(ReadLanguage.Name, sLanguage, True) = 0 Then
            m_SelectedLanguage = ReadLanguage
         End If
         nIndex += 1
      End While
      ' Inizializzo la lingua corrente
      m_SelectedLanguage = m_LanguageList(0)
      Dim sMsgName As String = String.Empty
      IniFile.GetMainPrivateProfileString(S_GENERAL, K_MESSAGES, "", sMsgName)
      For Each Language In m_LanguageList
         If Language.Name = sMsgName Then
            m_SelectedLanguage = Language
            Exit For
         End If
      Next
      ' carico la lista delle colonne delle variabili della macchina in ConfigurationPage
      GetPrivateProfileColumns(S_VARIABLESLIST, VariablesColumns)
      ' carico le Variables della macchina
      LoadVariables()
      ' leggo SectionTime e PartTime
      GetMainPrivateProfileString(S_NEST, K_SECTIONTIME, "", SectionTime)
      GetMainPrivateProfileString(S_NEST, K_PARTTIME, "", PartTime)
      ' assegno le liste dei parametri della macchina corrente alla ConfigMachTableList alla pagina di Configurazione
      ConfigMachTableList = CurrentMachine.MachTableList
      Dim nDefaultReminderFrequency As Integer = GetMainPrivateProfileInt(S_BACKUPANDRESTORE, K_REMINDERFREQUENCY, 1)
      SelReminder = m_ReminderList.FirstOrDefault(Function(x) x.Id = nDefaultReminderFrequency)
      ' rendo invisibile la sezione Offset presente nel tab Macchine
      SetMachineParameter_Visibility(Visibility.Collapsed)
      SetMachine_Visibility(Visibility.Collapsed)
   End Sub

#End Region ' Constructor

#Region "SaveCommand"

   ''' <summary>
   ''' Returns a command that do Save.
   ''' </summary>
   Public ReadOnly Property SaveCommand As ICommand
      Get
         If m_cmdSave Is Nothing Then
            m_cmdSave = New Command(AddressOf Save)
         End If
         Return m_cmdSave
      End Get
   End Property

   ''' <summary>
   ''' Execute the Save.  This method is invoked by the SaveCommand.
   ''' </summary>
   Public Sub Save()
      WriteVariables()
      WriteMainPrivateProfileString(S_GENERAL, K_MESSAGES, m_SelectedLanguage.Name)
      WriteMainPrivateProfileString(S_SCENE, K_MMUNITS, SelMeasureUnit.ToString())
   End Sub

#End Region ' SaveCommand

#Region "AddVariable"

   Public ReadOnly Property AddVariable_Command As ICommand
      Get
         If m_cmdAddVariable Is Nothing Then
            m_cmdAddVariable = New Command(AddressOf AddVariable)
         End If
         Return m_cmdAddVariable
      End Get
   End Property

   Public Sub AddVariable()
      VariablesList.Add(New ConfigVariable("[Name]", "[VariablePath]", "plc"))
   End Sub

#End Region ' AddVariable

#Region "RemoveVariable"

   Public ReadOnly Property RemoveVariable_Command As ICommand
      Get
         If m_cmdRemoveVariable Is Nothing Then
            m_cmdRemoveVariable = New Command(AddressOf RemoveVariable)
         End If
         Return m_cmdRemoveVariable
      End Get
   End Property

   Public Sub RemoveVariable()
      VariablesList.Remove(SelVariable)
      m_RemovedVarsCount += 1
   End Sub

#End Region ' RemoveVariable

#Region "Methods"

   ' funzione che verifica la modifica dei valori in Configurazione e ne chiede il salvataggio
   Friend Sub VerifyConfigPageModification()
      ' qui veniva verificata solamente la modifica delle proprietà delle colonne delle EgtDataGrid

   End Sub

   ' funzione che legge le variabili della macchina dall'INI
   Public Sub LoadVariables()
      VariablesList = New ObservableCollection(Of ConfigVariable)
      Dim VarIndex As Integer = 1
      Dim sValue As String = Nothing
      While EgtUILib.GetPrivateProfileString(S_VARIABLES, VarIndex, String.Empty, sValue, CurrentMachine.sMachIniFile)
         Dim sVariableValues() As String = sValue.Split(","c)
         ' verifico numero minimo di parametri
         If sVariableValues.Count >= 4 Then
            ' cancello spazi
            For Index = 0 To sVariableValues.Count - 1
               sVariableValues(Index) = sVariableValues(Index).Trim()
            Next
            ' creo parametro
            Dim sName As String = sVariableValues(0)
            Dim sVarPath As String = sVariableValues(1)
            Dim sType As String = sVariableValues(3)
            VariablesList.Add(New ConfigVariable(sName, sVarPath, sType))
         End If
         VarIndex += 1
      End While
   End Sub

   ' funzione che scrive i valori delle variabili della macchina nell'INI
   Public Sub WriteVariables()
      Dim VarIndex = 1
      For Each VarItem In VariablesList
         Dim VarStr As String = VarItem.sName & ", " & VarItem.sVarPath & ",  c, " & VarItem.SelType
         WritePrivateProfileString(S_VARIABLES, VarIndex, VarStr, CurrentMachine.sMachIniFile)
         VarIndex += 1
      Next
      ' Se ci sono variabili da rimuovere le rimuovo
      For Index = VarIndex To VarIndex + m_RemovedVarsCount
         WritePrivateProfileString(S_VARIABLES, Index, Nothing, CurrentMachine.sMachIniFile)
      Next
   End Sub

#End Region ' Methods

End Class

Public Class ConfigVariable

   Private m_sName As String
   Public Property sName As String
      Get
         Return m_sName
      End Get
      Set(value As String)
         m_sName = value
      End Set
   End Property

   Private m_sVarPath As String
   Public Property sVarPath As String
      Get
         Return m_sVarPath
      End Get
      Set(value As String)
         m_sVarPath = value
      End Set
   End Property

   Private m_SelType As String
   Public Property SelType As String
      Get
         Return m_SelType
      End Get
      Set(value As String)
         m_SelType = value
      End Set
   End Property

   Private m_TypeList As New ObservableCollection(Of String)({"plc", "cn"})
   Public Property TypeList As ObservableCollection(Of String)
      Get
         Return m_TypeList
      End Get
      Set(value As ObservableCollection(Of String))
         m_TypeList = value
      End Set
   End Property

   Sub New(Name As String, VarPath As String, Type As String)
      m_sName = Name
      m_sVarPath = VarPath
      m_SelType = TypeList.FirstOrDefault(Function(x) x = Type)
   End Sub

End Class

Public Class MachParam
   Inherits VMBase

   ' table a cui appartiene il parametro
   Private m_nParentTable As Integer
   Friend ReadOnly Property nParentTable As Integer
      Get
         Return m_nParentTable
      End Get
   End Property

   ' indice del parametro
   Private m_nParamIndex As Integer
   Friend ReadOnly Property nParamIndex As Integer
      Get
         Return m_nParamIndex
      End Get
   End Property

   ' tipo della variabile
   Private m_nType As MachParamType
   Friend ReadOnly Property nType As MachParamType
      Get
         Return m_nType
      End Get
   End Property

   ' parametri da struttura
   Private m_sName As String
   Public Property sName As String
      Get
         Return m_sName
      End Get
      Set(value As String)
         m_sName = value
      End Set
   End Property

   ' parametri da geometria
   Private m_IsModifiedValue As Boolean = False
   Private m_dValue As Double
   Private m_sValue As String
   Public Property sValue As String
      Get
         Select Case nType
            Case MachParamType.DOUBLE_
               Return DoubleToString(m_dValue, 3)
            Case MachParamType.LENGTH
               Return LenToString(m_dValue, 3)
            Case Else      ' stringhe
               Return m_sValue
         End Select
         Return If(nType = MachParamType.LENGTH, LenToString(m_dValue, 3), DoubleToString(m_dValue, 3))
      End Get
      Set(value As String)
         Dim dNewValue As Double
         ' verifico se valore immesso è diverso dall'originale
         If nParentTable > 0 Then
            ' trasformo valori
            Select Case nType
               Case MachParamType.DOUBLE_
                  StringToDoubleAdv(value, dNewValue, True)
                  m_IsModifiedValue = Math.Abs(dNewValue - m_dValue) > EPS_SMALL
               Case MachParamType.LENGTH
                  StringToLenAdv(value, dNewValue, True)
                  m_IsModifiedValue = Math.Abs(dNewValue - m_dValue) > EPS_SMALL
               Case Else
                  m_IsModifiedValue = String.Compare(value, m_sValue) <> 0
            End Select
         End If
         Select Case nType
            Case MachParamType.DOUBLE_, MachParamType.LENGTH
               UpdateParamValue(dNewValue, "")
            Case Else
               UpdateParamValue(0, value)
         End Select
      End Set
   End Property
   Public Property dValue As Double
      Get
         Return m_dValue
      End Get
      Set(value As Double)
         m_dValue = value
         NotifyPropertyChanged(NameOf(sValue))
      End Set
   End Property

   ' descrizione del parametro
   Private m_sDescription As String
   Public Property sDescription As String
      Get
         Return m_sDescription
      End Get
      Set(value As String)
         m_sDescription = value
      End Set
   End Property

   Private Sub StdInit(nParentTable As Integer, nParamIndex As Integer, Type As MachParamType, sName As String, sDescription As String)
      m_nParentTable = nParentTable
      m_nParamIndex = nParamIndex
      m_nType = Type
      m_sName = sName
      m_sDescription = MsgToString(sDescription)
   End Sub

   ' new per double e length
   Sub New(nParentTable As Integer, nParamIndex As Integer, nType As MachParamType, sParamName As String, dValue As Double, sDescription As String)
      StdInit(nParentTable, nParamIndex, nType, sParamName, sDescription)
      m_dValue = dValue 'sValue = DoubleToString(dValue, 3)
   End Sub

   ' new per stringhe
   Sub New(nParentTable As Integer, nParamIndex As Integer, nType As MachParamType, sParamName As String, sDescription As String)
      StdInit(nParentTable, nParamIndex, nType, sParamName, sDescription)
   End Sub

   ' new per parametro vuoto
   Sub New(nType As MachParamType, nParamIndex As Integer, sParamName As String)
      StdInit(Nothing, nParamIndex, nType, sParamName, "")
   End Sub

   Friend Sub UpdateParamValue(dNewValue As Double, sNewValue As String, Optional bDraw As Boolean = True)
      Select Case nType
         Case MachParamType.DOUBLE_, MachParamType.LENGTH
            m_dValue = dNewValue
         Case MachParamType.STRING_
            m_sValue = sNewValue
      End Select
   End Sub

   Public ReadOnly Property IsModified() As Boolean
      Get
         Return m_IsModifiedValue
      End Get
   End Property

   Public Sub IsModifiedReset()
      m_IsModifiedValue = False
   End Sub

End Class

Public Class MachTable
   Inherits VMBase

   ' nome della table
   Private m_sName As String
   Public Property sName As String
      Get
         Return m_sName
      End Get
      Set(value As String)
         m_sName = value
      End Set
   End Property

   Private m_MachParamList As New ObservableCollection(Of MachParam)
   Public Property MachParamList As ObservableCollection(Of MachParam)
      Get
         Return m_MachParamList
      End Get
      Set(value As ObservableCollection(Of MachParam))
         m_MachParamList = value
      End Set
   End Property

   Sub New(Name As String, ParamList As ObservableCollection(Of MachParam))
      sName = Name
      MachParamList = ParamList
   End Sub

End Class

' Tipo parametro nel file di configurazione Macchina
Public Enum MachParamType As Integer
   DOUBLE_ = 1
   STRING_ = 2
   COMBO = 3
   LENGTH = 4
   CHECKBOX = 5
End Enum
