
Imports System.Collections.Generic
Imports System.Collections.ObjectModel
Imports System.ComponentModel
Imports System.Data
Imports System.Drawing
Imports System.Linq
Imports System.Text
Imports System.Windows.Forms
Imports System.Runtime.InteropServices
Imports EgtUILib

Namespace Num

Public Class NumNCOld
   Inherits CN_generico

#Region " Classes"
#End Region

#Region " Enum"
      Enum eStateType As Int16
         NOT_INIT = -999
         READY = 0
         BUSY = -998
      End Enum
#End Region

#Region " Constants"

      Const SLEEP_TIME = 10

      Const A_AXIS As Short = 6
      Const RET_OK As Int16 = 0

      ' modi NUM Axium

      Const AUTO_M = 0, SINGLE_M = 1, MDI_M = 2, DRYRUN_M = 3, SEARCH_M = 4, EDIT_M = 5, TEST_M = 6
      Const MANUAL_M = 7, MOS_M = 8, SHIFTS_M = 9, TLCOMP_M = 10, LOAD_M = 13, UPLOAD_M = 15

      Const V0 = &HA000, V1 = &HA001, V2 = &HA002, V3 = &HA003, V4 = &HA004, V5 = &HA005, V6 = &HA006, V7 = &HA007
      Const VBY = &HA040, VW = &HA041, VL = &HA042   'VB4 doesn't accepte VB (-->VBY )

      Const M0 = &HA100, M1 = &HA101, M2 = &HA102, M3 = &HA103, M4 = &HA104, M5 = &HA105, M6 = &HA106, M7 = &HA107
      Const MB = &HA140, MW = &HA141, ML = &HA142

      'Global Const C0=*0xA200
      'C1,C2,C3,C4,C5,C6,C7,
      Const CB = &HA240, CW = &HA241, CL = &HA242

      Const R0 = &HA400, R1 = &HA401, R2 = &HA402, R3 = &HA403, R4 = &HA404, R5 = &HA405, R6 = &HA406, R7 = &HA407
      Const RB = &HA440, RW = &HA441, RL = &HA442

      Const W0 = &HA500, W1 = &HA501, W2 = &HA502, W3 = &HA503, W4 = &HA504, W5 = &HA505, W6 = &HA506, W7 = &HA507
      Const WB = &HA540, WW = &HA541, WL = &HA542

      Const I0 = &HA800, I1 = &HA801, I2 = &HA802, I3 = &HA803, I4 = &HA804, I5 = &HA805, I6 = &HA806, I7 = &HA807
      Const IB = &HA840, IW = &HA841, IL = &HA842

      Const Q0 = &HA900, Q1 = &HA901, Q2 = &HA902, Q3 = &HA903, Q4 = &HA904, Q5 = &HA905, Q6 = &HA906, Q7 = &HA907
      Const QB = &HA940, QW = &HA941, QL = &HA942

      Const SYN = 0 ' /* synchrone */
      Const ASS = 1 ' /* assynchrone send request */
      Const ASR = 2 ' /* assynchrone read response */

      Const CTRL_AXES = 143
      Const SPINDLE_SPEED = 144
      Const SPINDLE_POS = 145, H_VAR = 147, MOS_OK = 149
      Const E80000 = 150, E81000 = 151, E82000 = 152, E30000 = 166, E40000 = 167, M_DECOD = 168, DATA_PROG = 226

      Const Mode = 180, ACTIVE_PROG = 181

      Const REF = 128, MES = 129, DAT1 = 130, DAT2 = 131, DAT3 = 132, MIN_LIM = 133, MAX_LIM = 134, VARH = 147
      Const TILT = 135, MACH_ORIGIN = 136, P17_MIN = 137, P17_MAX = 138, REF_COR = 139, REF_POS = 140, MES_POS = 141

      Const TMACRO1 = &H31, TMACRO2 = &H32, TMACRO3 = &H33
      Const TUT6 = 6, TLAD = 7, TIHM = 8, TNC = 12, TPAR = 5, TCALIBR = 2, TMACRO = 11, TUTIL = 13, TPASSANT = 12
      Const TSi = 1, TFi = 2, SPi = 3, THi = 4, INI = 5, TABSYMB = 10, ALLMODULE = 16, CMODULE = 65, TXTFILE = 97
      Const IHMFNT = 98, IHMBMP = 99, IHMRSC = 100, IHMINI = 101, IHMTXT = 102, IHMICO = 103, IHMCOD = 104

#End Region

