Imports System
Imports System.Collections.Generic
Imports System.Linq
Imports System.Runtime.Remoting.Channels
Imports System.Runtime.Remoting.Channels.Ipc
Imports System.Security.Permissions
Imports System.Text
Imports System.Threading.Tasks
Imports System.Windows
Imports ISOCNC.Remoting

Class TPAComm

   ' creo classe di gestione variabili
   Private m_RWVariableManager As RWVariableManager
   Friend ReadOnly Property RWVariableManager As RWVariableManager
      Get
         Return m_RWVariableManager
      End Get
   End Property

   Private m_MachManaging As MachManaging
   Friend ReadOnly Property MachManaging As MachManaging
      Get
         Return m_MachManaging
      End Get
   End Property

   Private _axesVal As Double() = New Double(23) {}
   Private _cmdActive As Integer = 0
   Private m_opState As ISOCNC.Remoting.MachineOperatingState = ISOCNC.Remoting.MachineOperatingState.Unspecified
   Public ReadOnly Property opState As ISOCNC.Remoting.MachineOperatingState
      Get
         Return m_opState
      End Get
   End Property
   Private _remObject As ISOCNC.Remoting_Server

   Public ReadOnly Property remObject As ISOCNC.Remoting_Server
      Get
         Return _remObject
      End Get
   End Property

   Private serverURI As String = "ipc://localhost:9090/IRemoteObject.rem"
   Private m_eventProxy As ISOCNC.Remoting.EventProxyManager
   Friend ReadOnly Property eventProxy As ISOCNC.Remoting.EventProxyManager
      Get
         Return m_eventProxy
      End Get
   End Property

   Private _rpc As Integer
   Private _prgCount As Integer
   Private _prgAtIndex As String
   Private _prgList As String()
   Private _prgListUpdated As Boolean
   Private _errCycle As String
   Private _iso As String
   Private _message As String
   Private _errSystem As String

   Private m_Proxy_CommandExecutedEventHandler As New CommandExecutedEventHandler(AddressOf RemoteObject_CommandExecuted)
   Private m_Proxy_ServerErrorEventHandler As New ServerErrorEventHandler(AddressOf RemoteObject_ServerError)
   Private m_Proxy_AxesCoordinatesUpdateEventHandler As New AxesCoordinatesUpdateEventHandler(AddressOf RemoteObject_AxisCoordinatesUpdate)
   Private m_Proxy_OpStateUpdateEventHandler As New OpStateUpdateEventHandler(AddressOf RemoteObject_OpStateUpdate)
   Private m_Proxy_AlarmNotificationEventHandler As New AlarmNotificationEventHandler(AddressOf RemoteObject_AlarmNotification)
   Private m_Proxy_ListInfoEventHandler As New ListInfoEventHandler(AddressOf RemoteObject_ListInfoResponse)
   Private m_Proxy_RPCUpdateEventHandler As New RPCUpdateEventHandler(AddressOf RemoteObject_RPCUpdate)
   Private m_Proxy_VariableCommandExecutedEventHandler As New VariableCommandExecutedEventHandler(AddressOf RemoteObject_VariableCommandExecuted)
   Private m_Proxy_TickUpdateEventHandler As New TickUpdateEventHandler(AddressOf RemoteObject_TickUpdate)
   Private m_Rem_CommandExecutedEventHandler As CommandExecutedEventHandler
   Private m_Rem_ServerErrorEventHandler As ServerErrorEventHandler
   Private m_Rem_AxesCoordinatesUpdateEventHandler As AxesCoordinatesUpdateEventHandler
   Private m_Rem_OpStateUpdateEventHandler As OpStateUpdateEventHandler
   Private m_Rem_AlarmNotificationEventHandler As AlarmNotificationEventHandler
   Private m_Rem_ListInfoEventHandler As ListInfoEventHandler
   Private m_Rem_RPCUpdateEventHandler As RPCUpdateEventHandler
   Private m_Rem_VariableCommandExecutedEventHandler As VariableCommandExecutedEventHandler


   <SecurityPermission(SecurityAction.Demand)>
   Public Sub New(Machmanaging As MachManaging)
      m_MachManaging = Machmanaging
      Dim properties As System.Collections.Hashtable = New System.Collections.Hashtable()
      properties("name") = "remotingClient"
      properties("priority") = "20"
      properties("portName") = "67"
      Dim clientProv As BinaryClientFormatterSinkProvider = New BinaryClientFormatterSinkProvider()
      Dim serverProv As BinaryServerFormatterSinkProvider = New BinaryServerFormatterSinkProvider()
      serverProv.TypeFilterLevel = System.Runtime.Serialization.Formatters.TypeFilterLevel.Full
      Dim channel As IpcChannel = New IpcChannel(properties, clientProv, serverProv)
      System.Runtime.Remoting.Channels.ChannelServices.RegisterChannel(channel, False)
      Dim remoteType As System.Runtime.Remoting.WellKnownClientTypeEntry = New System.Runtime.Remoting.WellKnownClientTypeEntry(GetType(ISOCNC.Remoting_Server), serverURI)
      System.Runtime.Remoting.RemotingConfiguration.RegisterWellKnownClientType(remoteType)
      Dim objectUri As String
      Dim messageSink As System.Runtime.Remoting.Messaging.IMessageSink = channel.CreateMessageSink("ipc://localhost:9090/IRemoteObject.rem", Nothing, objectUri)
      Console.WriteLine("The URI of the message sink is {0}.", objectUri)

      If messageSink IsNot Nothing Then
         Console.WriteLine("The type of the message sink is {0}.", messageSink.[GetType]().ToString())
      End If

      m_eventProxy = New ISOCNC.Remoting.EventProxyManager()
      AddHandler m_eventProxy.CommandExecuted, m_Proxy_CommandExecutedEventHandler
      AddHandler m_eventProxy.ServerError, m_Proxy_ServerErrorEventHandler
      AddHandler m_eventProxy.AxisCoordinatesUpdate, m_Proxy_AxesCoordinatesUpdateEventHandler
      AddHandler m_eventProxy.OpStateUpdate, m_Proxy_OpStateUpdateEventHandler
      AddHandler m_eventProxy.AlarmNotification, m_Proxy_AlarmNotificationEventHandler
      AddHandler m_eventProxy.ListInfoResponse, m_Proxy_ListInfoEventHandler
      AddHandler m_eventProxy.RPCUpdate, m_Proxy_RPCUpdateEventHandler
      AddHandler m_eventProxy.VariableCommandExecuted, m_Proxy_VariableCommandExecutedEventHandler
      AddHandler m_eventProxy.TickUpdate, m_Proxy_TickUpdateEventHandler

      _remObject = CType(Activator.GetObject(GetType(ISOCNC.Remoting_Server), serverURI), ISOCNC.Remoting_Server)
      Try
         m_Rem_CommandExecutedEventHandler = New CommandExecutedEventHandler(AddressOf m_eventProxy.LocallyHandleCommandExecuted)
         m_Rem_ServerErrorEventHandler = New ServerErrorEventHandler(AddressOf m_eventProxy.LocallyHandleServerError)
         m_Rem_AxesCoordinatesUpdateEventHandler = New AxesCoordinatesUpdateEventHandler(AddressOf m_eventProxy.LocallyHandleAxisCoordinatesUpdate)
         m_Rem_OpStateUpdateEventHandler = New OpStateUpdateEventHandler(AddressOf m_eventProxy.LocallyHandleOpStateUpdate)
         m_Rem_AlarmNotificationEventHandler = New AlarmNotificationEventHandler(AddressOf m_eventProxy.LocallyHandleAlarmNotification)
         m_Rem_ListInfoEventHandler = New ListInfoEventHandler(AddressOf m_eventProxy.LocallyHandleListInfo)
         m_Rem_RPCUpdateEventHandler = New RPCUpdateEventHandler(AddressOf m_eventProxy.LocallyHandleRPCUpdate)
         m_Rem_VariableCommandExecutedEventHandler = New VariableCommandExecutedEventHandler(AddressOf m_eventProxy.LocallyHandleVariableCommandExecuted)
         AddHandler _remObject.CommandExecuted, m_Rem_CommandExecutedEventHandler
         AddHandler _remObject.ServerError, m_Rem_ServerErrorEventHandler
         AddHandler _remObject.AxisCoordinatesUpdate, m_Rem_AxesCoordinatesUpdateEventHandler
         AddHandler _remObject.OpStateUpdate, m_Rem_OpStateUpdateEventHandler
         AddHandler _remObject.AlarmNotification, m_Rem_AlarmNotificationEventHandler
         AddHandler _remObject.ListInfoResponse, m_Rem_ListInfoEventHandler
         AddHandler _remObject.RPCUpdate, m_Rem_RPCUpdateEventHandler
         AddHandler _remObject.VariableCommandExecuted, m_Rem_VariableCommandExecutedEventHandler
      Catch ex As System.Runtime.Remoting.RemotingException
         Dim dR As MessageBoxResult = MessageBox.Show(ex.Message)
      End Try
      ' creo classe che gestisce variabili
      m_RWVariableManager = RWVariableManager.CreateRWVariableManager(Me)
   End Sub

   Friend Sub OnDispose()
      RemoveHandler _remObject.CommandExecuted, m_Rem_CommandExecutedEventHandler
      RemoveHandler _remObject.ServerError, m_Rem_ServerErrorEventHandler
      RemoveHandler _remObject.AxisCoordinatesUpdate, m_Rem_AxesCoordinatesUpdateEventHandler
      RemoveHandler _remObject.OpStateUpdate, m_Rem_OpStateUpdateEventHandler
      RemoveHandler _remObject.AlarmNotification, m_Rem_AlarmNotificationEventHandler
      RemoveHandler _remObject.ListInfoResponse, m_Rem_ListInfoEventHandler
      RemoveHandler _remObject.RPCUpdate, m_Rem_RPCUpdateEventHandler
      RemoveHandler _remObject.VariableCommandExecuted, m_Rem_VariableCommandExecutedEventHandler
      RemoveHandler m_eventProxy.CommandExecuted, m_Proxy_CommandExecutedEventHandler
      RemoveHandler m_eventProxy.ServerError, m_Proxy_ServerErrorEventHandler
      RemoveHandler m_eventProxy.AxisCoordinatesUpdate, m_Proxy_AxesCoordinatesUpdateEventHandler
      RemoveHandler m_eventProxy.OpStateUpdate, m_Proxy_OpStateUpdateEventHandler
      RemoveHandler m_eventProxy.AlarmNotification, m_Proxy_AlarmNotificationEventHandler
      RemoveHandler m_eventProxy.ListInfoResponse, m_Proxy_ListInfoEventHandler
      RemoveHandler m_eventProxy.RPCUpdate, m_Proxy_RPCUpdateEventHandler
      RemoveHandler m_eventProxy.VariableCommandExecuted, m_Proxy_VariableCommandExecutedEventHandler
      RemoveHandler m_eventProxy.TickUpdate, m_Proxy_TickUpdateEventHandler
   End Sub

   Private Sub RemoteObject_OpStateUpdate(ByVal newOpState As ISOCNC.Remoting.MachineOperatingState)
      ' resetto stato pending iniziale
      If Map.refMachManaging.StartPending AndAlso newOpState = MachineOperatingState.Pending Then
         MachManaging.ResetStartPending()
      End If
      m_opState = newOpState
      m_OpStateCallbackDlg(newOpState)
   End Sub

   Private Sub RemoteObject_CommandExecuted(ByVal executedCommand As Integer)
      Select Case executedCommand
         Case CInt(ISOCNC.Remoting.Commands.NoCommand)
         Case CInt(ISOCNC.Remoting.Commands.[End])
            m_ResultCallbackDlg(CommandTypes.RESET, CommandStates.OK, ResultTypes.RESULT, "")
         Case CInt(ISOCNC.Remoting.Commands.[Error])
            m_ResultCallbackDlg(CommandTypes.ERROR_, CommandStates.ERROR_, ResultTypes.RESULT, "")
         Case CInt(ISOCNC.Remoting.Commands.MDI_End)
         Case CInt(ISOCNC.Remoting.Commands.MDI_Start)
         Case CInt(ISOCNC.Remoting.Commands.MDI_Stop)
         Case CInt(ISOCNC.Remoting.Commands.SetPoint)
            m_ResultCallbackDlg(CommandTypes.SETPOINT, CommandStates.OK, ResultTypes.RESULT, "")
         Case CInt(ISOCNC.Remoting.Commands.Start)
            m_ResultCallbackDlg(CommandTypes.START, CommandStates.OK, ResultTypes.RESULT, "")
         Case CInt(ISOCNC.Remoting.Commands.[Step])
            m_ResultCallbackDlg(CommandTypes.STEP_, CommandStates.OK, ResultTypes.RESULT, "")
         Case CInt(ISOCNC.Remoting.Commands.[Stop])
            m_ResultCallbackDlg(CommandTypes.STOP_, CommandStates.OK, ResultTypes.RESULT, "")
         Case CInt(ISOCNC.Remoting.Commands.Start_Program_Soft)
            m_ResultCallbackDlg(CommandTypes.SOFTSTART, CommandStates.OK, ResultTypes.RESULT, "")
         Case Else
      End Select
      _cmdActive = CInt(executedCommand)
   End Sub

   Private Sub RemoteObject_ServerError(ByVal sender As Object, ByVal seEA As ISOCNC.Remoting.ServerErrorEventArgs)
      m_ResultCallbackDlg(CommandTypes.ERROR_, CommandStates.ERROR_, ResultTypes.RESULT, "Server Error: " & seEA.[Error])
      Dim dr As MessageBoxResult = MessageBox.Show("Server Error: " & seEA.[Error])
   End Sub

   Private Sub RemoteObject_AxisCoordinatesUpdate(ByVal axisValue As Double, ByVal axisIndex As Integer)
      m_AxisCoordinatesCallbackDlg(axisValue, axisIndex)
   End Sub

   Private Sub RemoteObject_RPCUpdate(ByVal newRPC As UInteger)
      _rpc = CInt(newRPC)
   End Sub

   Private Sub RemoteObject_ListInfoResponse(ByVal prgCount As Integer, ByVal prgAtIndex As String, ByVal prgList As String())
      If prgCount >= 0 Then
         _prgCount = prgCount
      End If

      If prgAtIndex <> "" Then
         _prgAtIndex = prgAtIndex
      End If

      If prgList IsNot Nothing AndAlso prgList.Length > 0 Then
         _prgList = prgList
         _prgListUpdated = True
      End If
   End Sub

   Private Sub RemoteObject_AlarmNotification(ByVal alarmOperation As Integer, ByVal alarmType As Integer, ByVal alarmMessage As String, ByVal alarmCode As String, ByVal alarmDateTime As String)
      ' restituisco errore ad interfaccia
      m_AlarmCallbackDlg(alarmOperation, alarmType, alarmMessage, alarmCode, alarmDateTime)
   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
            m_RWVariableManager.UpdateVar(commandExecutedCorrectly, varName, varValue, varType)
         Case VariableCommands.WriteVar
            m_ResultCallbackDlg(CommandTypes.WRITE, If(commandExecutedCorrectly, CommandStates.OK, CommandStates.ERROR_), ResultTypes.RESULT, varName & "=" & varValue)
         Case VariableCommands.ReadAxis
         Case VariableCommands.ReadAny
      End Select
   End Sub

   Private Sub RemoteObject_TickUpdate(ByVal newTick As ULong)
   End Sub

End Class
