Imports EgtBEAMWALL.Core.ConstMachComm
Imports EgtUILib
Imports EgtWPFLib5
Imports ISOCNC.Remoting

Public Class RWVariableManager

   Private m_Tpa As TPAComm = Nothing
   Friend ReadOnly Property Tpa As TPAComm
      Get
         Return m_Tpa
      End Get
   End Property

   Private m_Proxy_VariableCommandExecutedEventHandler As New VariableCommandExecutedEventHandler(AddressOf RemoteObject_VariableCommandExecuted)

   ' lock per Synclock
   Private m_CopyLock As New Object
   Private m_ReadLock As New Object
   ' lista variabili in lettura
   Private Shared m_ReadingVars(19) As CommVar
   Public Shared ReadOnly Property ReadingVars As CommVar()
      Get
         Return m_ReadingVars
      End Get
   End Property

   ' lista variabili lette
   Public Shared m_ReadedVars(19) As String

   Protected Sub New()
   End Sub

   Friend Sub OnDispose()
      RemoveHandler m_Tpa.eventProxy.VariableCommandExecuted, m_Proxy_VariableCommandExecutedEventHandler
      'RemoveHandler m_Tpa.MachManaging.Timer.Tick, AddressOf Timer_Tick
   End Sub

   'Friend Sub Timer_Tick(sender As Object, e As EventArgs)
   '   ' leggo tutte le variabili
   '   RefreshAllVars()
   'End Sub

   Friend Shared Function CreateRWVariableManager(Tpa As TPAComm)
      Dim NewRWVariableManager As New RWVariableManager
      NewRWVariableManager.m_Tpa = Tpa
      AddHandler NewRWVariableManager.m_Tpa.eventProxy.VariableCommandExecuted, NewRWVariableManager.m_Proxy_VariableCommandExecutedEventHandler
      Return NewRWVariableManager
   End Function

   Public Sub RefreshAllVars()
      EgtOutLog("RefreshAllVars")
      For Each Var In m_ReadingVars
         ' rileggo solo variabili continue
         If Not IsNothing(Var) AndAlso Var.sType = CommVar.CommVarTypes.CONTINUOUS Then IntRefreshVar(Var.sAddress)
      Next
   End Sub

   Public Shared Function InitVar(Name As String, Address As String, Type As CommVar.CommVarTypes) As Integer
      Dim Index As Integer = Array.IndexOf(m_ReadingVars, Nothing)
      m_ReadingVars(Index) = New CommVar(Name, Address, Type)
      Return Index
   End Function

   Public Sub RefreshVar(Name As String)
      Dim Var As CommVar = GetReadVarFromName(Name)
      Var.ResetReading()
      IntRefreshVar(Var.sAddress)
   End Sub

   Public Sub WriteVar(Name As String, Value As String)
      IntWriteVar(GetReadVarFromName(Name).sAddress, Value)
   End Sub

   Private Sub IntRefreshVar(Address As String)
      Tpa.remObject.SetVariableCommand(ISOCNC.Remoting.VariableCommands.ReadVar, Address, "")
   End Sub

   Private Sub IntWriteVar(Address As String, Value As String)
      Tpa.remObject.SetVariableCommand(ISOCNC.Remoting.VariableCommands.WriteVar, Address, Value)
   End Sub

   Public Sub ReadVar(Name As String, ByRef Value As String)
      Value = m_ReadedVars(GetIndexFromName(Name))
   End Sub
   Public Sub ReadVar(Name As String, ByRef Value As Integer)
      Integer.TryParse(m_ReadedVars(GetIndexFromName(Name)), Value)
   End Sub
   Public Sub ReadVar(Name As String, ByRef Value As Double)
      Value = StringToDouble(m_ReadedVars(GetIndexFromName(Name)), 5)
   End Sub

   Private Shared Function GetIndexFromName(Name As String) As Integer
      Return Array.FindIndex(m_ReadingVars, Function(x) If(Not IsNothing(x), x.sName = Name, False))
   End Function
   Friend Shared Function GetReadVarFromName(Name As String) As CommVar
      Return m_ReadingVars(GetIndexFromName(Name))
   End Function
   Private Shared Function GetIndexFromAddress(Address As String) As Integer
      Return Array.FindIndex(m_ReadingVars, Function(x) If(Not IsNothing(x), x.sAddress = Address, False))
   End Function
   Friend Shared Function GetReadVarFromAddress(Address As String) As CommVar
      Return m_ReadingVars(GetIndexFromAddress(Address))
   End Function
   Friend Shared Function GetReadVarNameFromAddress(Address As String) As String
      Dim Var As CommVar = m_ReadingVars.FirstOrDefault(Function(x) If(Not IsNothing(x), x.sAddress = Address, False))
      Return If(Not IsNothing(Var), Var.sName, "")
   End Function

   Private Sub UpdateContinuousVars()
      Dim bReaded As Boolean = True
      For Each Var In m_ReadingVars
         If Not IsNothing(Var) AndAlso Var.sType = CommVar.CommVarTypes.CONTINUOUS AndAlso Not Var.bReaded Then
            bReaded = False
            Exit For
         End If
      Next
      ' se lette tutte
      If bReaded Then
         ' aggiorno variabili
         SyncLock m_CopyLock
            For VarIndex = 0 To m_ReadingVars.Count - 1
               If Not IsNothing(m_ReadingVars(VarIndex)) Then
                  m_ReadedVars(VarIndex) = m_ReadingVars(VarIndex).sValue
               End If
            Next
         End SyncLock
      End If
   End Sub

   Friend Sub UpdateVar(CommandExecutedCorrectly As Boolean, VarName As String, VarValue As String, VarType As Integer)
      If CommandExecutedCorrectly Then
         Dim Var As CommVar = GetReadVarFromAddress(VarName)
         If Not IsNothing(Var) Then
            'Dim bChangedVal As Boolean = ()
            Var.SetValue(VarValue)
            ' se variabile ripetitiva lancio update variabili ripetitive
            If Var.sType = CommVar.CommVarTypes.CONTINUOUS Then
               EgtOutLog(CommandExecutedCorrectly & " . " & VarName & " . " & VarValue)
               EgtOutLog(Var.sName & " . " & Var.sAddress & " . " & Var.sValue & " . " & Var.bReaded)
               UpdateContinuousVars()
            Else
               m_ReadVarCallbackDlg(CommandExecutedCorrectly, VarName, VarValue, VarType)
            End If
         End If
      End If
   End Sub

   Private Sub RemoteObject_VariableCommandExecuted(ByVal executedCommand As Integer, ByVal commandExecutedCorrectly As Boolean, ByVal varName As String, ByVal varValue As String, ByVal varType As Integer)
      ' riporto valore variabile su array
      Select Case executedCommand
         Case VariableCommands.Error
         Case VariableCommands.NotExecuted
         Case VariableCommands.ReadVar
            UpdateVar(commandExecutedCorrectly, varName, varValue, varType)
         Case VariableCommands.WriteVar
            m_ResultCallbackDlg(CommandTypes.WRITE, CommandStates.OK, ResultTypes.RESULT, "")
         Case VariableCommands.ReadAxis
         Case VariableCommands.ReadAny
      End Select
   End Sub

End Class

Public Class CommVar

   Public Enum CommVarTypes As Integer
      ONETIME
      CONTINUOUS
   End Enum

   Private m_sName As String
   Public ReadOnly Property sName As String
      Get
         Return m_sName
      End Get
   End Property
   Private m_sAddress As String
   Public ReadOnly Property sAddress As String
      Get
         Return m_sAddress
      End Get
   End Property
   Private m_nType As CommVarTypes
   Public ReadOnly Property sType As CommVarTypes
      Get
         Return m_nType
      End Get
   End Property
   Private m_sValue As String
   Public ReadOnly Property sValue As String
      Get
         Return m_sValue
      End Get
   End Property
   Public Sub SetValue(Value As String)
      m_sValue = Value
      m_bReaded = True
   End Sub

   Private m_bReaded As Boolean
   Public ReadOnly Property bReaded As Boolean
      Get
         Return m_bReaded
      End Get
   End Property

   Sub New(Name As String, Address As String, Type As CommVarTypes)
      m_sName = Name
      m_sAddress = Address
      m_nType = Type
   End Sub

   Friend Sub ResetReading()
      m_bReaded = False
   End Sub

End Class