#Region " Structures"

      Structure tDNC20_Position_OPOM
         Dim Valid As Byte
         Dim Position As Long
         Dim ToGo As Long
         Dim offset As Long
      End Structure

      Structure tDNC20_Axes
         '            Dim axe(0 To 8) As tDNC20_Position_OPOM
         Dim axe() As tDNC20_Position_OPOM
      End Structure

      Structure tDNC20_Spindle_i
         Dim Valid As Byte
         Dim Spindle As Long
      End Structure

      Structure tDNC20_Spindle
         ' Dim Data(0 To 3) As tDNC20_Spindle_i
         Dim Data() As tDNC20_Spindle_i
      End Structure

      Structure tCorOutil
         Dim L_X As Long
         Dim RTore_Z As Long
         Dim R_Radus As Long
         Dim DL_DX As Long
         Dim DR_DZ As Long
         Dim Direc As Long
         Dim Type As Long
      End Structure

      <StructLayout(LayoutKind.Explicit)> _
      Public Structure tDNC20_ObjectList
         <FieldOffset(0)> Public ElemNum As UInt16
         <FieldOffset(2)> Public First As UInt16
         <FieldOffset(4)> Public Quantity As UInt16
      End Structure

      Public Structure My_data_struct
         <MarshalAs(UnmanagedType.ByValArray, SizeConst:=256)> _
         Public data As Byte()
      End Structure

#End Region

#Region " Variabili "

      Public Var6003 As Byte
      Public Var600A As Byte
      Public Var600B As Byte
      Public Var600C As Byte
      Public Var600D As Byte
      Public Var600E As Byte

      Public var6010L As Long
      Public var6014L As Long
      Public var6018L As Long
      Public var601CL As Long
      Public var6020L As Long
      Public var6024L As Long
      Public var6028L As Long
      Public var602CL As Long

      Private iFirstVar As UInt16
      Private n_portNC As Int16

      Private Vmminch As Long = 1000
      Private NumCifreDecP4 As Long = 1000

      Private aTimer As System.Timers.Timer
      Private nCount As Integer = 0

      Private b_busy As Boolean = False
      Private b_OM_pos As Boolean = True
      Private global_state As eStateType = eStateType.NOT_INIT

      Private MyData As My_data_struct
      Private MyData2 As My_data_struct

      Private l_active_program As Int32 ' /* active CNC program number */
      Private l_GFunction As Int32 ' /* G functions running */

      Private n_BlocExe As UInt16 ' ; /* current block number */
      Private n_ProgError As Int16 ' ; /* CNC error number detected */
      Private n_BlocError As UInt16 ' ; /* block number where the error was detected */
      Private n_Tool As UInt16 ' ; /* current tool number (T) */
      Private n_Direction As UInt16 ' ; /* current tool direction */
      Private n_Corrector As UInt16 ' ; /* current tool offset number (D) */
      Private n_LeftFunct As UInt16 ' ; /* functions to be executed after current movement (see LADDER documentation) */

      Private n_ErrorNumber As UInt16     ' //Error number
      Private n_ErrorBlockNum As UInt16   '   //Block number in error
      Private n_ReadStatus As UInt16      '           //Read Status: 0x0F=end of message 0x06=follow-up
      Private n_MsgSize As UInt16         '                 //Number of  characters in the message
      Private MsgTab(123) As Byte         ' //Message read


#End Region

