Imports Microsoft.Win32
Imports CMSCncLib.App.Runtime
Imports CMSCncLib.Config.Settings
Imports System.Drawing

Namespace CNC

    Partial Public Class FANUC
        Inherits CNC

        Const N_BYTE_TYPE = 0
        Const N_WORD_TYPE = 1
        Const N_DWORD_TYPE = 2
        Public Const G_PARAM = 0
        Public Const F_PARAM = 1
        Public Const Y_PARAM = 2
        Public Const X_PARAM = 3
        Public Const A_PARAM = 4
        Public Const R_PARAM = 5
        Public Const T_PARAM = 6
        Public Const K_PARAM = 7
        Public Const C_PARAM = 8
        Public Const D_PARAM = 9
        Public Const M_PARAM = 10
        Public Const N_PARAM = 11
        Public Const E_PARAM = 12
        Public Const Z_PARAM = 13
        Public Const CM_PARAM = 100

        Const F_MAX_ITEM = 8
        Const F_MAX_MACRO = 5


        Public Enum MemType
            G = 0
            F = 1
            Y = 2
            X = 3
            A = 4
            R = 5
            T = 6
            K = 7
            C = 8
            D = 9
            M = 10
            N = 11
            E = 12
            Z = 13
            CM = 100
        End Enum

        Private _connectionType As ConnectionType
        Private _szIp As String
        Private _nPortIp As Integer
        Private _CncScreen_connectionType As ConnectionType
        Private _nPathActive As Integer
        Private _nMaxPath As Integer
        Private _bMultiProcess As Boolean
        Friend focas As Focas1
        Friend nLibHandle(1) As Integer
        'Private _err As New Err

        Private CncScreen_ProcessName As String

        Public Enum ConnectionType
            Ethernet = 0
            Hssb = 1
        End Enum

        Private _Is16Series As Boolean
        Public ReadOnly Property Is16Series() As Boolean
            Get
                Return _Is16Series
            End Get
        End Property
        Private _Is30Series As Boolean = Not _Is16Series
        Public ReadOnly Property Is30Series() As Boolean
            Get
                Return _Is30Series
            End Get
        End Property

        Public Overrides Property Licenza() As Integer
            Get
                Dim uiLicence As UInteger
                'leggo dal cn il valore
                Me.F_RW_DWord(R, MemType.D, 7222, uiLicence)
                Return UnsignedToInteger(uiLicence)
            End Get
            Set(ByVal value As Integer)
                'setto sul cn il valore
                Dim uiLicence As UInteger = IntegerToUnsigned(value)
                Me.F_RW_DWord(W, MemType.D, 7222, uiLicence)
            End Set
        End Property

        Public Overrides Property LicenzaScaduta() As Boolean
            Get
                Dim bLicenzaScaduta As Boolean
                'leggo dal cn il valore
                Me.F_RW_Boolean(R, MemType.D, 7217, 5, bLicenzaScaduta)
                Return bLicenzaScaduta
            End Get
            Set(ByVal value As Boolean)
                'setto sul cn il valore
                Me.F_RW_Boolean(W, MemType.D, 7217, 5, value)
            End Set
        End Property

        Public Sub New(ByRef connectionType As ConnectionType, Optional ByRef szIp As String = "192.168.1.1",
                             Optional ByRef nPortIp As Integer = 8193, Optional ByRef CncScreenHssb As ConnectionType = FANUC.ConnectionType.Ethernet)
            MyBase.New()
            _Type = NcType.FANUC

            Try
                focas = New Focas1
            Catch ex As Exception
                MsgBox(ex.Message)
            End Try

            _connectionType = connectionType
            _szIp = szIp
            _nPortIp = nPortIp
            _CncScreen_connectionType = CncScreenHssb

            'Definisco l'area della Cnc Window
            'SetCncWindowSize()

            'Inizializzo le variabili
            Me._Descrizione = "NC FANUC" & vbNewLine
            Select Case _connectionType
                Case FANUC.ConnectionType.Ethernet
                    Me._Descrizione = Me._Descrizione & "Connection type: Ethernet" & vbNewLine &
                                      "Ip address: " & _szIp & vbNewLine &
                                      "Port: " & _nPortIp
                Case FANUC.ConnectionType.Hssb
                    Me._Descrizione = Me._Descrizione & "Connection type: HSSB" & vbNewLine &
                                      "Hssb node: " & Hssb_node.ToString
                Case Else
                    Me._Descrizione = Me._Descrizione & "Connection type: " & _connectionType.ToString & " !!!"
            End Select

            Select Case _CncScreen_connectionType
                Case FANUC.ConnectionType.Ethernet
                    Me.CncScreen_ProcessName = "CNCScrnE"
                Case FANUC.ConnectionType.Hssb
                    Me.CncScreen_ProcessName = "CNCScrn"
            End Select

        End Sub

        Public Overrides Sub Connect(Optional ByRef szStatus As String = "")
            Dim i As Integer
            Dim nReturn As Integer

            Select Case _connectionType
                Case ConnectionType.Ethernet
                    szStatus = "TRY cnc_allclibhndl3 Connect CNC.FANUC  Ip=" & _szIp & " Port=" & _nPortIp
                    nReturn = Focas1.cnc_allclibhndl3(_szIp, _nPortIp, 5, nLibHandle(1))
                    If F_CheckRetError_Cnc(nReturn, "cnc_allclibhndl3 Connect CNC.FANUC") Then
                        szStatus = "ERR cnc_allclibhndl3 Connect CNC.FANUC  Return=" & nReturn
                        Focas1.cnc_freelibhndl(nLibHandle(1))
                        _bConnected = False
                        Throw New CmsNcException("ERR cnc_allclibhndl3 Connect CNC.FANUC")
                        Exit Sub
                    Else
                        'leggo la serie del cnc
                        szStatus = "TRY F_GetCncSeries Connect CNC.FANUC"
                        F_GetCncSeries()
                        'leggo il numero di processi e setto il primo
                        szStatus = "TRY cnc_getpath Connect CNC.FANUC"
                        nReturn = Focas1.cnc_getpath(nLibHandle(1), _nPathActive, _nMaxPath)
                        If F_CheckRetError_Cnc(nReturn, "cnc_getpath Connect CNC.FANUC") Then
                            szStatus = "ERR cnc_getpath Connect CNC.FANUC  Return=" & nReturn
                            Focas1.cnc_freelibhndl(nLibHandle(1))
                            _bConnected = False
                            Throw New CmsNcException("ERR cnc_getpath Connect CNC.FANUC")
                            Exit Sub
                        Else
                            If _nMaxPath > 1 Then
                                _bMultiProcess = True
                                nReturn = Focas1.cnc_setpath(nLibHandle(1), 1)
                                If F_CheckRetError_Cnc(nReturn, "cnc_setpath Connect CNC.FANUC") Then
                                    szStatus = "ERR cnc_setpath Connect CNC.FANUC  Return=" & nReturn
                                    Focas1.cnc_freelibhndl(nLibHandle(1))
                                    _bConnected = False
                                    Throw New CmsNcException("ERR cnc_setpath Connect CNC.FANUC")
                                    Exit Sub
                                Else
                                    ReDim Preserve nLibHandle(_nMaxPath)
                                    For i = 2 To _nMaxPath
                                        szStatus = "TRY cnc_allclibhndl3 Connect CNC.FANUC to Path " & i & " Ip=" & _szIp & " Port=" & _nPortIp
                                        nReturn = Focas1.cnc_allclibhndl3(_szIp, _nPortIp, 5, nLibHandle(i))
                                        If F_CheckRetError_Cnc(nReturn, "cnc_allclibhndl3 Connect CNC.FANUC to Path " & i) Then
                                            szStatus = "ERR cnc_allclibhndl3 Connect CNC.FANUC to Path " & i & " Return=" & nReturn
                                            Focas1.cnc_freelibhndl(nLibHandle(i))
                                            _bConnected = False
                                            Throw New CmsNcException("ERR cnc_allclibhndl3 Connect CNC.FANUC to Path " & i)
                                            Exit Sub
                                        Else
                                            nReturn = Focas1.cnc_setpath(nLibHandle(i), i)
                                            If F_CheckRetError_Cnc(nReturn, "cnc_setpath Connect CNC.FANUCto Path " & i) Then
                                                szStatus = "ERR cnc_setpath Connect CNC.FANUC to Path " & i & " Return=" & nReturn
                                                Focas1.cnc_freelibhndl(nLibHandle(i))
                                                _bConnected = False
                                                Throw New CmsNcException("ERR cnc_setpath Connect CNC.FANUC to Path " & i)
                                                Exit Sub
                                            Else
                                                _bConnected = True
                                            End If
                                        End If
                                    Next i
                                End If

                            Else
                                _bConnected = True
                            End If
                        End If

                    End If

                Case ConnectionType.Hssb
                    Hssb_node = HSSB_DEFAULT_NODE

                    szStatus = "TRY cnc_allclibhndl2 Connect CNC.FANUC"
                    nReturn = Focas1.cnc_allclibhndl2(Hssb_node, nLibHandle(1))
                    If F_CheckRetError_Cnc(nReturn, "cnc_allclibhndl2 Connect CNC.FANUC") Then
                        szStatus = "ERR cnc_allclibhndl2 Connect CNC.FANUC  Return=" & nReturn
                        Focas1.cnc_freelibhndl(nLibHandle(1))
                        _bConnected = False
                        Throw New CmsNcException("ERR cnc_allclibhndl2 Connect CNC.FANUC")
                        Exit Sub
                    Else
                        _bConnected = True
                    End If
            End Select

        End Sub

        Public Overrides Sub Disconnect(Optional ByRef szStatus As String = "")
            Dim i As Integer
            Dim nReturn As Integer

            For i = 1 To UBound(nLibHandle)
                nReturn = Focas1.cnc_freelibhndl(nLibHandle(i))
                If nReturn <> Focas1.EW_OK Then
                    _bConnected = False '?
                Else
                    _bConnected = False
                End If
            Next i
        End Sub

        ''' <summary>
        ''' Get class series of CNC: 16 or 30
        ''' </summary>
        ''' <returns>Series</returns>
        ''' <remarks>After, use Is16Series and Is30Series for discriminate</remarks>
        Public Function F_GetCncSeries() As Integer
            Dim nReturn As Integer
            Dim nOdb As Focas1.ODBSYS
            Dim nSeries As Integer

            nOdb = New Focas1.ODBSYS
            nReturn = Focas1.cnc_sysinfo(nLibHandle(1), nOdb)
            If F_CheckRetError_Cnc(nReturn, "cnc_sysinfo F_GetCncSeries CNC.FANUC") Then
                Throw New CmsNcException("ERR cnc_sysinfo F_GetCncSeries CNC.FANUC")
            Else
                nSeries = Val(nOdb.cnc_type)
                If nSeries >= 30 Then
                    _Is16Series = False
                    _Is30Series = True
                Else
                    _Is16Series = True
                    _Is30Series = False
                End If
            End If

            Return nSeries
        End Function

        ''' <summary>
        ''' Legge le memorie di configurazione dal cn
        ''' </summary>
        Public Overrides Sub GetStaticData()
            Dim usValue As UShort
            Dim uiValue As UInteger
            Dim cVal As Byte

            If Not bStaticDataReaded Then

                Try
                    'Matricola
                    F_RW_Word(R, MemType.D, 4018, usValue)
                    Me._Matricola = usValue
                    'Teste
                    F_RW_Word(R, MemType.D, 4032, usValue)
                    Me._Teste = usValue
                    'Magazzini
                    F_RW_Word(R, MemType.D, 4036, usValue)
                    Me._Magazzini = usValue

                    'Manine per Magazzino
                    ReDim Me._ManineMagazzino(Me._Magazzini - 1)
                    Select Case Settings.MemoryMapping
                        Case MemoryMapping.ElsManager
                            Dim usValueA(8 - 1) As UShort
                            Dim cValueB(12 - 1) As Byte
                            F_RW_Word(R, MemType.D, 4038, usValueA)
                            F_RW_Byte(R, MemType.D, 6780, cValueB)
                            For i = 0 To Me._Magazzini - 1
                                If i < 8 Then
                                    _ManineMagazzino(i) = CInt(usValueA(i))
                                Else
                                    _ManineMagazzino(i) = CInt(cValueB(i))
                                End If
                            Next
                        Case MemoryMapping.ToolManager,
                             MemoryMapping.ToolTable,
                             MemoryMapping.Default
                            Dim cValue(20 - 1) As Byte
                            F_RW_Byte(False, MemType.D, 3040, cValue)
                            For i = 0 To Me._Magazzini - 1
                                Me._ManineMagazzino(i) = CInt(cValue(i))
                            Next
                    End Select

                    'Magazzini Con Attrezzaggio Automatico (maschera)
                    F_RW_DWord(R, MemType.D, 8819, uiValue)
                    Me._MagazziniConAttrezzaggioAutomatico = UnsignedToInteger(uiValue)

                    'MaxUtensili
                    Dim odbtlinf As Focas1.ODBTLINF = New Focas1.ODBTLINF
                    'Reads the memory type of tool offset, and the available number of it.
                    Focas1.cnc_rdtofsinfo(nLibHandle(1), odbtlinf)
                    If F_CheckRetError_Cnc(Focas1.cnc_rdtofsinfo(nLibHandle(1), odbtlinf), "cnc_rdtofsinfo GetStaticData CNC.FANUC") Then
                        Throw New CmsNcException("ERR cnc_rdtofsinfo GetStaticData CNC.FANUC")
                    End If

                    Me._MaxUtensiliGestibili = odbtlinf.use_no
                    Me._MaxIdUtensile = odbtlinf.use_no

                    'ZoomSpeed
                    Select Case Settings.MemoryMapping
                        Case MemoryMapping.ElsManager
                            F_RW_Byte(R, MemType.D, 6792, cVal)
                        Case MemoryMapping.ToolManager,
                             MemoryMapping.ToolTable,
                             MemoryMapping.Default
                            F_RW_Byte(R, MemType.D, 3330, cVal)
                    End Select
                    If cVal > 0 And cVal <= 100 Then
                        Me._ZoomSpeed = cVal
                    Else
                        Me._ZoomSpeed = 1
                    End If

                    bStaticDataReaded = True

                Catch ex As CmsNcException
                    Me.CncException(ex.Message)
                End Try

            End If
        End Sub

        ''' <summary>
        ''' Legge il numero del processo attivo
        ''' </summary>
        ''' <returns>Processo attivo</returns>
        Public Function GetActivePath() As Integer
            Dim bValue As Boolean
            Dim nPathIdx As Integer

            nPathIdx = 1

            F_RW_Boolean(R, MemType.G, 63, 0, bValue)
            If bValue Then nPathIdx = nPathIdx + 1

            F_RW_Boolean(R, MemType.G, 62, 7, bValue)
            If bValue Then nPathIdx = nPathIdx + 2

            F_RW_Boolean(R, MemType.G, 408, 1, bValue)
            If bValue Then nPathIdx = nPathIdx + 4

            F_RW_Boolean(R, MemType.G, 408, 2, bValue)
            If bValue Then nPathIdx = nPathIdx + 8

            Return nPathIdx

            ''leggo il numero del processo attivo
            'Dim nReturn, nPathActive, nMaxPath As Integer
            'nReturn = Focas1.cnc_getpath(FANUC_ref.nLibHandle(1), nPathActive, nMaxPath)
            'If nPathActive < 1 Or nPathActive > nMaxPath Then nPathActive = 1

            '21/07/2015 Il codice sopra è ereditato da OpPaneled è funzionante
            '           verificare se questo sopra commentato possa sostituirlo ed è più efficiente
        End Function

        ''' <summary>
        ''' Legge o scrive Boolean da MEMORIE PLC
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MemType">Tipo di memoria Fanuc</param>
        ''' <param name="MemIndex">Indice di memoria</param>
        ''' <param name="MemBit">Bit della memoria</param>
        ''' <param name="Value">Valore da scrivere su scrittura e letto su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Function F_RW_Boolean(ByVal bWrite As Boolean, ByVal MemType As MemType, ByVal MemIndex As Integer, ByVal MemBit As Integer, ByRef Value As Boolean) As Boolean
            Dim iodb0 As Focas1.IODBPMC0
            Dim nlength As Integer
            Dim nReturn As Integer
            Dim nValue As Short

            iodb0 = New Focas1.IODBPMC0
            iodb0.type_a = MemType
            iodb0.type_d = N_BYTE_TYPE
            iodb0.datano_s = MemIndex
            iodb0.datano_e = MemIndex
            nlength = 8 + 1

            'leggo la memoria
            nReturn = Focas1.pmc_rdpmcrng(nLibHandle(1), iodb0.type_a, iodb0.type_d, iodb0.datano_s, iodb0.datano_e, nlength, iodb0)
            If F_CheckRetError_Pmc(nReturn, "pmc_rdpmcrng F_RW_Boolean CNC.FANUC") Then
                Throw New CmsNcException("ERR pmc_rdpmcrng F_RW_Boolean CNC.FANUC")
                Return False
            Else
                nValue = iodb0.cdata(0)

                If bWrite Then ' *** Write
                    If Value Then 'True
                        nValue = nValue Or (2 ^ MemBit)
                    Else 'False
                        nValue = nValue And Not (2 ^ MemBit)
                    End If
                    iodb0.cdata(0) = nValue
                    nReturn = Focas1.pmc_wrpmcrng(nLibHandle(1), nlength, iodb0)
                    If nReturn = Focas1.EW_SOCKET Then
                        Throw New CmsNcException("ERR pmc_wrpmcrng CNC.FANUC")
                        Return False
                    ElseIf nReturn <> Focas1.EW_OK Then
                        'CMSCncLib.App.Runtime.Log.WW("ERR pmc_wrpmcrng on F_RW_Boolean CNC.FANUC", "Return=" & nReturn, True)
                        Return False
                    End If

                Else ' ************* Read
                    If (nValue And (2 ^ MemBit)) = (2 ^ MemBit) Then 'True
                        Value = True
                    Else 'False
                        Value = False
                    End If
                End If
            End If

            Return True
        End Function

        ''' <summary>
        ''' Legge o scrive Byte da MEMORIE PLC
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MemType">Tipo di memoria Fanuc</param>
        ''' <param name="MemIndex">Indice di memoria</param>
        ''' <param name="Value">Matrice di valori da scrivere su scrittura o letti su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_Byte(ByVal bWrite As Boolean, ByVal MemType As MemType, ByVal MemIndex As Integer, ByRef Value() As Byte) As Boolean
            Dim iodb0 As Focas1.IODBPMC0
            Dim nlength As Integer
            Dim nReturn As Integer
            Dim nQta As Integer
            Dim nBlock As Integer
            Dim nMod As Integer

            If Value Is Nothing Then Throw New InvalidOperationException

            'Calcolo la dimesione dell'array
            nBlock = Value.Length \ F_MAX_ITEM
            nMod = Value.Length Mod F_MAX_ITEM
            If nMod > 0 Then nBlock += 1

            For b = 0 To nBlock - 1
                If b < nBlock - 1 Then
                    nQta = F_MAX_ITEM
                Else
                    nQta = IIf(nMod > 0, nMod, F_MAX_ITEM)
                End If

                'Setto il tipo di memoria
                iodb0 = New Focas1.IODBPMC0
                iodb0.type_a = MemType
                iodb0.type_d = N_BYTE_TYPE
                iodb0.datano_s = MemIndex + b * F_MAX_ITEM
                iodb0.datano_e = MemIndex + b * F_MAX_ITEM + nQta - 1
                nlength = 8 + nQta

                If bWrite Then ' *** Write
                    ReDim iodb0.cdata(8 - 1)
                    For i = 0 To nQta - 1
                        iodb0.cdata(i) = Value(i + b * F_MAX_ITEM)
                    Next
                    nReturn = Focas1.pmc_wrpmcrng(nLibHandle(1), nlength, iodb0)
                    If F_CheckRetError_Pmc(nReturn, "pmc_wrpmcrng F_RW_Byte CNC.FANUC") Then
                        Throw New CmsNcException("ERR pmc_wrpmcrng F_RW_Byte CNC.FANUC")
                        Return False
                    End If

                Else ' ************* Read
                    nReturn = Focas1.pmc_rdpmcrng(nLibHandle(1), iodb0.type_a, iodb0.type_d, iodb0.datano_s, iodb0.datano_e, nlength, iodb0)
                    If F_CheckRetError_Pmc(nReturn, "pmc_rdpmcrng F_RW_Byte CNC.FANUC") Then
                        Throw New CmsNcException("ERR pmc_rdpmcrng F_RW_Byte CNC.FANUC")
                        Return False
                    Else
                        For i = 0 To nQta - 1
                            Value(i + b * F_MAX_ITEM) = iodb0.cdata(i)
                        Next
                    End If
                End If
            Next

            Return True
        End Function

        ''' <summary>
        ''' Legge o scrive Byte da MEMORIE PLC
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MemType">Tipo di memoria Fanuc</param>
        ''' <param name="MemIndex">Indice di memoria</param>
        ''' <param name="Value">Valore da scrivere su scrittura o letto su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_Byte(ByVal bWrite As Boolean, ByVal MemType As MemType, ByVal MemIndex As Integer, ByRef Value As Byte) As Boolean
            Dim bRet As Boolean
            Dim cValue(0) As Byte
            If bWrite Then cValue(0) = Value
            bRet = F_RW_Byte(bWrite, MemType, MemIndex, cValue)
            If Not bWrite Then Value = cValue(0)
            Return bRet
        End Function

        ''' <summary>
        ''' Legge o scrive Word da MEMORIE PLC
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MemType">Tipo di memoria Fanuc</param>
        ''' <param name="MemIndex">Indice di memoria</param>
        ''' <param name="Value">Matrice di valori da scrivere su scrittura o letti su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_Word(ByVal bWrite As Boolean, ByVal MemType As MemType, ByVal MemIndex As Integer, ByRef Value() As UShort) As Boolean
            Dim iodb1 As Focas1.IODBPMC1
            Dim nlength As Integer
            Dim nReturn As Integer
            Dim nQta As Integer
            Dim nBlock As Integer
            Dim nMod As Integer

            If Value Is Nothing Then Throw New InvalidOperationException

            'Calcolo la dimesione dell'array
            nBlock = Value.Length \ F_MAX_ITEM
            nMod = Value.Length Mod F_MAX_ITEM
            If nMod > 0 Then nBlock += 1

            For b = 0 To nBlock - 1
                If b < nBlock - 1 Then
                    nQta = F_MAX_ITEM
                Else
                    nQta = IIf(nMod > 0, nMod, F_MAX_ITEM)
                End If

                'Setto il tipo di memoria
                iodb1 = New Focas1.IODBPMC1
                iodb1.type_a = MemType
                iodb1.type_d = N_WORD_TYPE
                iodb1.datano_s = MemIndex + (b * F_MAX_ITEM * 2)
                iodb1.datano_e = MemIndex + (b * F_MAX_ITEM * 2) + (nQta * 2) - 1
                nlength = 8 + (nQta * 2)

                If bWrite Then ' *** Write
                    ReDim iodb1.idata(8 - 1)
                    For i = 0 To nQta - 1
                        iodb1.idata(i) = Value(i + b * F_MAX_ITEM)
                    Next
                    nReturn = Focas1.pmc_wrpmcrng(nLibHandle(1), nlength, iodb1)
                    If F_CheckRetError_Pmc(nReturn, "pmc_wrpmcrng F_RW_Word CNC.FANUC") Then
                        Throw New CmsNcException("ERR pmc_wrpmcrng F_RW_Word CNC.FANUC")
                        Return False
                    End If

                Else ' ************* Read
                    nReturn = Focas1.pmc_rdpmcrng(nLibHandle(1), iodb1.type_a, iodb1.type_d, iodb1.datano_s, iodb1.datano_e, nlength, iodb1)
                    If F_CheckRetError_Pmc(nReturn, "pmc_rdpmcrng F_RW_Word CNC.FANUC") Then
                        Throw New CmsNcException("ERR pmc_rdpmcrng F_RW_Word CNC.FANUC")
                        Return False
                    Else
                        For i = 0 To nQta - 1
                            Value(i + b * F_MAX_ITEM) = iodb1.idata(i)
                        Next
                    End If
                End If
            Next

            Return True
        End Function

        ''' <summary>
        ''' Legge o scrive Short da MEMORIE PLC
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MemType">Tipo di memoria Fanuc</param>
        ''' <param name="MemIndex">Indice di memoria</param>
        ''' <param name="Value">Matrice di valori da scrivere su scrittura o letti su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_Short(ByVal bWrite As Boolean, ByVal MemType As MemType, ByVal MemIndex As Integer, ByRef Value() As Short) As Boolean
            Dim bReturn As Boolean
            Dim usValue(Value.Length - 1) As UShort

            If bWrite Then ' *** Write
                For i = 0 To Value.Length - 1
                    usValue(i) = ShortToUnsigned(Value(i))
                Next
                bReturn = F_RW_Word(bWrite, MemType, MemIndex, usValue)

            Else ' ************* Read
                bReturn = F_RW_Word(bWrite, MemType, MemIndex, usValue)
                For i = 0 To Value.Length - 1
                    Value(i) = UnsignedToShort(usValue(i))
                Next
            End If

            Return bReturn
        End Function

        ''' <summary>
        ''' Legge o scrive Word da MEMORIE PLC
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MemType">Tipo di memoria Fanuc</param>
        ''' <param name="MemIndex">Indice di memoria</param>
        ''' <param name="Value">Valore da scrivere su scrittura o letto su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_Word(ByVal bWrite As Boolean, ByVal MemType As MemType, ByVal MemIndex As Integer, ByRef Value As UShort) As Boolean
            Dim bRet As Boolean
            Dim usValue(0) As UShort
            If bWrite Then usValue(0) = Value
            bRet = F_RW_Word(bWrite, MemType, MemIndex, usValue)
            If Not bWrite Then Value = usValue(0)
            Return bRet
        End Function

        ''' <summary>
        ''' Legge o scrive Short da MEMORIE PLC
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MemType">Tipo di memoria Fanuc</param>
        ''' <param name="MemIndex">Indice di memoria</param>
        ''' <param name="Value">Valore da scrivere su scrittura o letto su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_Short(ByVal bWrite As Boolean, ByVal MemType As MemType, ByVal MemIndex As Integer, ByRef Value As Short) As Boolean
            Dim bRet As Boolean
            Dim sValue(0) As Short
            If bWrite Then sValue(0) = Value
            bRet = F_RW_Short(bWrite, MemType, MemIndex, sValue)
            If Not bWrite Then Value = sValue(0)
            Return bRet
        End Function

        ''' <summary>
        ''' Legge DWord da MEMORIE PLC
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MemType">Tipo di memoria Fanuc</param>
        ''' <param name="MemIndex">Indice di memoria</param>
        ''' <param name="Value">Matrice di valori da scrivere su scrittura o letti su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_DWord(ByVal bWrite As Boolean, ByVal MemType As MemType, ByVal MemIndex As Integer, ByRef Value() As UInteger) As Boolean
            Dim iodb2 As Focas1.IODBPMC2
            Dim nlength As Integer
            Dim nReturn As Integer
            Dim nQta As Integer
            Dim nBlock As Integer
            Dim nMod As Integer

            If Value Is Nothing Then Throw New InvalidOperationException

            'Calcolo la dimesione dell'array
            nBlock = Value.Length \ F_MAX_ITEM
            nMod = Value.Length Mod F_MAX_ITEM
            If nMod > 0 Then nBlock += 1

            For b = 0 To nBlock - 1
                If b < nBlock - 1 Then
                    nQta = F_MAX_ITEM
                Else
                    nQta = IIf(nMod > 0, nMod, F_MAX_ITEM)
                End If

                'Setto il tipo di memoria
                iodb2 = New Focas1.IODBPMC2
                iodb2.type_a = MemType
                iodb2.type_d = N_DWORD_TYPE
                iodb2.datano_s = MemIndex + (b * F_MAX_ITEM * 4)
                iodb2.datano_e = MemIndex + (b * F_MAX_ITEM * 4) + (nQta * 4) - 1
                nlength = 8 + (nQta * 4)

                If bWrite Then ' *** Write
                    ReDim iodb2.ldata(8 - 1)
                    For i = 0 To nQta - 1
                        iodb2.ldata(i) = Value(i + b * F_MAX_ITEM)
                    Next
                    nReturn = Focas1.pmc_wrpmcrng(nLibHandle(1), nlength, iodb2)
                    If F_CheckRetError_Pmc(nReturn, "pmc_wrpmcrng F_RW_DWord CNC.FANUC") Then
                        Throw New CmsNcException("ERR pmc_wrpmcrng F_RW_DWord CNC.FANUC")
                        Return False
                    End If

                Else ' ************* Read
                    nReturn = Focas1.pmc_rdpmcrng(nLibHandle(1), iodb2.type_a, iodb2.type_d, iodb2.datano_s, iodb2.datano_e, nlength, iodb2)
                    If F_CheckRetError_Pmc(nReturn, "pmc_rdpmcrng F_RW_DWord CNC.FANUC") Then
                        Throw New CmsNcException("ERR pmc_rdpmcrng F_RW_DWord CNC.FANUC")
                        Return False
                    Else
                        For i = 0 To nQta - 1
                            Value(i + b * F_MAX_ITEM) = iodb2.ldata(i)
                        Next
                    End If
                End If
            Next

            Return True
        End Function

        ''' <summary>
        ''' Legge DWord da MEMORIE PLC
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MemType">Tipo di memoria Fanuc</param>
        ''' <param name="MemIndex">Indice di memoria</param>
        ''' <param name="Value">Valore da scrivere su scrittura o letto su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_DWord(ByVal bWrite As Boolean, ByVal MemType As MemType, ByVal MemIndex As Integer, ByRef Value As UInteger) As Boolean
            Dim bRet As Boolean
            Dim uiValue(0) As UInteger
            If bWrite Then uiValue(0) = Value
            bRet = F_RW_DWord(bWrite, MemType, MemIndex, uiValue)
            If Not bWrite Then Value = uiValue(0)
            Return bRet
        End Function

        ''' <summary>
        ''' Legge Integer da MEMORIE PLC
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MemType">Tipo di memoria Fanuc</param>
        ''' <param name="MemIndex">Indice di memoria</param>
        ''' <param name="Value">Matrice di valori da scrivere su scrittura o letti su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_Integer(ByVal bWrite As Boolean, ByVal MemType As MemType, ByVal MemIndex As Integer, ByRef Value() As Integer) As Boolean
            Dim iodb2 As Focas1.IODBPMC2
            Dim nlength As Integer
            Dim nReturn As Integer
            Dim nQta As Integer
            Dim nBlock As Integer
            Dim nMod As Integer

            If Value Is Nothing Then Throw New InvalidOperationException

            'Calcolo la dimesione dell'array
            nBlock = Value.Length \ F_MAX_ITEM
            nMod = Value.Length Mod F_MAX_ITEM
            If nMod > 0 Then nBlock += 1

            For b = 0 To nBlock - 1
                If b < nBlock - 1 Then
                    nQta = F_MAX_ITEM
                Else
                    nQta = IIf(nMod > 0, nMod, F_MAX_ITEM)
                End If

                'Setto il tipo di memoria
                iodb2 = New Focas1.IODBPMC2
                iodb2.type_a = MemType
                iodb2.type_d = N_DWORD_TYPE
                iodb2.datano_s = MemIndex + (b * F_MAX_ITEM * 4)
                iodb2.datano_e = MemIndex + (b * F_MAX_ITEM * 4) + (nQta * 4) - 1
                nlength = 8 + (nQta * 4)

                If bWrite Then ' *** Write
                    ReDim iodb2.ldata(8 - 1)
                    For i = 0 To nQta - 1
                        iodb2.ldata(i) = Value(i + b * F_MAX_ITEM)
                    Next
                    nReturn = Focas1.pmc_wrpmcrng(nLibHandle(1), nlength, iodb2)
                    If F_CheckRetError_Pmc(nReturn, "pmc_wrpmcrng F_RW_Integer CNC.FANUC") Then
                        Throw New CmsNcException("ERR pmc_wrpmcrng F_RW_Integer CNC.FANUC")
                        Return False
                    End If

                Else ' ************* Read
                    nReturn = Focas1.pmc_rdpmcrng(nLibHandle(1), iodb2.type_a, iodb2.type_d, iodb2.datano_s, iodb2.datano_e, nlength, iodb2)
                    If F_CheckRetError_Pmc(nReturn, "pmc_rdpmcrng F_RW_Integer CNC.FANUC") Then
                        Throw New CmsNcException("ERR pmc_rdpmcrng F_RW_Integer CNC.FANUC")
                        Return False
                    Else
                        For i = 0 To nQta - 1
                            Value(i + b * F_MAX_ITEM) = WordsToInteger(iodb2.ldata(i) And &HFFFF, (iodb2.ldata(i) And &HFFFF0000) >> 16)
                        Next
                    End If
                End If
            Next

            Return True
        End Function

        ''' <summary>
        ''' Legge Integer da MEMORIE PLC
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MemType">Tipo di memoria Fanuc</param>
        ''' <param name="MemIndex">Indice di memoria</param>
        ''' <param name="Value">Valore da scrivere su scrittura o letto su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_Integer(ByVal bWrite As Boolean, ByVal MemType As MemType, ByVal MemIndex As Integer, ByRef Value As Integer) As Boolean
            Dim bRet As Boolean
            Dim iValue(0) As Integer
            If bWrite Then iValue(0) = Value
            bRet = F_RW_Integer(bWrite, MemType, MemIndex, iValue)
            If Not bWrite Then Value = iValue(0)
            Return bRet
        End Function

        ''' <summary>
        ''' Legge o scrive Length and Radius Offset da tabella Utensili CN
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="ToolOffsetNumber">Numero dell'offset utensile</param>
        Public Overloads Sub F_RW_ToolOffset(ByVal bWrite As Boolean, ByVal ToolOffsetNumber As Integer, ByRef CutterRadius_Wear As Double, ByRef CutterRadius_Geometry As Double, ByRef ToolLenght_Wear As Double, ByRef ToolLenght_Geometry As Double)
            Dim iodbpsd_1 As Focas1.IODBPSD_1
            Dim odbtofs As Focas1.ODBTOFS
            Dim nReturn As Integer
            Dim bNcInInch As Boolean
            Dim bTtInInch As Boolean
            Dim valid_fig As Short
            Dim dec_fig_in(31) As Short
            Dim dec_fig_out(31) As Short

            iodbpsd_1 = New Focas1.IODBPSD_1
            odbtofs = New Focas1.ODBTOFS

            'Leggo se il CN è impostato in Inch (parametro 0.2)
            nReturn = Focas1.cnc_rdparam(nLibHandle(1), 0, 0, 4 + 1, iodbpsd_1)
            If F_CheckRetError_Cnc(nReturn, "cnc_rdparam F_RW_LengthOffset CNC.FANUC") Then
                Throw New CmsNcException("ERR cnc_rdparam F_RW_LengthOffset CNC.FANUC")
            End If
            bNcInInch = (iodbpsd_1.cdata And MASK_BIT2) = MASK_BIT2

            'Leggo se ToolTable è impostato in Inch
            bTtInInch = Config.Options.CurrentOptions.ToolTable_Inch

            'leggo le cifre decimali
            nReturn = Focas1.cnc_getfigure(nLibHandle(1), 1, valid_fig, dec_fig_in, dec_fig_out)
            If F_CheckRetError_Cnc(nReturn, "cnc_getfigure F_RW_LengthOffset CNC.FANUC") Then
                Throw New CmsNcException("ERR cnc_getfigure F_RW_LengthOffset CNC.FANUC")
            End If

            If bWrite Then ' *** Write
                For i = 0 To 3
                    Dim dblTmp As Double
                    Dim nTmp As Integer
                    Select Case i
                        Case 0 : dblTmp = CutterRadius_Wear
                        Case 1 : dblTmp = CutterRadius_Geometry
                        Case 2 : dblTmp = ToolLenght_Wear
                        Case 3 : dblTmp = ToolLenght_Geometry
                    End Select
                    'moltiplico per le cifre decimali
                    dblTmp *= 10 ^ dec_fig_in(0)
                    'riporto all'unità di misura di Nc
                    If bNcInInch And Not bTtInInch Then
                        nTmp = dblTmp / 25.4
                    ElseIf Not bNcInInch And bTtInInch Then
                        nTmp = dblTmp * 25.4
                    Else
                        nTmp = dblTmp
                    End If
                    nReturn = Focas1.cnc_wrtofs(nLibHandle(1), ToolOffsetNumber, i, 8, nTmp)
                    If F_CheckRetError_Pmc(nReturn, "cnc_wrtofs F_RW_ToolOffset CNC.FANUC") Then
                        Throw New CmsNcException("ERR cnc_wrtofs F_RW_ToolOffset CNC.FANUC")
                    End If
                Next

            Else ' ************* Read
                For i = 0 To 3
                    nReturn = Focas1.cnc_rdtofs(nLibHandle(1), ToolOffsetNumber, i, 8, odbtofs)
                    If F_CheckRetError_Pmc(nReturn, "cnc_rdtofs F_RW_ToolOffset CNC.FANUC") OrElse (odbtofs.datano <> ToolOffsetNumber Or odbtofs.type <> i) Then
                        Throw New CmsNcException("ERR cnc_rdtofs F_RW_ToolOffset CNC.FANUC")
                    Else
                        Dim dblTmp As Double
                        'riporto all'unità di misura di ToolTable
                        If bNcInInch And Not bTtInInch Then
                            dblTmp = odbtofs.data * 25.4
                        ElseIf Not bNcInInch And bTtInInch Then
                            dblTmp = odbtofs.data / 25.4
                        Else
                            dblTmp = odbtofs.data
                        End If
                        'divido per le cifre decimali
                        dblTmp /= 10 ^ dec_fig_in(0)
                        'memorizzo il dato
                        Select Case i
                            Case 0 : CutterRadius_Wear = dblTmp
                            Case 1 : CutterRadius_Geometry = dblTmp
                            Case 2 : ToolLenght_Wear = dblTmp
                            Case 3 : ToolLenght_Geometry = dblTmp
                        End Select
                    End If
                Next

            End If

        End Sub

        ''' <summary>
        ''' Cancella la tabella Utensili CN
        ''' </summary>
        Public Sub F_Clear_ToolOffsets()

            'Memo di tipo C

            Dim nMaxUt As Integer
            Dim iodbto_1_3 As Focas1.IODBTO_1_3
            Dim ofs_3 As Focas1.OFS_3 'OFS_3 Modificato per permettere di eleiminare tutti e 100 gli utensili
            Dim nReturn As Integer

            iodbto_1_3 = New Focas1.IODBTO_1_3
            ofs_3 = New Focas1.OFS_3

            nMaxUt = CMSCncLib.CNC.Runtime.NC.MaxIdUtensile

            Dim n As Integer
            n = nMaxUt \ 100
            n += IIf(nMaxUt Mod 100, 1, 0)


            For j = 1 To n

                iodbto_1_3.datano_s = ((j - 1) * 100) + 1
                If nMaxUt < iodbto_1_3.datano_s + 100 Then
                    iodbto_1_3.datano_e = nMaxUt
                Else
                    iodbto_1_3.datano_e = iodbto_1_3.datano_s + 99
                End If
                iodbto_1_3.ofs = ofs_3

                For i As Integer = 0 To 3
                    iodbto_1_3.type = i
                    nReturn = Focas1.cnc_wrtofsr(nLibHandle(1), 8 + 4 * (iodbto_1_3.datano_e - iodbto_1_3.datano_s + 1), iodbto_1_3)
                    If F_CheckRetError_Pmc(nReturn, "cnc_wrtofsr F_Clear_ToolOffsets CNC.FANUC") Then
                        Throw New CmsNcException("ERR cnc_wrtofsr F_Clear_ToolOffsets CNC.FANUC")
                    End If
                Next
            Next


        End Sub


        ''' <summary>
        ''' Legge o scrive Parametri Interi
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="Axis">0: assigns no axis, -1: assigns all axes </param>
        ''' <param name="ParamIndex">Indice di memoria</param>
        ''' <param name="Size">1 byte, 2 word, 3 dword</param>
        ''' <param name="Value">Matrice di valori da scrivere su scrittura o letti su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_Param_Integer(ByVal bWrite As Boolean, ByVal Axis As Integer, ByVal ParamIndex As Integer, ByVal Size As Integer, ByRef Value() As Object) As Boolean
            Dim iodbpsd1 As Focas1.IODBPSD_1 = Nothing
            Dim iodbpsd3 As Focas1.IODBPSD_3 = Nothing
            Dim nOdb As Focas1.ODBSYS
            Dim nlength As Integer
            Dim nQta As Integer
            Dim nReturn As Integer
            Dim nMemSize As Integer

            If bWrite And Value Is Nothing Then Throw New InvalidOperationException

            'Seleziono la dimensione della memoria
            Select Case Size
                Case 1 : nMemSize = 1
                Case 2 : nMemSize = 2
                Case 3 : nMemSize = 4
                Case Else : Throw New InvalidOperationException
            End Select

            'Setto se parametro singolo o su ogni asse
            If Axis >= 0 Then
                iodbpsd1 = New Focas1.IODBPSD_1
                nQta = 1
                nlength = 4 + (nMemSize * nQta)
            Else 'If Axis = -1 Then
                iodbpsd3 = New Focas1.IODBPSD_3
                nOdb = New Focas1.ODBSYS
                nReturn = Focas1.cnc_sysinfo(nLibHandle(1), nOdb)
                nQta = nOdb.axes.Length
                nlength = 4 + (nMemSize * nQta)
            End If

            If bWrite Then ' *** Write
                If nQta = 1 Then
                    iodbpsd1.datano = ParamIndex
                    Select Case Size
                        Case 1 : iodbpsd1.cdata = Value(0)
                        Case 2 : iodbpsd1.idata = Value(0)
                        Case 3 : iodbpsd1.ldata = Value(0)
                    End Select
                Else
                    iodbpsd3.datano = ParamIndex
                    For i = 0 To nQta - 1
                        Select Case Size
                            Case 1 : iodbpsd3.cdatas(i) = Value(i)
                            Case 2 : iodbpsd3.idatas(i) = Value(i)
                            Case 3 : iodbpsd3.ldatas(i) = Value(i)
                        End Select
                    Next
                End If

                If nQta = 1 Then
                    nReturn = Focas1.cnc_wrparam(nLibHandle(1), nlength, iodbpsd1)
                Else
                    nReturn = Focas1.cnc_wrparam(nLibHandle(1), nlength, iodbpsd3)
                End If
                If F_CheckRetError_Cnc(nReturn, "cnc_wrparam F_RW_Param_DWord CNC.FANUC") Then
                    Throw New CmsNcException("ERR cnc_wrparam F_RW_Param_DWord CNC.FANUC")
                    Return False
                End If

            Else ' ************* Read
                If nQta = 1 Then
                    nReturn = Focas1.cnc_rdparam(nLibHandle(1), ParamIndex, Axis, nlength, iodbpsd1)
                Else
                    nReturn = Focas1.cnc_rdparam(nLibHandle(1), ParamIndex, Axis, nlength, iodbpsd3)
                End If
                If F_CheckRetError_Pmc(nReturn, "cnc_rdparam F_RW_Param_DWord CNC.FANUC") Then
                    Throw New CmsNcException("ERR cnc_rdparam F_RW_Param_DWord CNC.FANUC")
                    Return False
                Else
                    If nQta = 1 Then
                        Select Case Size
                            Case 1 : Value(0) = iodbpsd1.cdata
                            Case 2 : Value(0) = iodbpsd1.idata
                            Case 3 : Value(0) = iodbpsd1.ldata
                        End Select
                    Else
                        For i = 0 To nQta - 1
                            Select Case Size
                                Case 1 : Value(i) = iodbpsd3.cdatas
                                Case 2 : Value(i) = iodbpsd3.idatas
                                Case 3 : Value(i) = iodbpsd3.ldatas
                            End Select
                        Next
                    End If
                End If
            End If

            Return True
        End Function

        ''' <summary>
        ''' Legge o scrive Parametri Interi
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MemIndex">Indice di memoria</param>
        ''' <param name="Size">1 byte, 2 word, 3 dword</param>
        ''' <param name="Value">Valore da scrivere su scrittura o letto su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_Param_Integer(ByVal bWrite As Boolean, ByVal MemIndex As Integer, ByVal Size As Integer, ByRef Value As Object) As Boolean
            Dim bRet As Boolean
            Dim oValue(0) As Object
            If bWrite Then oValue(0) = Value
            bRet = F_RW_Param_Integer(bWrite, 0, MemIndex, Size, oValue)
            If Not bWrite Then Value = oValue(0)
            Return bRet
        End Function



        ''' <summary>
        ''' Legge o scrive le variabile Custom Macro
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MacroIndex">Indice di memoria</param>
        ''' <param name="Value">Matrice di valori da scrivere su scrittura o letti su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_Macro_Short(ByVal bWrite As Boolean, ByVal MacroIndex As Integer, ByRef Value() As Short) As Boolean
            Dim iodbmr As Focas1.IODBMR
            Dim nlength As Integer
            Dim nReturn As Integer
            Dim nQta As Integer
            Dim nBlock As Integer
            Dim nMod As Integer
            Dim nActivePath As Integer

            If Value Is Nothing Then Throw New InvalidOperationException

            nActivePath = GetActivePath()

            'Calcolo la dimesione dell'array
            nBlock = Value.Length \ F_MAX_MACRO
            nMod = Value.Length Mod F_MAX_MACRO
            If nMod > 0 Then nBlock += 1

            For b = 0 To nBlock - 1
                If b < nBlock - 1 Then
                    nQta = F_MAX_MACRO
                Else
                    nQta = IIf(nMod > 0, nMod, F_MAX_MACRO)
                End If

                'Setto il tipo di memoria
                iodbmr = New Focas1.IODBMR
                iodbmr.datano_s = MacroIndex + (b * F_MAX_MACRO)
                iodbmr.datano_e = MacroIndex + (b * F_MAX_MACRO) + nQta - 1
                nlength = 8 + (nQta * 8)

                If bWrite Then ' *** Write
                    iodbmr.data = New Focas1.IODBMR1
                    iodbmr.data.data1 = New Focas1.IODBMR_data
                    iodbmr.data.data2 = New Focas1.IODBMR_data
                    iodbmr.data.data3 = New Focas1.IODBMR_data
                    iodbmr.data.data4 = New Focas1.IODBMR_data
                    iodbmr.data.data5 = New Focas1.IODBMR_data

                    If nQta >= 1 Then iodbmr.data.data1.mcr_val = Value(0 + b * F_MAX_MACRO)
                    If nQta >= 2 Then iodbmr.data.data2.mcr_val = Value(1 + b * F_MAX_MACRO)
                    If nQta >= 3 Then iodbmr.data.data3.mcr_val = Value(2 + b * F_MAX_MACRO)
                    If nQta >= 4 Then iodbmr.data.data4.mcr_val = Value(3 + b * F_MAX_MACRO)
                    If nQta >= 5 Then iodbmr.data.data5.mcr_val = Value(4 + b * F_MAX_MACRO)

                    nReturn = Focas1.cnc_wrmacror(nLibHandle(nActivePath), MacroIndex, iodbmr)
                    If F_CheckRetError_Cnc(nReturn, "cnc_wrmacror F_RW_Macro_Short CNC.FANUC") Then
                        Throw New CmsNcException("ERR cnc_wrmacror F_RW_Macro_Short CNC.FANUC")
                        Return False
                    End If

                Else ' ************* Read
                    nReturn = Focas1.cnc_rdmacror(nLibHandle(nActivePath), iodbmr.datano_s, iodbmr.datano_e, nlength, iodbmr)

                    If F_CheckRetError_Cnc(nReturn, "cnc_rdmacror F_RW_Macro_Short CNC.FANUC") Then
                        Throw New CmsNcException("ERR cnc_rdmacror F_RW_Macro_Short CNC.FANUC")
                        Return False
                    Else
                        If nQta >= 1 Then Value(0 + b * F_MAX_MACRO) = iodbmr.data.data1.mcr_val / (10 ^ iodbmr.data.data1.dec_val)
                        If nQta >= 2 Then Value(1 + b * F_MAX_MACRO) = iodbmr.data.data2.mcr_val / (10 ^ iodbmr.data.data2.dec_val)
                        If nQta >= 3 Then Value(2 + b * F_MAX_MACRO) = iodbmr.data.data3.mcr_val / (10 ^ iodbmr.data.data3.dec_val)
                        If nQta >= 4 Then Value(3 + b * F_MAX_MACRO) = iodbmr.data.data4.mcr_val / (10 ^ iodbmr.data.data4.dec_val)
                        If nQta >= 5 Then Value(4 + b * F_MAX_MACRO) = iodbmr.data.data5.mcr_val / (10 ^ iodbmr.data.data5.dec_val)
                    End If
                End If
            Next

            Return True
        End Function

        ''' <summary>
        ''' Legge o scrive le variabile Custom Macro
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MacroIndex">Indice di memoria</param>
        ''' <param name="Value">Matrice di valori da scrivere su scrittura o letti su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_Macro_Short(ByVal bWrite As Boolean, ByVal MacroIndex As Integer, ByRef Value As Short) As Boolean
            Dim bRet As Boolean
            Dim sValue(0) As Short
            If bWrite Then sValue(0) = Value
            bRet = F_RW_Macro_Short(bWrite, MacroIndex, sValue)
            If Not bWrite Then Value = sValue(0)
            Return bRet
        End Function

        Private Function GetNumDec(ByVal dVal As Double) As Short
            ' Determino il numero di decimali più adatto, in base al valore
            ' (per evitare l'overflow durante le operazioni di moltiplicazione)
            If dVal < -99999999 Or dVal > 99999999 Then
                GetNumDec = 0
            ElseIf dVal < -9999999 Or dVal > 9999999 Then
                GetNumDec = 1
            ElseIf dVal < -999999 Or dVal > 999999 Then
                GetNumDec = 2
            ElseIf dVal < -99999 Or dVal > 99999 Then
                GetNumDec = 3
            ElseIf dVal < -9999 Or dVal > 9999 Then
                GetNumDec = 4
            ElseIf dVal < -999 Or dVal > 999 Then
                GetNumDec = 5
            ElseIf dVal < -99 Or dVal > 99 Then
                GetNumDec = 6
            ElseIf dVal < -9 Or dVal > 9 Then
                GetNumDec = 7
            Else
                GetNumDec = 8
            End If
        End Function


        ''' <summary>
        ''' Legge o scrive le variabile Custom Macro
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MacroIndex">Indice di memoria</param>
        ''' <param name="Value">Matrice di valori da scrivere su scrittura o letti su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_Macro_Double(ByVal bWrite As Boolean, ByVal MacroIndex As Integer, ByRef Value() As Double) As Boolean
            Dim iodbmr As Focas1.IODBMR
            Dim nlength As Integer
            Dim nReturn As Integer
            Dim nQta As Integer
            Dim nBlock As Integer
            Dim nMod As Integer
            Dim nActivePath As Integer

            If Value Is Nothing Then Throw New InvalidOperationException

            nActivePath = GetActivePath()

            'Calcolo la dimesione dell'array
            nBlock = Value.Length \ F_MAX_MACRO
            nMod = Value.Length Mod F_MAX_MACRO
            If nMod > 0 Then nBlock += 1

            For b = 0 To nBlock - 1
                If b < nBlock - 1 Then
                    nQta = F_MAX_MACRO
                Else
                    nQta = IIf(nMod > 0, nMod, F_MAX_MACRO)
                End If

                'Setto il tipo di memoria
                iodbmr = New Focas1.IODBMR
                iodbmr.datano_s = MacroIndex + (b * F_MAX_MACRO)
                iodbmr.datano_e = MacroIndex + (b * F_MAX_MACRO) + nQta - 1
                nlength = 8 + (nQta * 8)

                If bWrite Then ' *** Write
                    iodbmr.data = New Focas1.IODBMR1
                    iodbmr.data.data1 = New Focas1.IODBMR_data
                    iodbmr.data.data2 = New Focas1.IODBMR_data
                    iodbmr.data.data3 = New Focas1.IODBMR_data
                    iodbmr.data.data4 = New Focas1.IODBMR_data
                    iodbmr.data.data5 = New Focas1.IODBMR_data

                    ' Determino il numero di decimali più adatto, in base al valore
                    ' (per evitare l'overflow durante le operazioni di moltiplicazione)
                    If nQta >= 1 Then iodbmr.data.data1.dec_val = GetNumDec(Value(0 + b * F_MAX_MACRO))
                    If nQta >= 2 Then iodbmr.data.data2.dec_val = GetNumDec(Value(1 + b * F_MAX_MACRO))
                    If nQta >= 3 Then iodbmr.data.data3.dec_val = GetNumDec(Value(2 + b * F_MAX_MACRO))
                    If nQta >= 4 Then iodbmr.data.data4.dec_val = GetNumDec(Value(3 + b * F_MAX_MACRO))
                    If nQta >= 5 Then iodbmr.data.data5.dec_val = GetNumDec(Value(4 + b * F_MAX_MACRO))

                    If nQta >= 1 Then iodbmr.data.data1.mcr_val = Value(0 + b * F_MAX_MACRO) * (10 ^ iodbmr.data.data1.dec_val)
                    If nQta >= 2 Then iodbmr.data.data2.mcr_val = Value(1 + b * F_MAX_MACRO) * (10 ^ iodbmr.data.data2.dec_val)
                    If nQta >= 3 Then iodbmr.data.data3.mcr_val = Value(2 + b * F_MAX_MACRO) * (10 ^ iodbmr.data.data3.dec_val)
                    If nQta >= 4 Then iodbmr.data.data4.mcr_val = Value(3 + b * F_MAX_MACRO) * (10 ^ iodbmr.data.data4.dec_val)
                    If nQta >= 5 Then iodbmr.data.data5.mcr_val = Value(4 + b * F_MAX_MACRO) * (10 ^ iodbmr.data.data5.dec_val)

                    nReturn = Focas1.cnc_wrmacror(nLibHandle(nActivePath), MacroIndex, iodbmr)

                    If F_CheckRetError_Cnc(nReturn, "cnc_wrmacror F_RW_Macro_Double CNC.FANUC") Then
                        Throw New CmsNcException("ERR cnc_wrmacror F_RW_Macro_Double CNC.FANUC")
                        Return False
                    End If

                Else ' ************* Read
                    nReturn = Focas1.cnc_rdmacror(nLibHandle(nActivePath), iodbmr.datano_s, iodbmr.datano_e, nlength, iodbmr)

                    If F_CheckRetError_Cnc(nReturn, "cnc_rdmacror F_RW_Macro_Double CNC.FANUC") Then
                        Throw New CmsNcException("ERR cnc_rdmacror F_RW_Macro_Double CNC.FANUC")
                        Return False
                    Else
                        If nQta >= 1 Then Value(0 + b * F_MAX_MACRO) = iodbmr.data.data1.mcr_val / (10 ^ iodbmr.data.data1.dec_val)
                        If nQta >= 2 Then Value(1 + b * F_MAX_MACRO) = iodbmr.data.data2.mcr_val / (10 ^ iodbmr.data.data2.dec_val)
                        If nQta >= 3 Then Value(2 + b * F_MAX_MACRO) = iodbmr.data.data3.mcr_val / (10 ^ iodbmr.data.data3.dec_val)
                        If nQta >= 4 Then Value(3 + b * F_MAX_MACRO) = iodbmr.data.data4.mcr_val / (10 ^ iodbmr.data.data4.dec_val)
                        If nQta >= 5 Then Value(4 + b * F_MAX_MACRO) = iodbmr.data.data5.mcr_val / (10 ^ iodbmr.data.data5.dec_val)
                    End If
                End If
            Next

            Return True
        End Function

        ''' <summary>
        ''' Legge o scrive le variabile Custom Macro
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MacroIndex">Indice di memoria</param>
        ''' <param name="Value">Matrice di valori da scrivere su scrittura o letti su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_Macro_Double(ByVal bWrite As Boolean, ByVal MacroIndex As Integer, ByRef Value As Double) As Boolean
            Dim bRet As Boolean
            Dim sValue(0) As Double
            If bWrite Then sValue(0) = Value
            bRet = F_RW_Macro_Double(bWrite, MacroIndex, sValue)
            If Not bWrite Then Value = sValue(0)
            Return bRet
        End Function

        ''' <summary>
        ''' Legge o scrive le variabile P Code Macro
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MacroIndex">Indice di memoria</param>
        ''' <param name="Value">Matrice di valori da scrivere su scrittura o letti su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_PCodeMacro_Short(ByVal bWrite As Boolean, ByVal MacroIndex As Integer, ByRef Value() As Short) As Boolean
            Dim iodbpr As Focas1.IODBPR
            Dim nlength As Integer
            Dim nReturn As Integer
            Dim nQta As Integer
            Dim nBlock As Integer
            Dim nMod As Integer
            Dim nActivePath As Integer

            If Value Is Nothing Then Throw New InvalidOperationException

            nActivePath = GetActivePath()

            'Calcolo la dimesione dell'array
            nBlock = Value.Length \ F_MAX_MACRO
            nMod = Value.Length Mod F_MAX_MACRO
            If nMod > 0 Then nBlock += 1

            For b = 0 To nBlock - 1
                If b < nBlock - 1 Then
                    nQta = F_MAX_MACRO
                Else
                    nQta = IIf(nMod > 0, nMod, F_MAX_MACRO)
                End If

                'Setto il tipo di memoria
                iodbpr = New Focas1.IODBPR
                iodbpr.datano_s = MacroIndex + (b * F_MAX_MACRO)
                iodbpr.datano_e = MacroIndex + (b * F_MAX_MACRO) + nQta - 1
                nlength = 12 + (nQta * 8)

                If bWrite Then ' *** Write
                    iodbpr.data = New Focas1.IODBPR1
                    iodbpr.data.data1 = New Focas1.IODBPR_data
                    iodbpr.data.data2 = New Focas1.IODBPR_data
                    iodbpr.data.data3 = New Focas1.IODBPR_data
                    iodbpr.data.data4 = New Focas1.IODBPR_data
                    iodbpr.data.data5 = New Focas1.IODBPR_data

                    If nQta >= 1 Then iodbpr.data.data1.mcr_val = Value(0 + b * F_MAX_MACRO)
                    If nQta >= 2 Then iodbpr.data.data2.mcr_val = Value(1 + b * F_MAX_MACRO)
                    If nQta >= 3 Then iodbpr.data.data3.mcr_val = Value(2 + b * F_MAX_MACRO)
                    If nQta >= 4 Then iodbpr.data.data4.mcr_val = Value(3 + b * F_MAX_MACRO)
                    If nQta >= 5 Then iodbpr.data.data5.mcr_val = Value(4 + b * F_MAX_MACRO)

                    nReturn = Focas1.cnc_wrpmacror(nLibHandle(nActivePath), MacroIndex, iodbpr)
                    If F_CheckRetError_Cnc(nReturn, "cnc_wrpmacror F_RW_PCodeMacro_Short CNC.FANUC") Then
                        Throw New CmsNcException("ERR cnc_wrpmacror F_RW_PCodeMacro_Short CNC.FANUC")
                        Return False
                    End If

                Else ' ************* Read
                    nReturn = Focas1.cnc_rdpmacror(nLibHandle(nActivePath), iodbpr.datano_s, iodbpr.datano_e, nlength, iodbpr)

                    If F_CheckRetError_Cnc(nReturn, "cnc_rdmacror F_RW_Macro_Short CNC.FANUC") Then
                        Throw New CmsNcException("ERR cnc_rdmacror F_RW_Macro_Short CNC.FANUC")
                        Return False
                    Else
                        If nQta >= 1 Then Value(0 + b * F_MAX_MACRO) = iodbpr.data.data1.mcr_val / (10 ^ iodbpr.data.data1.dec_val)
                        If nQta >= 2 Then Value(1 + b * F_MAX_MACRO) = iodbpr.data.data2.mcr_val / (10 ^ iodbpr.data.data2.dec_val)
                        If nQta >= 3 Then Value(2 + b * F_MAX_MACRO) = iodbpr.data.data3.mcr_val / (10 ^ iodbpr.data.data3.dec_val)
                        If nQta >= 4 Then Value(3 + b * F_MAX_MACRO) = iodbpr.data.data4.mcr_val / (10 ^ iodbpr.data.data4.dec_val)
                        If nQta >= 5 Then Value(4 + b * F_MAX_MACRO) = iodbpr.data.data5.mcr_val / (10 ^ iodbpr.data.data5.dec_val)
                    End If
                End If
            Next

            Return True
        End Function


        ''' <summary>
        ''' Legge o scrive le variabile P Code Macro
        ''' </summary>
        ''' <param name="bWrite">Se True SCRIVE, se False LEGGE</param>
        ''' <param name="MacroIndex">Indice di memoria</param>
        ''' <param name="Value">Matrice di valori da scrivere su scrittura o letti su lettura</param>
        ''' <returns>True se andata a buon fine</returns>
        Public Overloads Function F_RW_PCodeMacro_Short(ByVal bWrite As Boolean, ByVal MacroIndex As Integer, ByRef Value As Short) As Boolean
            Dim bRet As Boolean
            Dim sValue(0) As Short
            If bWrite Then sValue(0) = Value
            bRet = F_RW_PCodeMacro_Short(bWrite, MacroIndex, sValue)
            If Not bWrite Then Value = sValue(0)
            Return bRet
        End Function












        Public Overloads Function F_CheckRetError_Cnc(ByVal nReturn As Short, ByVal Position As String) As Boolean
            Dim szErrorDesc As String

            If nReturn <> Focas1.EW_OK Then
                'Seleziono il messaggio
                Select Case nReturn
                    Case Focas1.EW_PROTOCOL : szErrorDesc = "Protocol error (Ethernet version only)"
                    Case Focas1.EW_SOCKET : szErrorDesc = "Socket error (Ethernet version only)"
                    Case Focas1.EW_NODLL : szErrorDesc = "DLL file error"
                    Case Focas1.EW_BUS : szErrorDesc = "Bus error (HSSB version only)"
                    Case Focas1.EW_SYSTEM2 : szErrorDesc = "System error (2) (HSSB version only)"
                    Case Focas1.EW_HSSB : szErrorDesc = "Communication error of HSSB (HSSB version only)"
                    Case Focas1.EW_HANDLE : szErrorDesc = "Handle number error"
                    Case Focas1.EW_VERSION : szErrorDesc = "Version mismatch between the CNC/PMC and library"
                    Case Focas1.EW_UNEXP : szErrorDesc = "Abnormal library state"
                    Case Focas1.EW_SYSTEM : szErrorDesc = "System error (HSSB version only)"
                    Case Focas1.EW_PARITY : szErrorDesc = "Shared RAM parity error (HSSB version only)"
                    Case Focas1.EW_MMCSYS : szErrorDesc = "FANUC drivers installation error (HSSB version only)"
                    Case Focas1.EW_RESET : szErrorDesc = "Reset or stop request"
                    Case Focas1.EW_BUSY : szErrorDesc = "Busy"
                    Case Focas1.EW_OK : szErrorDesc = "Normal termination"
                    Case Focas1.EW_FUNC : szErrorDesc = "Error(function is not executed, or not available)"
                    Case Focas1.EW_LENGTH : szErrorDesc = "Error(data block length error, error of number of data)"
                    Case Focas1.EW_NUMBER : szErrorDesc = "Error(data number error)"
                    Case Focas1.EW_ATTRIB : szErrorDesc = "Error(data attribute error)"
                    Case Focas1.EW_DATA : szErrorDesc = "Error(data error)"
                    Case Focas1.EW_NOOPT : szErrorDesc = "Error(no option)"
                    Case Focas1.EW_PROT : szErrorDesc = "Error(write protection)"
                    Case Focas1.EW_OVRFLOW : szErrorDesc = "Error(memory overflow)"
                    Case Focas1.EW_PARAM : szErrorDesc = "Error(CNC parameter error)"
                    Case Focas1.EW_BUFFER : szErrorDesc = "Error(buffer empty/full)"
                    Case Focas1.EW_PATH : szErrorDesc = "Error(path number error)"
                    Case Focas1.EW_MODE : szErrorDesc = "Error(CNC mode error)"
                    Case Focas1.EW_REJECT : szErrorDesc = "Error(CNC execution rejection)"
                    Case Focas1.EW_DTSRVR : szErrorDesc = "Error(Data server error)"
                    Case Focas1.EW_ALARM : szErrorDesc = "Error(alarm)"
                    Case Focas1.EW_STOP : szErrorDesc = "Error(stop)"
                    Case Focas1.EW_PASSWD : szErrorDesc = "Error(State of data protection)"
                    Case Else : szErrorDesc = "- ERRORE CNC INESISTENTE -"
                End Select

                'Stampo il messaggio
                'If Config.Settings.Settings.Debug > 0 Then
                ' impostato a true x mostrare errore
                If False Then
                    'If nReturn <> Focas1.EW_SOCKET Then 'tranne su errore di connessione
                    'CMSCncLib.App.Runtime..Log.WW("ERR pmc_wrpmcrng on F_RW_DWord CNC.FANUC", "Return=" & nReturn, True)
                    MsgBox(szErrorDesc & vbLf & "Occurred in: " & Position, MsgBoxStyle.Exclamation + MsgBoxStyle.ApplicationModal, "Error on Fanuc CNC Data Window")
                    'End If
                End If

                Return True 'presenza errore
            End If

            Return False 'assenza errori
        End Function

        Public Overloads Function F_CheckRetError_Pmc(ByVal nReturn As Short, ByVal Position As String) As Boolean
            Dim szErrorDesc As String

            If nReturn <> Focas1.EW_OK Then
                'Seleziono il messaggio
                Select Case nReturn
                    Case Focas1.EW_PROTOCOL : szErrorDesc = "Protocol error (Ethernet version only)"
                    Case Focas1.EW_SOCKET : szErrorDesc = "Socket error (Ethernet version only)"
                    Case Focas1.EW_NODLL : szErrorDesc = "DLL file error"
                    Case Focas1.EW_BUS : szErrorDesc = "Bus error (HSSB version only)"
                    Case Focas1.EW_SYSTEM2 : szErrorDesc = "System error (2) (HSSB version only)"
                    Case Focas1.EW_HSSB : szErrorDesc = "Communication error of HSSB (HSSB version only)"
                    Case Focas1.EW_HANDLE : szErrorDesc = "Handle number error"
                    Case Focas1.EW_VERSION : szErrorDesc = "Version mismatch between the CNC/PMC and library"
                    Case Focas1.EW_UNEXP : szErrorDesc = "Abnormal library state"
                    Case Focas1.EW_SYSTEM : szErrorDesc = "System error (HSSB version only)"
                    Case Focas1.EW_PARITY : szErrorDesc = "Shared RAM parity error (HSSB version only)"
                    Case Focas1.EW_MMCSYS : szErrorDesc = "FANUC drivers installation error (HSSB version only)"
                    Case Focas1.EW_OK : szErrorDesc = "Normal termination"
                    Case Focas1.EW_NOPMC : szErrorDesc = "Error(No PMC)"
                    Case Focas1.EW_LENGTH : szErrorDesc = "Error(data block length error)"
                    Case Focas1.EW_RANGE : szErrorDesc = "Error(address range error)"
                    Case Focas1.EW_TYPE : szErrorDesc = "Error(address type/data type error)"
                    Case Focas1.EW_DATA : szErrorDesc = "Error(data error)"
                    Case Focas1.EW_NOOPT : szErrorDesc = "Error(no option)"
                    Case Focas1.EW_BUFFER : szErrorDesc = "Error(buffer empty/full)"
                    Case Focas1.EW_PASSWD : szErrorDesc = "Error(State of data protection)"
                    Case Else : szErrorDesc = "- ERRORE PMC INESISTENTE -"
                End Select

                ''Stampo il messaggio
                'If (Config.Settings.Settings.Debug > 0) Then
                '    'If nReturn <> Focas1.EW_SOCKET Then 'tranne su errore di connessione
                '    'CMSCncLib.App.Runtime..Log.WW("ERR pmc_wrpmcrng on F_RW_DWord CNC.FANUC", "Return=" & nReturn, True)
                '    MsgBox(szErrorDesc & vbLf & "Occurred in: " & Position, MsgBoxStyle.Exclamation + MsgBoxStyle.ApplicationModal, "Error on Fanuc CNC Data Window")
                '    'End If
                'End If
                Return True 'presenza errore
                End If

                Return False 'assenza errori
        End Function

#Region "Funzioni specifiche IOT"


        Public Function getAllAxisPos() As Focas1.ODBPOS
            ' RIFERIMENTO: 
            ' C:\Users\samuele\Documents\FOCAS A02B-0207-K737_04.20\Document\SpecE\Position\cnc_rdposition.htm

            Dim nPathIdx As Integer
            Dim nNumAxisRead As Integer
            Dim nReturn As Integer

            Dim posizAssi As Focas1.ODBPOS

            'leggo il numero del processo attivo
            nPathIdx = GetActivePath()
            'leggo num max assi dal cn
            nNumAxisRead = Focas1.MAX_AXIS

            If Is30Series Then

                ' leggo tutto!!!
                nReturn = Focas1.cnc_rdposition(nLibHandle(nPathIdx), -1, nNumAxisRead, posizAssi)

                If F_CheckRetError_Cnc(nReturn, "cnc_rdposition RefreshAxisPosition CNC.FANUC.CMS_CncLib") Then
                    Throw New CmsNcException("ERR cnc_rdposition RefreshAxisPosition CNC.FANUC.CMS_CncLib")
                End If
            End If

            Return posizAssi

        End Function

        Public Function getAllAxisLoad() As Focas1.ODBSVLOAD
            ' RIFERIMENTO: 
            ' C:\Users\samuele\Documents\FOCAS A02B-0207-K737_04.20\Document\SpecE\Position\cnc_rdsvmeter.htm

            Dim nPathIdx As Integer
            Dim nNumAxisRead As Integer
            Dim nReturn As Integer

            Dim caricoAssi As Focas1.ODBSVLOAD

            'leggo il numero del processo attivo
            nPathIdx = GetActivePath()
            'leggo num max assi dal cn
            nNumAxisRead = Focas1.MAX_AXIS

            If Is30Series Then

                ' leggo tutto!!!
                nReturn = Focas1.cnc_rdsvmeter(nLibHandle(nPathIdx), nNumAxisRead, caricoAssi)

                If F_CheckRetError_Cnc(nReturn, "cnc_rdsvmeter RefreshAxisMeter CNC.FANUC.CMS_CncLib") Then
                    Throw New CmsNcException("ERR cnc_rdsvmeter RefreshAxisMeter CNC.FANUC.CMS_CncLib")
                End If
            End If

            Return caricoAssi

        End Function

        Public Function getGlobalFeedrate() As Focas1.ODBACT
            ' RIFERIMENTO: 
            ' C:\Users\samuele\Documents\FOCAS A02B-0207-K737_04.20\Document\SpecE\Position\cnc_actf.htm

            Dim nPathIdx As Integer
            Dim nNumAxisRead As Integer
            Dim nReturn As Integer

            Dim feedData As Focas1.ODBACT
            ' inizializzo
            feedData = New Focas1.ODBACT

            'leggo il numero del processo attivo
            nPathIdx = GetActivePath()
            'leggo num max assi dal cn
            nNumAxisRead = Focas1.MAX_AXIS

            If Is30Series Then

                ' leggo feed globale
                nReturn = Focas1.cnc_actf(nLibHandle(nPathIdx), feedData)

                If F_CheckRetError_Cnc(nReturn, "cnc_actf RefreshActFeedRate CNC.FANUC.CMS_CncLib") Then
                    Throw New CmsNcException("ERR cnc_actf RefreshActFeedRate CNC.FANUC.CMS_CncLib")
                End If
            End If

            Return feedData

        End Function

        Public Function getSpindleLoad() As Focas1.ODBSPN
            ' RIFERIMENTO: 
            ' C:\Users\samuele\Documents\FOCAS A02B-0207-K737_04.20\Document\SpecE\Position\cnc_rdspload.htm
            ' RICHIEDE DRIVER ESTESO!!! NON VA!!!

            Dim nPathIdx As Integer
            Dim nNumAxisRead As Integer
            Dim nReturn As Integer

            Dim allData As Focas1.ODBSPN
            ' inizializzo
            allData = New Focas1.ODBSPN

            'leggo il numero del processo attivo
            nPathIdx = GetActivePath()
            'leggo num max assi dal cn
            nNumAxisRead = Focas1.MAX_AXIS

            If Is30Series Then

                ' leggo feed globale
                nReturn = Focas1.cnc_rdspload(nLibHandle(nPathIdx), -1, allData)

                If F_CheckRetError_Cnc(nReturn, "cnc_rdspload RefreshAllSpindleLoad CNC.FANUC.CMS_CncLib") Then
                    Throw New CmsNcException("ERR cnc_rdspload RefreshAllSpindleLoad CNC.FANUC.CMS_CncLib")
                End If
            End If

            Return allData

        End Function

        Public Function getAllDynData() As Focas1.ODBDY2_1
            ' RIFERIMENTO: 
            ' C:\Users\samuele\Documents\FOCAS A02B-0207-K737_04.20\Document\SpecE\Position\cnc_rddynamic2.htm

            Dim nPathIdx As Integer
            Dim nNumAxisRead As Integer
            Dim nReturn As Integer

            Dim allData As Focas1.ODBDY2_1
            ' inizializzo
            allData = New Focas1.ODBDY2_1

            'leggo il numero del processo attivo
            nPathIdx = GetActivePath()
            'leggo num max assi dal cn
            nNumAxisRead = Focas1.MAX_AXIS

            If Is30Series Then

                nReturn = Focas1.cnc_rddynamic2(nLibHandle(nPathIdx), 1, 28 + 4 * (4 * 1), allData)
                '!!! non funziona: con -1 LEGGE 1 SOLO ASSE!!!
                'nReturn = Focas1.cnc_rddynamic2(nLibHandle(nPathIdx), -1, 28 + 4 * (4 * nNumAxisRead), allData)

                If F_CheckRetError_Cnc(nReturn, "cnc_rddynamic2 RefreshAllData CNC.FANUC.CMS_CncLib") Then
                    Throw New CmsNcException("ERR cnc_rddynamic2 RefreshAllData CNC.FANUC.CMS_CncLib")
                End If
            End If

            Return allData

        End Function

        Public Function getCncAlarm() As Focas1.ODBALMMSG2
            ' RIFERIMENTO: 
            ' C:\Users\samuele\Documents\FOCAS A02B-0207-K737_04.20\Document\SpecE\Misc\cnc_rdalmmsg2.htm
            ' C:\Users\samuele\Documents\FOCAS A02B-0207-K737_04.20\Document\SpecE\Misc\cnc_rdalminfo.htm

            Dim nPathIdx As Integer
            Dim nNumAxisRead As Integer
            Dim nReturn As Integer

            Dim allData As Focas1.ODBALMMSG2
            ' inizializzo
            allData = New Focas1.ODBALMMSG2

            'leggo il numero del processo attivo
            nPathIdx = GetActivePath()
            'leggo num max assi dal cn
            nNumAxisRead = Focas1.MAX_AXIS

            ' vettore num allarmi MAX da leggere......
            Dim numAllarmi As Int16
            numAllarmi = 512

            If Is30Series Then

                ' leggo tutto!!!
                nReturn = Focas1.cnc_rdalmmsg2(nLibHandle(nPathIdx), -1, numAllarmi, allData)

                If F_CheckRetError_Cnc(nReturn, "cnc_rdalmmsg2 GetCncAlarm CNC.FANUC.CMS_CncLib") Then
                    Throw New CmsNcException("ERR cnc_rdalmmsg2 GetCncAlarm CNC.FANUC.CMS_CncLib")
                End If
            End If

            Return allData

        End Function

        Public Function getPathGCodeMod() As Focas1.ODBGCD
            ' RIFERIMENTO: 
            ' C:\Users\samuele\Documents\FOCAS A02B-0207-K737_04.20\Document\SpecE\Misc\cnc_rdgcode.htm

            Dim nPathIdx As Integer
            Dim nNumAxisRead As Integer
            Dim nReturn As Integer

            Dim actGCode As Focas1.ODBGCD
            ' inizializzo
            actGCode = New Focas1.ODBGCD

            'leggo il numero del processo attivo
            nPathIdx = GetActivePath()
            'leggo num max assi dal cn
            nNumAxisRead = Focas1.MAX_AXIS

            If Is30Series Then

                ' leggo tutto!!! 0-27 (28 elementi)
                nReturn = Focas1.cnc_rdgcode(nLibHandle(nPathIdx), -1, 1, 37, actGCode)

                If F_CheckRetError_Cnc(nReturn, "cnc_rdgcode RefreshPathGCode CNC.FANUC.CMS_CncLib") Then
                    Throw New CmsNcException("ERR cnc_rdgcode RefreshPathGCode CNC.FANUC.CMS_CncLib")
                End If
            End If

            Return actGCode

        End Function

        Public Function getPathGCode1Shot() As Focas1.ODBGCD
            ' RIFERIMENTO: 
            ' C:\Users\samuele\Documents\FOCAS A02B-0207-K737_04.20\Document\SpecE\Misc\cnc_rdgcode.htm

            Dim nPathIdx As Integer
            Dim nNumAxisRead As Integer
            Dim nReturn As Integer

            Dim actGCode As Focas1.ODBGCD
            ' inizializzo
            actGCode = New Focas1.ODBGCD

            'leggo il numero del processo attivo
            nPathIdx = GetActivePath()
            'leggo num max assi dal cn
            nNumAxisRead = Focas1.MAX_AXIS

            If Is30Series Then

                ' leggo tutto!!! 0-27 (28 elementi)
                nReturn = Focas1.cnc_rdgcode(nLibHandle(nPathIdx), -2, 1, 4, actGCode)

                If F_CheckRetError_Cnc(nReturn, "cnc_rdgcode RefreshPathGCode CNC.FANUC.CMS_CncLib") Then
                    Throw New CmsNcException("ERR cnc_rdgcode RefreshPathGCode CNC.FANUC.CMS_CncLib")
                End If
            End If

            Return actGCode

        End Function

        Public Function getPathTTCoord() As Focas1.ODB5AXMAN
            ' RIFERIMENTO: 
            ' C:\Users\samuele\Documents\FOCAS A02B-0207-K737_04.20\Document\SpecE\Position\cnc_rd5axmandt.htm

            Dim nPathIdx As Integer
            Dim nNumAxisRead As Integer
            Dim nReturn As Integer

            Dim ttCoord As Focas1.ODB5AXMAN
            ' inizializzo
            ttCoord = New Focas1.ODB5AXMAN

            'leggo il numero del processo attivo
            nPathIdx = GetActivePath()
            'leggo num max assi dal cn
            nNumAxisRead = Focas1.MAX_AXIS

            If Is30Series Then

                ' leggo tutto!!! 
                nReturn = Focas1.cnc_rd5axmandt(nLibHandle(nPathIdx), ttCoord)

                If F_CheckRetError_Cnc(nReturn, "cnc_rd3dtooltip RefreshPathTTCoord CNC.FANUC.CMS_CncLib") Then
                    Throw New CmsNcException("ERR cnc_rd3dtooltip RefreshPathTTCoord CNC.FANUC.CMS_CncLib")
                End If
            End If

            Return ttCoord

        End Function

        Public Function getSpindleSpeed() As Focas1.ODBSPEED
            ' RIFERIMENTO: 
            ' C:\Users\samuele\Documents\FOCAS A02B-0207-K737_04.20\Document\SpecE\Position\cnc_rdspeed.htm

            Dim nPathIdx As Integer
            Dim nNumAxisRead As Integer
            Dim nReturn As Integer

            Dim speedAssi As Focas1.ODBSPEED

            'leggo il numero del processo attivo
            nPathIdx = GetActivePath()
            'leggo num max assi dal cn
            nNumAxisRead = Focas1.MAX_AXIS

            If Is30Series Then

                ' leggo tutto!!!
                nReturn = Focas1.cnc_rdspeed(nLibHandle(nPathIdx), -1, speedAssi)

                If F_CheckRetError_Cnc(nReturn, "cnc_rdspeed RefreshAxisSpeed CNC.FANUC.CMS_CncLib") Then
                    Throw New CmsNcException("ERR cnc_rdspeed RefreshAxisSpeed CNC.FANUC.CMS_CncLib")
                End If
            End If

            Return speedAssi

        End Function

#End Region

    End Class

End Namespace