#Region " DLL import"

      Declare Function SetPLCTool Lib "LIB_UNIT2.DLL" (ByVal chinit As String) As Int16
      Declare Function Get_Port Lib "LIB_UNIT2.DLL" (ByRef Port As Int16) As Int16

      Declare Function Free_Port Lib "LIB_UNIT2.DLL" (ByVal Port As Int16) As Int16
      Declare Function Close_Unite Lib "LIB_UNIT2.DLL" () As Int16

      Declare Function WriteObjectVarious2 Lib "dnc2.DLL" (ByVal Port As Int16, ByVal qui As UInt16, ByRef pData As Int32) As Int16
      Declare Function ReadObjectVarious2 Lib "dnc2.DLL" (ByVal Port As Int16, ByVal qui As UInt16, ByRef pData As Int32, ByVal Mode As UInt16) As Int16
      '        Declare Function WriteLadderVar Lib "dnc2.DLL" (ByVal Port As Int16, ByVal qui As UInt16, ByVal num As Int16, ByVal Nb As Int16, ByRef pData As Int32) As Int16

      Declare Function StartNC Lib "dnc2.dll" (ByVal Port As Int16) As Int16
      Declare Function StopNC Lib "dnc2.dll" (ByVal Port As Int16) As Int16
      Declare Function InitNC Lib "dnc2.dll" (ByVal Port As Int16) As Int16

      Declare Function WriteTool Lib "dnc2.dll" (ByVal Port As Int16, ByVal number As Integer, ByVal Quantity As Integer, AdrData As tCorOutil) As Int16
      Declare Function ReadTool Lib "dnc2.dll" (ByVal Port As Int16, ByVal number As Integer, ByVal Quantity As Integer, ByRef d As My_data_struct, ByVal Mode As UInt16) As Int16

      Declare Function DNC20_DialWithModes_2 Lib "dnc20_2.dll" (ByVal Port As Int16, ByVal pstring As String, ByVal Mode As UInt16) As Int16
      Declare Function DNC20_Spindle Lib "dnc20_2.dll" (ByVal Port As Int16, ByVal Group As Int16, ByRef pData As tDNC20_Spindle, ByVal Mode As UInt16) As Int16

      Declare Function ReadLadderVar Lib "dnc2.DLL" (ByVal Port As Int16, ByVal qui As UInt16, ByVal num As UInt16, ByVal Nb As UInt16, ByRef d As My_data_struct, ByVal Mode As UInt16) As Int16

      Declare Function UpLoadFile Lib "dnc2.dll" (ByVal Port As Int16, ByVal prog As Int32, ByVal filename As String) As Int16
      Declare Function DownLoadFile Lib "dnc2.dll" (ByVal Port As Int16, ByVal prog As Int32, ByVal filename As String) As Int16
      Declare Function DncDeleteFile Lib "dnc2.dll" (ByVal Port As Int16, ByVal prog As Int32) As Int16

      Declare Function DNC20_Position_OM Lib "dnc20_2.dll" (ByVal Port As Int16, ByVal Groupe As Int16, ByRef d As My_data_struct, ByVal Mode As UInt16) As Int16
      Declare Function DNC20_Position_OP Lib "dnc20_2.dll" (ByVal Port As Int16, ByVal Groupe As Int16, ByRef d As My_data_struct, ByVal Mode As UInt16) As Int16

      Declare Function ReadObjectVarious4 Lib "dnc2.dll" (ByVal Port As Int16, ByVal qui As UInt16, ByVal Prem As UInt16, ByVal Quantity As UInt16, ByRef d As My_data_struct, ByVal Mode As UInt16) As Int16
      Declare Function WriteObjectVarious4 Lib "dnc2.dll" (ByVal Port As Int16, ByVal qui As UInt16, ByVal Prem As UInt16, ByVal Quantity As UInt16, ByRef d As My_data_struct) As Int16

      Declare Function DNC20_ReadExxxxx Lib "dnc20_2.dll" (ByVal Port As Int16, ByVal Group As UInt16, ElemNb As Int16, ByRef DataList As tDNC20_ObjectList, ByRef Data As Int32, ByVal Mode As UInt16) As Int16
      Declare Function DNC20_ReadLxxx Lib "dnc20_2.dll" (ByVal Port As Int16, ByVal Group As UInt16, ElemNb As Int16, ByRef DataList As tDNC20_ObjectList, ByRef Data As Single, ByVal Mode As UInt16) As Int16

      Declare Function ReadMemoryFree Lib "dnc2.dll" (ByVal port As Int16, ByRef pData As Long, ByVal zone As Int16) As Int16

      Declare Function ReadProgStatus Lib "dnc2.dll" (ByVal port As Int16, ByVal PremGr As Int16, ByVal NbGr As Int16, ByRef d As My_data_struct, ByVal Mode As Int16) As Int16

      Declare Function DNC40_ReadCncError Lib "dnc40_2.dll" (ByVal Port As Int16, ByVal Group As UInt16, ByVal ErrorLineNum As Int16, ByRef d As My_data_struct, ByVal Mode As Int16) As Int16

      Declare Function InterpoState Lib "dnc2.dll" (ByVal port As Int16, ByVal Group As Int16, ByVal GroupNB As Int16, ByRef d As My_data_struct, ByVal Mode As Int16) As Int16

#End Region

#Region " Constructor"

   Sub New()
      n_state = 0
      sz_NC_error_messages = New List(Of String)
   End Sub

   Public Overrides Function Init() As Boolean

      n_state = 0

      ' Stringhe valide : "COM" o "XIP01, 0, 10, 0, 0, 0"
      Dim nret As Integer = NC_connect(m_szCnDataVar(CnData.Comm))
      If nret <> 0 Then Return False

      n_state = 2

      ' Create a timer and set an half second interval.
      aTimer = New System.Timers.Timer()

      Dim nRefresh As Integer = 200
      Dim nTemp As Integer
      If Integer.TryParse(m_szCnDataVar(CnData.Refresh), nTemp) Then
         nRefresh = nTemp
      End If

      aTimer.Interval = nRefresh

      ' Hook up the Elapsed event for the timer.  
      AddHandler aTimer.Elapsed, AddressOf OnTimedEvent

      aTimer.AutoReset = True         ' Have the timer fire repeated events (true is the default)

      aTimer.Enabled = True          ' Start the timer

      Return n_state >= 2
   End Function

   Private Sub OnTimedEvent(source As Object, e As System.Timers.ElapsedEventArgs)

      If Not b_busy Then
         aTimer.Enabled = False
         b_busy = True

         nCount += 1

         Read_machine_pos()     ' leggo posizioni assi

         If nCount = 2 Or nCount = 4 Then
            timer_read_var()       ' leggo un mucchio di variabili in un colpo solo
         End If

         If nCount = 4 Then
            nCount = 0
            get_errors()        ' leggo eventueli errori PLC e CN
         End If

         b_busy = False
         aTimer.Enabled = True
      End If

   End Sub

   Function NC_connect(sz_connect_string As String) As Int16

      Dim nret As Int16
      Dim msga As String

      'nret = SetPLCTool("XIP01, 0, 10, 0, 0, 0")
      'nret = SetPLCTool("COM")

      nret = SetPLCTool(sz_connect_string)

      If nret <> 0 Then
         msga = "Communication not available (SetPLCTool) : " & nret.ToString & " - " & sz_connect_string
         EgtOutLog(msga)
      End If

      'Richiedo porta comunicazione PC-CN 2
      '           iport2 = 1
      nret = Get_Port(n_portNC)
      If nret <> 0 Then
         msga = " Port not available (Get_Port) : " & nret.ToString
         EgtOutLog(msga)
      End If

      ' eventualmente aggiungere apertura porta per PPP
      'iport3 = 3
      'nret = Get_Port(iport3)

      global_state = eStateType.READY

      Return nret

   End Function

   Function NC_disconnect() As Int16

      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If

      Dim nret As Int16 = Free_Port(n_portNC)

      global_state = eStateType.NOT_INIT

      Return nret

   End Function

#End Region

   Function timer_read_var() As Int16


      Const FIRST_GROUP As Int16 = 0, N_GROUPS As Int16 = 1

      Dim nret As Int16 = -1

      If global_state <> eStateType.READY Then
         Return global_state
      End If

      global_state = eStateType.BUSY

      ' Lettura variabile %V6003
      
      iFirstVar = &H6003

      nret = ReadLadderVar(n_portNC, VBY, iFirstVar, 1, MyData, SYN)
      If nret = 0 Then
         Var6003 = MyData.data(0)
      End If

      ' Lettura variabili da %V600A.B a %V600D.B tramite un solo accesso in memoria per %V600A.B e lettura di 4 in serie

      iFirstVar = &H600A

      nret = ReadLadderVar(n_portNC, VBY, iFirstVar, 5, MyData, SYN)

      If nret = 0 Then
         Var600A = MyData.data(0)        ' Feed_override
         Var600B = MyData.data(1)        ' spindle_override
         Var600C = MyData.data(2)
         Var600D = MyData.data(3)        ' active_mode
         Var600E = MyData.data(4)

         b_feed_changed = True
         d_DInterpo_Feed_override = Math.Round(Var600A * 120.0 / 255, 0)

         b_spindle_data_changed = True
         n_spindle_override(0) = CShort(Math.Round((Var600B * 50 / 255) + 50))
      End If

      ' Lettura variabile assorbimento mandrino ( %V250F )

      iFirstVar = &H250F

      nret = ReadLadderVar(n_portNC, VW, iFirstVar, 1, MyData, SYN)

      If nret = 0 Then

         d_spindle_power = CDbl(BitConverter.ToInt16(MyData.data, 0)) / 10.0

      End If

      ' Lettura potenziometro F override......

      '     Type tInterpo
      '         FeedMes1 As Integer ';  /* not used */
      '         FeedMes2 As Integer ';  /* internal unit per NC sampling time */
      '         Distance As Long ';  /* to go on the path */
      '         FeedProg  As Long ';
      '         Override  As Long ';  /* 16 LSB used */
      '     End Type

      nret = InterpoState(n_portNC, FIRST_GROUP, N_GROUPS, MyData, SYN)

      If nret <> 0 Then
         Dim sMsg As String = "Error in InterpoState : " & nret.ToString
         EgtOutLog(sMsg)
      End If

      '         FeedMes1 = BitConverter.ToInt16(MyData.data, 0))
      '         FeedMes2 = BitConverter.ToInt16(MyData.data, 2))  '/* internal unit per NC sampling time */
      '         Distance = BitConverter.ToInt32(MyData.data, 4))  '/* to go on the path */
      '         FeedProg = BitConverter.ToInt32(MyData.data, 8))  
      '         Override = BitConverter.ToInt32(MyData.data, 12))  /* 16 LSB used */

      'e non gestiamo il caso del numero negativo.......
      d_DInterpo_Prog_Feed = CDbl(BitConverter.ToUInt16(MyData.data, 10)) ' sembrerebbero i due bytes più alti del long ...??   

      ' Lettura variabile S effettiva

      iFirstVar = &H2600

      nret = ReadLadderVar(n_portNC, VL, iFirstVar, 1, MyData, SYN)

      If nret = 0 Then
         d_spindle_eff(0) = CDbl(BitConverter.ToInt32(MyData.data, 0))  ' progr. Feed
      End If

      ' Lettura variabili da %V6010.L a %V601C.L

      iFirstVar = &H6010

      nret = ReadLadderVar(n_portNC, VL, iFirstVar, 4, MyData, SYN)

      If nret = 0 Then
         var6010L = BitConverter.ToInt32(MyData.data, 0)  ' progr. Feed
         var6014L = BitConverter.ToInt32(MyData.data, 4)  ' progr. speed
         var6018L = BitConverter.ToInt32(MyData.data, 8)
         var601CL = BitConverter.ToInt32(MyData.data, 12)
      End If

      '         d_DInterpo_Prog_Feed = CDbl(var6010L)  ' sembrerebbe non buona letta da qua ...
      d_spindle_prog(0) = CDbl(var6014L)


      ' Lettura variabili da %V6020.L a %V602C.L

      iFirstVar = &H6020

      nret = ReadLadderVar(n_portNC, VL, iFirstVar, 4, MyData, SYN)

      If nret = 0 Then
         var6020L = BitConverter.ToInt32(MyData.data, 0)
         var6024L = BitConverter.ToInt32(MyData.data, 4) ' potenziometro tablet
         var6028L = BitConverter.ToInt32(MyData.data, 8) ' disponibile
         var602CL = BitConverter.ToInt32(MyData.data, 12) ' disponibile
      End If

      global_state = eStateType.READY
      Return nret

   End Function

   Private Function set_NC_mode(n_mode As Integer) As Int16

      Dim nret As Int16 = -1

      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If

      global_state = eStateType.BUSY

      nret = WriteObjectVarious2(n_portNC, Mode, n_mode)  '     0 AUTO    1 SEQUENZIALE    2 IMD    7 MANUALE   

      If nret <> 0 Then
         EgtOutLog("Error in set_NC_mode(" & n_mode.ToString() & ") : " & nret.ToString())
      End If

      global_state = eStateType.READY

      Return nret

   End Function

   Private Function set_MDI_command(sz_command As String) As Int16

      Dim nret As Int16 = -1
      Dim nret2 As Int16 = -1
      Dim nret3 As Int16 = -1

      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If

      global_state = eStateType.BUSY

      nret = WriteObjectVarious2(n_portNC, Mode, MDI_M)    ' SELEZIONE MODO IMD
      If nret = 0 Then

         nret2 = DNC20_DialWithModes_2(n_portNC, sz_command, SYN)                  ' PASSO IL COMANDO  SU UN BUFFER 
         If nret2 = 0 Then

            nret3 = StartNC(n_portNC)                                             ' DO IL CICLO
            If nret3 = 0 Then

               nret = WriteObjectVarious2(n_portNC, Mode, MANUAL_M) '            ' SELEZIONO MODO MANUALE

            Else
               nret = nret3 + 3000S   ' codice di errore della StartNC
            End If ' If nret3 = 0
         Else
            nret = nret2 + 2000S ' codice di errore della DNC20_DialWithModes_2
         End If ' If nret2 = 0
      End If ' If nret = 0

      global_state = eStateType.READY
      Return nret

   End Function

   Function Read_machine_pos() As Int16

      Dim nret As Int16
      Dim i, n As Integer

      If global_state <> eStateType.READY Then
         Return global_state
      End If

      global_state = eStateType.BUSY

      If b_OM_pos Then               ' quote rispetto a 0  Macchina
         nret = DNC20_Position_OM(n_portNC, 0, MyData, SYN)

      Else                           ' quote rispetto a 0 Pezzo
         nret = DNC20_Position_OP(n_portNC, 0, MyData, SYN)
      End If

      If nret <> 0 Then
         Dim sMsg As String = "Error in DNC20_Position_O* : " & nret.ToString
         EgtOutLog(sMsg)
      End If

      For i = 0 To Math.Min(8, MAX_AXES)      ' si possono leggere come massimo 9 assi 0 -> 8

         n = i * 16

         b_axis_valid(i) = (MyData.data(n) <> 0)

         If b_axis_valid(i) Then
            If i < A_AXIS Then
               d_axis_position(i) = (BitConverter.ToInt32(MyData.data, n + 4)) / Vmminch  ' X
               d_axis_delta(i) = (BitConverter.ToInt32(MyData.data, n + 8)) / Vmminch
            Else
               d_axis_position(i) = (BitConverter.ToInt32(MyData.data, n + 4)) / NumCifreDecP4 ' A
               d_axis_delta(i) = (BitConverter.ToInt32(MyData.data, n + 8)) / NumCifreDecP4
            End If
         End If
      Next

      If b_axis_events_enable Then
         MyBase.OnNewPositionData()
         MyBase.OnNewPosDeltaData()
      End If

      global_state = eStateType.READY
      Return nret

   End Function

#Region " Metodi pubblici"

   Public Overrides Function Stop_Connection() As Boolean

      If VerifyBusy() <> eStateType.READY Then
         Dim sMsg As String = "Error in NC_disconnect : always busy"
         EgtOutLog(sMsg)
      End If

      aTimer.Stop()

      Dim nRet As Short = NC_disconnect()

      If nRet <> 0 Then
         Dim sMsg As String = "Error in NC_disconnect : " & nRet.ToString
         EgtOutLog(sMsg)
      End If

      Return True
   End Function

   Public Overrides Sub ReadEls_Add_Parameter(sz_var As String, n_par As Short)

      ' Verifico accessibilità CN
      If VerifyBusy() <> eStateType.READY Then
         n_DReadELS_handle = 0
         Return
      End If
      ' Dichiaro CN occupato
      global_state = eStateType.BUSY

      Dim Ask As tDNC20_ObjectList

      Select Case sz_var(0)
         Case "E"(0)
            Ask.ElemNum = CUShort(sz_var.Substring(1, 1))
            Ask.First = CUShort(sz_var.Remove(0, 2))
            Ask.Quantity = 1
            Dim nVal As Int32
            Dim nRet As Int16 = DNC20_ReadExxxxx(n_portNC, 0, 1, Ask, nVal, SYN)
            If nRet = 0 Then
               d_DReadELS_value = CDbl(nVal)
               n_DReadELS_handle = n_par
            End If
         Case "L"(0)
            Ask.ElemNum = 0
            Ask.First = CUShort(sz_var.Remove(0, 1))
            Ask.Quantity = 1
            Dim fVal As Single
            Dim nRet As Int16 = DNC20_ReadLxxx(n_portNC, 0, 1, Ask, fVal, SYN)
            If nRet = 0 Then
               d_DReadELS_value = CDbl(fVal)
               n_DReadELS_handle = n_par
            End If
         Case Else
            n_DReadELS_handle = 0
      End Select

      ' Dichiaro CN libero
      global_state = eStateType.READY

   End Sub
   '
   ' call DVariables_WriteVariables("E80000;E80001" , "1;2" )
   '
   Public Overrides Sub DVariables_WriteVariables(sz_parameters As String, sz_values As String)


   End Sub

   Public Overrides Sub DVariables_WriteVariables2(sz_parameters As String, sz_values As String)


   End Sub

   Public Overrides Function MDI_command() As Short

      Dim nret As Int16 = set_MDI_command(sz_ManualDataInput)

      If nret <> 0 Then
         EgtOutLog("Error Execute MDI Command :" & nret.ToString())
      End If

      Return nret

   End Function
   '
   ' Activate program
   ' returns 0 = OK ; > 0 error
   '
   Public Overrides Function ActivateProgram(n_part_program As Integer) As Int16

      Dim nret As Int16 = -1

      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If

      global_state = eStateType.BUSY

      nret = WriteObjectVarious2(n_portNC, Mode, AUTO_M)  ' potrebbe essere anche modo 11 !

      If nret = 0 Then
         nret = WriteObjectVarious2(n_portNC, ACTIVE_PROG, n_part_program)  ' notare : numero non moltiplicato * 10
      End If

      If nret <> 0 Then
         EgtOutLog("Error in Activate program : " & nret.ToString())
      End If

      global_state = eStateType.READY
      Return nret

   End Function
   '
   ' Set DPOsition Mode OP/OM
   '
   Public Overrides Sub set_OP_OM(n As Short)
      b_OM_pos = ( n = 0)
   End Sub
   '
   ' Read Once position
   ' returns 0 = OK ; > 0 error
   '
   Public Overrides Function DPOsition_ReadOnce() As Int16

      Return 1
   End Function
   '
   ' Set Cycle Start
   '
   Public Overrides Function DGeneralFunctions_CycleStart() As Int16

      Dim nret As Int16 = -1

      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If
      global_state = eStateType.BUSY

      nret = StartNC(n_portNC)

      global_state = eStateType.READY

      Return nret

   End Function
   '
   ' Set Feed Hold
   '
   Public Overrides Function DGeneralFunctions_FeedHold() As Int16

      Dim nret As Int16 = -1

      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If

      global_state = eStateType.BUSY

      nret = StopNC(n_portNC)

      global_state = eStateType.READY
      Return nret

   End Function
   '
   ' Set NC Reset
   '
   Public Overrides Function DGeneralFunctions_Reset() As Int16
      Dim nret As Int16 = -1

      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If

      global_state = eStateType.BUSY

      nret = InitNC(n_portNC)

      global_state = eStateType.READY
      Return nret

   End Function

   Public Overrides Function DGeneralFunctions_WriteCncMode(nmode As Short) As Int16

      ' Non controllare global_state, lo fa già la set_NC_mode

      Return set_NC_mode(nmode)

   End Function

   Public Overrides Function Write_var_1(sz_par As String, lvalue As Long) As Int16

      Dim nret As Int16 = -1
      Dim n_what As UInt16

      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If

      global_state = eStateType.BUSY

      If sz_par = "E80000" Then  ' !!! da sistemare per beccare anche gli altri indirizzi
         n_what = E80000
         MyData.data = BitConverter.GetBytes(lvalue)

         nret = WriteObjectVarious4(n_portNC, n_what, 0, 1, MyData)
      Else
         nret = -997
      End If

      global_state = eStateType.READY
      Return nret

   End Function
   '
   ' da PC a CN
   '
   Public Overrides Function Download_NC_prog(sz_PC_filename As String, sz_NC_filename As String) As Int16

      ' Verifico accessibilità CN
      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If
      ' Dichiaro CN occupato
      global_state = eStateType.BUSY

      ' Determino numero programma ( %900.0 -> 9000)
      Dim l As Int32 = get_Num_prog_number(sz_NC_filename)
      ' Trasmetto il programma
      Dim nRet As Int16 = DownLoadFile(n_portNC, l, sz_PC_filename)

      If nRet <> 0 Then
         EgtOutLog("Error in Download_NC_prog : " & nRet.ToString())
      End If

      ' Dichiaro CN libero
      global_state = eStateType.READY

      Return nRet

   End Function
   '
   ' da CN a pc
   '
   Public Overrides Function Upload_NC_prog(sz_PC_filename As String, sz_NC_filename As String) As Int16

      Dim nret As Int16 = -1

      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If

      global_state = eStateType.BUSY

      Dim l As Int32 = get_Num_prog_number(sz_NC_filename)

      nret = UpLoadFile(n_portNC, l, sz_PC_filename)

      global_state = eStateType.READY
      Return nret

   End Function

   Private Function get_Num_prog_number(sz_in As String) As Int32

      Dim sz_n As String = sz_in
      Dim n_prog_num As Int32

      If sz_n.Contains("%") Then sz_n = sz_n.Replace("%", "")

      If sz_n.Contains(".") Then
         sz_n = sz_n.Replace(".", "")
         n_prog_num = CInt(sz_n)
      Else
         n_prog_num = 10 * CInt(sz_n)
      End If

      Return n_prog_num

   End Function

   Public Overrides Function Delete_NC_prog(sz_NC_filename As String) As Int16

      Dim nret As Int16 = -1

      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If

      global_state = eStateType.BUSY

      Dim l As Int32 = get_Num_prog_number(sz_NC_filename)

      nret = DncDeleteFile(n_portNC, l)

      If nret <> 0 Then
         EgtOutLog("Error in Delete_NC_prog : " & nret.ToString())
      End If

      global_state = eStateType.READY
      Return nret

   End Function

   Public Overrides Function DTool_set_read_range(n_start As Short, n_stop As Short) As Int16

      Dim nret As Int16 = -1

      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If

      global_state = eStateType.BUSY

      nret = ReadTool(n_portNC, n_start, 1, MyData, SYN)

      If nret = RET_OK Then

         Tools(0).lenght = 0 ' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         Tools(0).radius = 0
         Tools(0).comp_num = 0

         b_Tool_data_changed = True

      End If

      global_state = eStateType.READY
      Return nret

   End Function

   Public Overrides Function DTool_write_tool(n_tool_number As Short, Length_X As Double, Radius As Double, TipRadius_Z As Double,
                                       DLength_X As Double, DTipRadius_Z As Double,
                                       nDirection As Short, nType As Short, nH As Integer) As Int16
      Dim Tool As tCorOutil

      Dim nret As Int16 = -1

      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If

      global_state = eStateType.BUSY

      ' da rifare !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

      Tool.L_X = CLng(Length_X * 1000)
      Tool.R_Radus = CLng(Radius * 1000)
      Tool.RTore_Z = CLng(TipRadius_Z * 1000)
      Tool.DL_DX = 0
      Tool.DR_DZ = 0
      Tool.Direc = 0
      Tool.Type = 0

      nret = WriteTool(n_portNC, n_tool_number, 1, Tool)

      global_state = eStateType.READY
      Return nret

   End Function

   Public Overrides Function get_free_memory(n_zone As Int16) As Long
      '
      '
      ' usare zona 0
      '
      Dim nret As Int16 = -1

      Dim l_free_mem As Long

      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If

      global_state = eStateType.BUSY

      nret = ReadMemoryFree(n_portNC, l_free_mem, n_zone)

      global_state = eStateType.READY

      If nret = 0 Then
         Return l_free_mem
      Else
         Return -9999
      End If

   End Function

   Public Overrides Function read_active_mode() As Int16

      Return (Var600D)  ' es 0 = auto, ecc.

   End Function

   Public Overrides Function Is_G24_active() As Boolean
      Return (( Var6003 And &H2) <> 0)
   End Function

   Public Overrides Function get_program_status() As Int16

      Dim nret As Int16 = -1

      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If

      global_state = eStateType.BUSY

      nret = ReadProgStatus(n_portNC, 0, 1, MyData, SYN)

      If nret = 0 Then

         l_GFunction = BitConverter.ToInt32(MyData.data, 0)
         l_active_program = BitConverter.ToInt32(MyData.data, 4)

         n_BlocExe = CUShort(BitConverter.ToInt16(MyData.data, 8))
         n_ProgError = BitConverter.ToInt16(MyData.data, 10)
         n_BlocError = CUShort(BitConverter.ToInt16(MyData.data, 12))
         n_Tool = CUShort(BitConverter.ToInt16(MyData.data, 14))
         n_Direction = CUShort(BitConverter.ToInt16(MyData.data, 16))
         n_Corrector = CUShort(BitConverter.ToInt16(MyData.data, 18))
         n_LeftFunct = CUShort(BitConverter.ToInt16(MyData.data, 20))
      End If

      global_state = eStateType.READY

      Return nret
   End Function

   Public Overrides Function get_plc_messages() As Int16

      If VerifyBusy() <> eStateType.READY Then
         Return global_state
      End If
      Return get_errors()

   End Function

   Private Function get_errors() As Int16

      Const GROUP_ACTIVE As UInt16 = &HFFFF ' 0xFFFF=Groupe Actif

      Const MORE_MESSAGES As UInt16 = 6
      Const NO_MORE_MESSAGES As UInt16 = 15

      Dim nret As Int16 = -1, i As Short = 0

      Dim nErrorLineNum As Int16 = 0

      Dim b_int_NC_error As Boolean = False

      Dim szt As String = ""

      If global_state <> eStateType.READY Then
         Return global_state
      End If

      global_state = eStateType.BUSY

      ' PLC errors
      b_PLC_error = False
      SyncLock Me
         sz_PLC_error_messages = "PLC Errors : "
      End SyncLock
      iFirstVar = &H7000   ' messaggio 0 " MACCHINA OK "

      nret = ReadLadderVar(n_portNC, VBY, iFirstVar, 100, MyData, SYN)    ' max 120 bytes....
      If nret = 0 Then  ' 253 = troppi dati

         For i = 0 To 100 - 1
            If MyData.data(i) <> 0 Then
               b_PLC_error = True
               SyncLock Me
                  sz_PLC_error_messages = sz_PLC_error_messages & " " & i.ToString
               End SyncLock
            End If
         Next

         iFirstVar = &H7000 + 100  ' messaggio 100 

         nret = ReadLadderVar(n_portNC, VBY, iFirstVar, 50, MyData2, SYN)
         If nret = 0 Then  ' 253 = troppi dati

            For i = 0 To 50 - 1
               If MyData2.data(i) <> 0 Then
                  b_PLC_error = True
                  SyncLock Me
                     sz_PLC_error_messages = sz_PLC_error_messages & " " & (i + 100).ToString
                  End SyncLock
               End If
            Next

         End If
      End If

      '--------------------------------------------------------------------------
      ' Visualizzazione errore CN

      b_NC_error = False
      SyncLock Me
         sz_NC_error_messages.Clear()
      End SyncLock
      b_int_NC_error = False

      iFirstVar = &H3
      nret = ReadLadderVar(n_portNC, R6, iFirstVar, 1, MyData, SYN)

      If MyData.data(0) <> 0 Then
         b_int_NC_error = True
      End If

      If b_int_NC_error Then

         nErrorLineNum = 0

         n_ReadStatus = MORE_MESSAGES

         While (n_ReadStatus = MORE_MESSAGES)

            nret = DNC40_ReadCncError(n_portNC, GROUP_ACTIVE, nErrorLineNum, MyData, SYN)

            If nret = 0 Then

               ' ErrorNumber As Integer    'Numéro d'erreur
               ' ErrorBlockNum As Integer  'Numéro de bloc en erreur
               ' ReadStatus As Byte        'Status de lecture: 0x0F=pas de suite 0x06=suite
               ' MsgSize As Byte           'Nombre de caractères dans le message
               ' MsgTab As String * 122    'Message lu

               n_ErrorNumber = CUShort(BitConverter.ToInt16(MyData.data, 0))
               n_ErrorBlockNum = CUShort(BitConverter.ToInt16(MyData.data, 2))
               n_ReadStatus = MyData.data(4)
               n_MsgSize = MyData.data(5)

               If n_ErrorNumber <> 0 Then

                  For i = 0 To CShort(n_MsgSize) - 1S
                     szt = szt & System.Convert.ToChar(MyData.data(i + 6))
                  Next

                  SyncLock Me
                     sz_NC_error_messages.Add(szt) ' add this message to the error message list
                  End SyncLock
               End If

               nErrorLineNum = nErrorLineNum + 1S
            Else
               n_ReadStatus = NO_MORE_MESSAGES
            End If

         End While

         b_NC_error = True
      End If ' any error

      global_state = eStateType.READY

      Return nret

   End Function

   Function VerifyBusy() As eStateType
      For I As Integer = 0 To 50
         If global_state <> eStateType.READY Then
            System.Threading.Thread.Sleep(SLEEP_TIME)
         Else
            Exit For
         End If
      Next

      Return global_state

   End Function

#End Region

End Class

End Namespace