Imports System.Globalization
Imports EgtUILib
Imports EgtWPFLib

Public Class DrawPageUC

   ' Constants
   Private Const NUM_VAR As Integer = 10
   Private Const LUA_CMP_VARS As String = "CMP"
   Private Const LUA_CMP_DRAW As String = "CMP_Draw"
   Private Const INFO_VAR As String = "Var"
   Private Const INFO_CMP As String = "CMP"
   Private Const INFO_ID As String = "ID"
   Friend Const LUA_CMP_INDEX As String = LUA_CMP_VARS & ".Ind"
   Friend Const LUA_CMP_INTERNAL As String = LUA_CMP_VARS & ".Int"
   Friend Const LUA_REMOVEHOLE As String = "RemoveHole"
   ' Costanti layer componenti
   Friend Const COMPO_LAYER_AUX As String = "LayAux"
   Friend Const COMPO_LAYER_QUOTATURE As String = "Quotature"
   Friend Const COMPO_LAYER_ETICHETTE As String = "Etichette"

   'Riferimento alla MainWindow
   Private m_MainWindow As MainWindow = DirectCast(Application.Current.MainWindow, MainWindow)
   ' Dichiarazione SceneButtons
   Friend m_SceneButtons As SceneButtonsUC

   ' Dichiarazione delle Page UserControl
   Friend m_MainComponentPage As MainComponentPageUC
   Friend m_CompoDimension As CompoDimensionUC
   Friend m_SideAngleUC As SideAngleUC
   Friend m_FiloTopUC As FiloTopUC

   ' Variabile che indica se componenti interni o esterni (usato anche per definire le alzatine e i fronatlini)
   Friend m_bInternalCompo As Boolean = False
   Friend m_bBackFromInternalCompo As Boolean = False

   ' Properties 
   Private m_sCompoDir As String = String.Empty
   Private m_sCompoName As String = String.Empty
   Private m_CVars(NUM_VAR - 1) As CompoVar
   Friend m_bDrawOk As Boolean = False
   Private m_bFirst As Boolean = True

   ' questa variabile serve per risalire al nome della componente che ospita i componenti interni att
   Friend m_sMainCompo As String = String.Empty


   ' Trf Data
   Private m_bTrfData As Boolean = False
   Private m_TrfOrderCode As String = ""
   Private m_TrfOrderDesc As String = ""
   Private m_TrfPartCode As String = ""
   Private m_TrfMatCode As String = ""
   Private m_TrfSurfCode As String = ""
   Private m_TrfThickness As Double = 0

   ' Csv Data
   Private m_bCsvData As Boolean = False
   Private m_sCsvOrder As String = ""
   Private m_sCsvList As String = ""
   Private m_sCsvName As String = ""

   ' Abilito i tagli inclinati solo per macchina a 5 assi
   Private m_bEnableSideAngle As Boolean = True

   Friend ReadOnly Property bEnableSideAngle As Boolean
      Get
         Return m_bEnableSideAngle
      End Get
   End Property


   Friend ReadOnly Property sCompoName As String
      Get
         Return m_sCompoName
      End Get
   End Property

   Friend Sub ResetCompoName()
      m_sCompoName = String.Empty
   End Sub

   Friend Function GetParamType(nI As Integer) As Integer
      If nI >= 0 And nI < NUM_VAR Then Return m_CVars(nI).m_nType
      Return 0
   End Function

   ' Dichiarazione Scene
   Friend WithEvents DrawScene As New Scene
   Dim DrawSceneHost As New System.Windows.Forms.Integration.WindowsFormsHost

   ' Riferimento alla pagina correntemente attiva
   Friend m_ActiveComponentPage As Pages

   ' Modalità aggiornamento variabili
   Friend m_bShowVar As Boolean = False

   ' Pagina corrente prima di aprire SideAngle
   Private m_PrevSideAnglePage As Pages

   ' Indentificativo del layer selezionato
   Private m_nSelectedLayer As Integer = GDB_ID.NULL
   Friend ReadOnly Property SelectedLayer As Integer
      Get
         Return m_nSelectedLayer
      End Get
   End Property
   Public Sub SetCurrLayer(ByVal nCurrLayer As Integer)
      m_nSelectedLayer = nCurrLayer
   End Sub

   Enum Pages
      MainComponent
      SecondaryComponent
      InternalComponent
      Draw
      CompoDimension
      SideAngle
      FiloTop
      AlzFront
   End Enum

   Private Sub DrawPage_Initialized(sender As Object, e As EventArgs)

      ' Creazione delle Page UserControl
      m_SceneButtons = New SceneButtonsUC
      m_MainComponentPage = New MainComponentPageUC
      m_CompoDimension = New CompoDimensionUC
      m_SideAngleUC = New SideAngleUC
      m_FiloTopUC = New FiloTopUC
      ' Posizionemento nella griglia delle Page UserControl
      m_SceneButtons.SetValue(Grid.ColumnProperty, 5)
      m_MainComponentPage.SetValue(Grid.ColumnSpanProperty, 2)
      m_MainComponentPage.SetValue(Grid.RowSpanProperty, 4)
      m_CompoDimension.SetValue(Grid.ColumnSpanProperty, 2)
      m_CompoDimension.SetValue(Grid.RowSpanProperty, 4)
      m_SideAngleUC.SetValue(Grid.RowSpanProperty, 1)
      m_FiloTopUC.SetValue(Grid.RowSpanProperty, 1)
      UpperButtonGrid.Children.Add(m_SceneButtons)

      ' Assegnazione scena all'host e posizionamento nella ImportPageGrid
      DrawSceneHost.Child = DrawScene
      DrawSceneHost.SetValue(Grid.ColumnProperty, 1)
      DrawSceneHost.SetValue(Grid.RowProperty, 1)
      Me.DrawPageGrd.Children.Add(DrawSceneHost)

      ' Imposto i messaggi letti dal file dei messaggi
      PartNameTxBl.Text = EgtMsg( 90388)                   ' Nome
      PartNumTxBl.Text = EgtMsg( 90381)                    ' Numero pezzi
      DimensionBtn.Content = EgtMsg( 90382)                ' Misure
      SideAngleBtn.Content = EgtMsg( 90383)                ' Inclina lati
      FiloTopBtn.Content = EgtMsg( 90400)                  ' Filo Top
      EngraveBtn.Content = EgtMsg( 90397)                  ' Incidi
      DripCutBtn.Content = EgtMsg( 90458)                  ' Incidi da sotto
      TopTxBl.Text = EgtMsg( 90384)                        ' Indica Lato Sopra

      ' Abilitazione lavorazioni da sotto da chiave
      DripCutBtn.IsEnabled = m_MainWindow.GetKeyOption(MainWindow.KEY_OPT.UNDER_CUT) And
                             Not String.IsNullOrWhiteSpace(m_MainWindow.m_CurrentMachine.sCurrDripSaw)

      ' Abilitazione TrfData
      m_bTrfData = m_MainWindow.GetKeyOption(MainWindow.KEY_OPT.TRF_IMPORT) And
                   (GetPrivateProfileInt(S_COMPO, K_TRFDATA, 0, m_MainWindow.GetIniFile()) <> 0)
      ' Abilitazione CsvData
      m_bCsvData = (Not m_bTrfData And GetPrivateProfileInt(S_COMPO, K_CSVDATA, 0, m_MainWindow.GetIniFile()) <> 0)

      ' Abilitazione tagli inclinati (solo per macchine a 5 assi)
      m_bEnableSideAngle = GetPrivateProfileInt(S_AXES, K_AXESNUM, 5, m_MainWindow.GetMachIniFile()) > 4
      If Not m_bEnableSideAngle Then
         SideAngleBtn.IsEnabled = False
      End If

      If m_bTrfData Then
         PartNameTxBl.Visibility = Windows.Visibility.Hidden
         PartNameTxBx.Visibility = Windows.Visibility.Hidden
         TrfDataBtn.Visibility = Windows.Visibility.Visible
         TrfDataBtn.Content = EgtMsg( 90389)                  ' Dati Trf
      ElseIf m_bCsvData Then
         PartNameTxBl.Visibility = Windows.Visibility.Hidden
         PartNameTxBx.Visibility = Windows.Visibility.Hidden
         TrfDataBtn.Visibility = Windows.Visibility.Visible
         TrfDataBtn.Content = EgtMsg( 90398)                  ' Dati Csv
      Else
         PartNameTxBl.Visibility = Windows.Visibility.Visible
         PartNameTxBx.Visibility = Windows.Visibility.Visible
         TrfDataBtn.Visibility = Windows.Visibility.Hidden
      End If

   End Sub

   ' carico le impostazioni grafiche della scena (solo al primo avvio)
   Private Sub DrawPage_Loaded(sender As Object, e As RoutedEventArgs)

      If m_bFirst Then
         ' imposto colore di default
         Dim DefColor As New Color3d(0, 0, 0)
         GetPrivateProfileColor(S_GEOMDB, K_DEFAULTCOLOR, DefColor, m_MainWindow.GetIniFile())
         DrawScene.SetDefaultMaterial(DefColor)
         ' imposto colori sfondo
         DrawScene.SetViewBackground(GetBackTopColor(), GetBackBottomColor())
         ' imposto colore di evidenziazione
         Dim MarkColor As New Color3d(255, 255, 0)
         GetPrivateProfileColor(S_SCENE, K_MARK, MarkColor, m_MainWindow.GetIniFile())
         DrawScene.SetMarkMaterial(MarkColor)
         ' imposto colore per superfici selezionate
         Dim SelSurfColor As New Color3d(255, 255, 192)
         GetPrivateProfileColor(S_SCENE, K_SELSURF, SelSurfColor, m_MainWindow.GetIniFile())
         DrawScene.SetSelSurfMaterial(SelSurfColor)
         ' imposto tipo e colore del rettangolo di zoom
         Dim bOutline As Boolean = True
         Dim ZwColor As New Color3d(0, 0, 0)
         GetPrivateProfileZoomWin(S_SCENE, K_ZOOMWIN, bOutline, ZwColor, m_MainWindow.GetIniFile())
         DrawScene.SetZoomWinAttribs(bOutline, ZwColor)
         ' imposto colore della linea di distanza
         Dim DstLnColor As New Color3d(255, 0, 0)
         GetPrivateProfileColor(S_SCENE, K_DISTLINE, DstLnColor, m_MainWindow.GetIniFile())
         DrawScene.SetDistLineMaterial(DstLnColor)

         '' imposto il colore di sfondo del disegno
         'Dim BAckTopColor As New Color3d(192, 192, 192)
         'GetPrivateProfileColor(S_SCENE, "BackTop", BAckTopColor, m_MainWindow.GetIniFile())
         'Dim BackBottom As New Color3d(192, 192, 192)
         'GetPrivateProfileColor(S_SCENE, "BackBottom", BackBottom, m_MainWindow.GetIniFile())
         'DrawScene.SetViewBackground(BAckTopColor, BackBottom)

         ' imposto parametri OpenGL
         Dim nDriver As Integer = GetPrivateProfileInt(S_OPENGL, K_DRIVER, 3, m_MainWindow.GetIniFile())
         Dim b2Buff As Boolean = (GetPrivateProfileInt(S_OPENGL, K_DOUBLEBUFFER, 1, m_MainWindow.GetIniFile()) <> 0)
         Dim nColorBits As Integer = GetPrivateProfileInt(S_OPENGL, K_COLORBITS, 32, m_MainWindow.GetIniFile())
         Dim nDepthBits As Integer = GetPrivateProfileInt(S_OPENGL, K_DEPTHBITS, 32, m_MainWindow.GetIniFile())
         DrawScene.SetViewAttributes(nDriver, b2Buff, nColorBits, nDepthBits)
         ' inizializzo la scena (DB geometrico + visualizzazione)
         DrawScene.Init()
         ' dimensione lineare max in pixel delle textures
         Dim nTxrMaxLinPix As Integer = GetPrivateProfileInt(S_SCENE, K_TEXMAXLINPIX, 4096, m_MainWindow.GetIniFile())
         EgtSetTextureMaxLinPixels(nTxrMaxLinPix)
         ' Imposto griglia
         LoadGridData()
         ' leggo direttorio componenti
         GetPrivateProfileString(S_COMPO, K_COMPODIR, "", m_sCompoDir, m_MainWindow.GetIniFile())
         ' Imposto componenti esterni
         m_bInternalCompo = False
         m_bFirst = False
      Else
         ' Imposto contesto
         EgtSetCurrentContext(DrawScene.GetCtx())
         ' Imposto griglia
         LoadGridData()
      End If

      ' inibisco selezione diretta da Scene
      DrawScene.SetStatusNull()
      ' pulisco la scena e relativo db
      EgtNewFile()
      EgtDraw()

      ' Seleziono la Tab e la Page di apertura
      VariablesGrd.Children.Remove(m_CompoDimension)
      LeftButtonGrd.Children.Add(m_MainComponentPage)
      m_ActiveComponentPage = Pages.MainComponent
      MessageGrid.Visibility = Windows.Visibility.Hidden
      BackBtn.Visibility = Windows.Visibility.Hidden
      TopGrd.Visibility = Windows.Visibility.Hidden
      PartNameGrd.Visibility = Windows.Visibility.Hidden
      PartNumberGrd.Visibility = Windows.Visibility.Hidden

      ' Valore di default del nome e del numero pezzi
      PartNameTxBx.Text = String.Empty
      PartNumTxBx.Text = "1"

      ' Reset dati TRF
      m_TrfOrderCode = ""
      m_TrfOrderDesc = ""
      m_TrfPartCode = ""
      m_TrfMatCode = ""
      m_TrfSurfCode = ""
      m_TrfThickness = 0

      ' Reset dati Csv
      m_sCsvOrder = ""
      m_sCsvList = ""
      m_sCsvName = ""
   End Sub

   ' recupero il click sulla scena ed assegno il metodo a secondo della pagina aperta
   Private Sub OnMouseDownScene(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles DrawScene.OnMouseDownScene
      ' Si può selezionare solo con il tasto sinistro e se stato NULL
      If e.Button <> Windows.Forms.MouseButtons.Left Or Not DrawScene.IsStatusNull() Then Return
      ' Si può selezionare solo se non si sta già editando un componente
      If m_ActiveComponentPage = Pages.InternalComponent Then
         OnMouseDownSceneInternalComponent(e)
      ElseIf m_ActiveComponentPage = Pages.SideAngle Then
         OnMouseDownSceneSideAngle(e)
      ElseIf m_ActiveComponentPage = Pages.FiloTop Then
         OnMouseDownSceneFiloTop(e)
      ElseIf m_ActiveComponentPage = Pages.AlzFront Then
         ' da definire

      End If
   End Sub

   Private Sub OnMouseDownSceneInternalComponent(e As System.Windows.Forms.MouseEventArgs)
      ' Verifico se selezionato indicativo di componente (wall, door o window)
      EgtSetObjFilterForSelWin(False, False, True, False, False)
      Dim nSel As Integer
      EgtSelect(e.Location, 2 * Scene.DIM_SEL, 2 * Scene.DIM_SEL, nSel)
      Dim sCompo As String = String.Empty
      Dim nId As Integer = EgtGetFirstObjInSelWin()
      While nId <> GDB_ID.NULL
         If EgtGetInfo(nId, INFO_CMP, sCompo) Then
            Exit While
         End If
         nId = EgtGetNextObjInSelWin()
      End While
      If String.IsNullOrWhiteSpace(sCompo) Then Return
      ' Salvo l'indice della superficie di selezione
      Dim nSurfSelId As Integer = nId
      ' Recupero l'indice del componente
      Dim sName As String = String.Empty
      If Not EgtGetName(nId, sName) Then Return
      Dim nCmp As Integer = -1
      If Not StringToInt(sName, nCmp) Then Return
      ' Rendo corrente il componente
      m_sCompoName = sCompo & ".lua"
      ' Pulisco l'ambiente lua
      ResetLuaVariables()
      ' Carico il file
      Dim bOk As Boolean = ExecCompoFile()
      If Not bOk Then
         EgtOutLog("Error in Component " & sCompo)
      End If
      MessageTxBl.Text = ""
      MessageGrid.Background = Brushes.Transparent
      ' Leggo le variabili da Lua (per sapere numero, nome e tipo)
      ReadAndShowVariables()
      ' Imposto le variabili del componente
      For i As Integer = 1 To NUM_VAR
         ' leggo il valore della variabile
         If m_CVars(i - 1) IsNot Nothing Then
            Dim sVar As String = String.Empty
            If EgtGetInfo(nId, "V" & i.ToString(), sVar) Then
               m_CVars(i - 1).FromString(sVar, False)
               ' aggiorno la corrispondente variabile lua
               If Not m_CVars(i - 1).ToLua() Then
                  Dim sErr As String = String.Empty
                  EgtLuaGetLastError(sErr)
                  EgtOutLog(sErr)
               End If
            End If
         End If
      Next
      ShowVariables()
      ' Imposto l'indice del componente
      If Not EgtLuaSetGlobIntVar(LUA_CMP_INDEX, nCmp) Then Return
      ' Evidenzio la sua regione di selezione
      EgtSelectObj(nSurfSelId)
      ' Rendo visibili le eventuali etichette del componente
      Dim nHLId As Integer = EgtGetFirstNameInGroup(EgtGetFirstGroupInGroup(GDB_ID.ROOT), "HoleLabels")
      While nHLId <> GDB_ID.NULL
         Dim nCmpInfo As Integer = 0
         If EgtGetInfo(nHLId, "ID", nCmpInfo) AndAlso nCmp = nCmpInfo Then
            EgtSetStatus(nHLId, GDB_ST.ON_)
            Exit While
         End If
         nHLId = EgtGetNextName(nHLId, "HoleLabels")
      End While
      DrawScene.ZoomAll()
      ' Aggiorno griglia
      LeftButtonGrd.Children.Remove(m_CompoDimension.m_InternalCompoPage)
      VariablesGrd.Children.Add(m_MainWindow.m_DrawPageUC.m_CompoDimension)
   End Sub

   Private Sub OnMouseDownSceneSideAngle(e As System.Windows.Forms.MouseEventArgs)
      ' Se non ci sono loop interni, selezione inutile
      If EgtGetFirstNameInGroup(EgtGetFirstPart(), NAME_INLOOP) = GDB_ID.NULL Then Return
      ' Verifico se selezionato indicativo di pezzo
      EgtSetObjFilterForSelWin(False, False, True, False, False)
      Dim nSel As Integer
      EgtSelect(e.Location, Scene.DIM_SEL, Scene.DIM_SEL, nSel)
      Dim nId As Integer = EgtGetFirstObjInSelWin()
      While nId <> GDB_ID.NULL
         ' Recupero l'identificativo del layer e del pezzo cui appartiene
         Dim nRegLayId As Integer = EgtGetParent(nId)
         Dim nPartId As Integer = EgtGetParent(nRegLayId)
         If EgtIsPart(nPartId) Then
            Dim sRegLayName As String = String.Empty
            EgtGetName(nRegLayId, sRegLayName)
            If (SideAngleBtn.IsChecked And (sRegLayName = NAME_REGION Or sRegLayName = SELECT_REGION_LAYER)) Or (DripCutBtn.IsChecked And sRegLayName = NAME_REGION) Then
               Dim nStat As Integer = GDB_ST.ON_
               EgtGetStatus(nId, nStat)
               If nStat = GDB_ST.SEL Then
                  EgtDeselectAll()
                  m_nSelectedLayer = GDB_ID.NULL
                  SideAngle.WriteSideAngleForNest(DrawScene.GetCtx())
                  ' Messaggio di selezione da effettuare
                  MessageTxBx.Text = EgtMsg(MSG_DRAWPAGEUC + 6)   ' Selezionare un contorno
                  MessageBrd.Background = Application.Current.FindResource("OmagCut_Green")
               Else
                  Dim nLayId As Integer = EgtGetFirstNameInGroup(nPartId, NAME_OUTLOOP)
                  Dim nInd As Integer = 0
                  EgtGetInfo(nId, "ID", nInd)
                  If nInd <> 0 Then
                     Dim nInLoopId As Integer = EgtGetFirstNameInGroup(nPartId, NAME_INLOOP)
                     While nInLoopId <> GDB_ID.NULL
                        Dim nLoopInd As Integer = 0
                        EgtGetInfo(nInLoopId, "ID", nLoopInd)
                        If nLoopInd = nInd And nInd <> 0 Then
                           nLayId = nInLoopId
                           Exit While
                        End If
                        nInLoopId = EgtGetNextName(nInLoopId, NAME_INLOOP)
                     End While
                  End If
                  EgtDeselectAll()
                  EgtSelectObj(nId)
                  EgtSelectObj(nLayId)
                  m_nSelectedLayer = nLayId
                  ' Pulisco area messaggi
                  MessageTxBx.Text = ""
                  MessageBrd.Background = Brushes.Transparent
               End If
               m_SideAngleUC.ReLoadSideAnglePage()
               Exit While
            End If
         End If
         nId = EgtGetNextObjInSelWin()
      End While
   End Sub

   Private Sub OnMouseDownSceneFiloTop(e As System.Windows.Forms.MouseEventArgs)
      ' Verifico se selezionato indicativo di pezzo
      EgtSetObjFilterForSelWin(False, False, True, False, False)
      Dim nSel As Integer
      EgtSelect(e.Location, Scene.DIM_SEL, Scene.DIM_SEL, nSel)
      Dim nId As Integer = EgtGetFirstObjInSelWin()
      While nId <> GDB_ID.NULL
         ' Recupero l'identificativo del layer e del pezzo cui appartiene
         Dim nRegLayId As Integer = EgtGetParent(nId)
         Dim nPartId As Integer = EgtGetParent(nRegLayId)
         If EgtIsPart(nPartId) Then
            Dim sRegLayName As String = String.Empty
            EgtGetName(nRegLayId, sRegLayName)
            If sRegLayName = NAME_REGION Or sRegLayName = SELECT_REGION_LAYER Then
               Dim nStat As Integer = GDB_ST.ON_
               EgtGetStatus(nId, nStat)
               Dim nLayId As Integer = GDB_ID.NULL
               Dim nInd As Integer = 0
               EgtGetInfo(nId, "ID", nInd)
               If nInd <> 0 Then
                  Dim nInLoopId As Integer = EgtGetFirstNameInGroup(nPartId, NAME_INLOOP)
                  While nInLoopId <> GDB_ID.NULL
                     Dim nLoopInd As Integer = 0
                     EgtGetInfo(nInLoopId, "ID", nLoopInd)
                     If nLoopInd = nInd And nInd <> 0 Then
                        nLayId = nInLoopId
                        Exit While
                     End If
                     nInLoopId = EgtGetNextName(nInLoopId, NAME_INLOOP)
                  End While
               End If
               If nStat = GDB_ST.SEL Then
                  EgtDeselectObj(nId)
                  EgtDeselectObj(nLayId)
                  Dim sLayName As String = ""
                  If EgtGetName(nLayId, sLayName) AndAlso sLayName = NAME_INLOOP AndAlso EgtExistsInfo( nLayId, INFO_FILOTOP) Then
                     EgtRemoveInfo( nLayId, INFO_FILOTOP)
                     EgtRemoveInfo( nLayId, INFO_OFFSET)
                     EgtRemoveInfo( nLayId, INFO_DEPTH)
                     EgtResetColor( nLayId)
                  End If
               Else
                  Dim sLayName As String = ""
                  If EgtGetName( nLayId, sLayName) AndAlso sLayName = NAME_INLOOP Then
                     EgtSelectObj( nId)
                     EgtSelectObj( nLayId)
                     EgtSetInfo( nLayId, INFO_FILOTOP, 1)
                     EgtSetInfo( nLayId, INFO_OFFSET, m_FiloTopUC.FiloTopOffset)
                     EgtSetInfo( nLayId, INFO_DEPTH, m_FiloTopUC.FiloTopDepth)
                     EgtSetColor( nLayId, New Color3d(255, 255, 255))
                  End If
               End If
               EgtDraw()
            End If
         End If
         nId = EgtGetNextObjInSelWin()
      End While
   End Sub

   Private Sub OnShowDistanceVector(sender As Object, vtDist As Vector3d) Handles DrawScene.OnShowDistanceVector
      MessageTxBx.Text = DistToString(vtDist)
      MessageBrd.Background = Application.Current.FindResource("OmagCut_Green")
   End Sub

   Private Sub LoadGridData()
      Dim dSnapStep As Double = If(EgtUiUnitsAreMM(),
                                   GetPrivateProfileDouble(S_GRID, K_SNAPSTEP, 10, m_MainWindow.GetIniFile()),
                                   GetPrivateProfileDouble(S_GRID, K_SNAPSTEPINCH, 12.7, m_MainWindow.GetIniFile()))
      Dim nMinLineSStep As Integer = GetPrivateProfileInt(S_GRID, K_MINLINESSTEP, 1, m_MainWindow.GetIniFile())
      Dim nMajLineSStep As Integer = GetPrivateProfileInt(S_GRID, K_MAJLINESSTEP, 10, m_MainWindow.GetIniFile())
      Dim nExtSStep As Integer = GetPrivateProfileInt(S_GRID, K_EXTSSTEP, 50, m_MainWindow.GetIniFile())
      Dim MinLnColor As New Color3d(160, 160, 160)
      GetPrivateProfileColor(S_GRID, K_MINLNCOLOR, MinLnColor, m_MainWindow.GetIniFile())
      Dim MajLnColor As New Color3d(160, 160, 160)
      GetPrivateProfileColor(S_GRID, K_MAJLNCOLOR, MajLnColor, m_MainWindow.GetIniFile())
      EgtSetGridFrame(Frame3d.GLOB)
      EgtSetGridGeo(dSnapStep, nMinLineSStep, nMajLineSStep, nExtSStep)
      EgtSetGridColor(MinLnColor, MajLnColor)
      Dim bShowGrid As Boolean = (GetPrivateProfileInt(S_GRID, K_SHOWGRID, 1, m_MainWindow.GetIniFile()) <> 0)
      EgtSetGridShow(bShowGrid, False)
   End Sub

   Public Sub SelectedComponent(sCompo As String)
      ' Carico componente
      LoadCurrentCompo(sCompo)
   End Sub

   Private Sub LoadCurrentCompo(ByVal sCompo As String)
      ' Verifico se cambiato
      If sCompo = m_sCompoName Then
         Return
      End If

      m_sCompoName = sCompo
      ' Pulisco l'ambiente lua
      ResetLuaVariables()
      ' Carico il file ed eseguo in modalità anteprima
      Dim bOk As Boolean = ExecCompoFile()
      Dim sMsg As String = String.Empty
      ' Verifico se compo interno o esterno
      Dim InternalCompo As Integer = -1
      EgtLuaGetGlobIntVar(LUA_CMP_INTERNAL, InternalCompo)
      bOk = bOk AndAlso MakePreview(sMsg)
      If Not bOk And InternalCompo <> 1 Then
         EgtNewFile()
      End If
      MessageTxBl.Text = sMsg
      MessageGrid.Background = If(m_bDrawOk, Brushes.Transparent, Application.Current.FindResource("OmagCut_Red"))
      DrawScene.ZoomAll()
      ' leggo variabili e aggiorno griglia
      ReadAndShowVariables()
      ' abilito bottoni Vista e Inserisci
      OkBtn.IsEnabled = True
   End Sub

   Friend Sub BackBtn_Click(sender As Object, e As RoutedEventArgs) Handles BackBtn.Click
      m_SceneButtons.MeasureBtn.IsChecked = False
      DrawPage_Unloaded(sender, e)
      ' Elimino nome del componente precedente
      m_sCompoName = String.Empty
      ' Reset inclinazioni
      m_SideAngleUC.DeleteSideAngle()
      If String.IsNullOrEmpty(m_MainComponentPage.m_SecondaryComponentPage.m_sCurrCompo) Then
         DrawPage_Loaded(sender, e)
      Else
         LoadSecondaryPage()
      End If
   End Sub

   Private Sub LoadSecondaryPage()
      EgtSetCurrentContext(DrawScene.GetCtx())

      ' inibisco selezione diretta da Scene
      DrawScene.SetStatusNull()
      ' pulisco la scena e relativo db
      EgtNewFile()
      EgtDraw()

      ' Seleziono la Tab e la Page di apertura
      VariablesGrd.Children.Remove(m_CompoDimension)
      LeftButtonGrd.Children.Add(m_MainComponentPage.m_SecondaryComponentPage)
      m_ActiveComponentPage = Pages.MainComponent
      MessageGrid.Visibility = Windows.Visibility.Hidden
      BackBtn.Visibility = Windows.Visibility.Hidden
      TopGrd.Visibility = Windows.Visibility.Hidden
      PartNameGrd.Visibility = Windows.Visibility.Hidden
      PartNumberGrd.Visibility = Windows.Visibility.Hidden

      ' Valore di default del nome e del numero pezzi
      PartNameTxBx.Text = String.Empty
      PartNumTxBx.Text = "1"

   End Sub

   Public Sub UpdateView()
      ' verifico ci sia un componente corrente
      If String.IsNullOrWhiteSpace(m_sCompoName) Then
         Return
      End If
      ' aggiorno le variabili dalla griglia
      UpdateVariables()
      ' ricalcolo il disegno
      Dim sMsg As String = String.Empty
      MakePreview(sMsg)
      MessageTxBl.Text = sMsg
      MessageGrid.Background = If(m_bDrawOk, Brushes.Transparent, Application.Current.FindResource("OmagCut_Red"))
      ' aggiorno visualizzazione
      EgtSetView(VT.TOP, False)
      EgtZoom(ZM.ALL)
   End Sub

   Private Function ExecCompoFile() As Boolean
      ' Costruisco path completa del componente
      Dim sPath = m_sCompoDir & "\" & m_sCompoName
      ' Carico il file
      Return EgtLuaExecFile(sPath)
   End Function

   Private Function ReadAndShowVariables() As Boolean
      ' Recupero nome, tipo e valore delle variabili globali
      For i As Integer = 1 To NUM_VAR
         Dim CVar = New CompoVar
         CVar.m_nInd = i
         If CVar.NameTypeValueFromLua() Then
            m_CVars(i - 1) = CVar
         Else
            m_CVars(i - 1) = Nothing
         End If
      Next

      ' Aggiorno la griglia dalle variabili
      m_bShowVar = True

      ' Conto numero variabili definite e da nascondere
      Dim nShow As Integer = GetDefinedVarCount()
      Dim nHide As Integer = NUM_VAR - nShow

      For i As Integer = 1 To nHide
         m_CompoDimension.GetNameEdit(i).Visibility = Windows.Visibility.Hidden
         m_CompoDimension.GetValueEdit(i).Visibility = Windows.Visibility.Hidden
      Next
      For i As Integer = 1 To nShow
         Dim j As Integer = nHide + i
         m_CompoDimension.GetNameEdit(j).Text = m_CVars(i - 1).m_sName
         m_CompoDimension.GetNameEdit(j).Visibility = Windows.Visibility.Visible
         m_CompoDimension.GetValueEdit(j).Text = m_CVars(i - 1).ToString()
         m_CompoDimension.GetValueEdit(j).Visibility = Windows.Visibility.Visible
         If m_CVars(i - 1).m_nType = 5 Then
            TryCast(m_CompoDimension.GetValueEdit(j), EgtTextBox).Keyboard = EgtTextBox.KeyboardType.Alphanumeric
            TryCast(m_CompoDimension.GetValueEdit(j), EgtTextBox).KeyboardDimension = 600
         Else
            TryCast(m_CompoDimension.GetValueEdit(j), EgtTextBox).Keyboard = EgtTextBox.KeyboardType.Calculator
            TryCast(m_CompoDimension.GetValueEdit(j), EgtTextBox).KeyboardDimension = 300
         End If
      Next
      m_bShowVar = False
      Return True
   End Function

   Private Function ShowVariables() As Boolean
      ' Conto numero variabili definite e nascoste
      Dim nShow As Integer = GetDefinedVarCount()
      Dim nHide As Integer = NUM_VAR - nShow
      ' Aggiorno i valori visualizzati
      m_bShowVar = True
      For i As Integer = 1 To nShow
         Dim j As Integer = nHide + i
         m_CompoDimension.GetValueEdit(j).Text = m_CVars(i - 1).ToString()
      Next
      m_bShowVar = False
      Return True
   End Function

   Private Function UpdateVariables() As Boolean
      ' Conto numero variabili definite e da nascondere
      Dim nShow As Integer = GetDefinedVarCount()
      Dim nHide As Integer = NUM_VAR - nShow
      ' aggiorno le variabili
      For i As Integer = 1 To nShow
         Dim j As Integer = nHide + i
         ' interpreto il valore, se non riesco ripristino default
         If Not m_CVars(i - 1).FromString(m_CompoDimension.GetValueEdit(j).Text) Then
            m_CompoDimension.GetValueEdit(j).Text = m_CVars(i - 1).ToString()
         End If
         ' aggiorno la corrispondente variabile lua
         If Not m_CVars(i - 1).ToLua() Then
            Dim sErr As String = String.Empty
            EgtLuaGetLastError(sErr)
            EgtOutLog(sErr)
         End If
      Next
      Return True
   End Function

   Friend Function GetDefinedVarCount() As Integer
      Dim nCount As Integer = 0
      For i As Integer = 1 To NUM_VAR
         If m_CVars(i - 1) IsNot Nothing Then
            nCount += 1
         End If
      Next
      Return nCount
   End Function

   Private Function ResetLuaVariables() As Boolean
      EgtLuaResetGlobVar(LUA_CMP_VARS)
      EgtLuaResetGlobVar(LUA_CMP_DRAW)
      Return False
   End Function

   Private Function MakePreview(ByRef sMsg As String) As Boolean
      If Not EgtLuaExecLine(LUA_CMP_DRAW & "(true)") Then
         sMsg = "Error in component execution"
         m_bDrawOk = False
      Else
         EgtLuaGetGlobStringVar(LUA_CMP_VARS & ".MSG", sMsg)
         Dim nErr As Integer = 0
         EgtLuaGetGlobIntVar(LUA_CMP_VARS & ".ERR", nErr)
         m_bDrawOk = (nErr = 0)
      End If
      EgtAdjustFlatPart(EgtGetFirstPart())
      Return m_bDrawOk
   End Function

   Private Function MakeInsert(ByVal nNbr As Integer, sName As String) As Boolean
      ' Imposto il contesto corrente
      EgtSetCurrentContext(DrawScene.GetCtx())
      ' Cancello layer regioni per selezione buchi
      Dim Pz As Integer = EgtGetFirstGroupInGroup(GDB_ID.ROOT)
      Dim SelectRegion As Integer = EgtGetFirstNameInGroup(Pz, "SelectRegion")
      EgtErase(SelectRegion)
      ' Cancello layer etichette, quotatura,ausiliario e box
      EgtErase(EgtGetFirstNameInGroup(Pz, "LayAux"))
      EgtErase(EgtGetFirstNameInGroup(Pz, "Etichette"))
      EgtErase(EgtGetFirstNameInGroup(Pz, "Quotature"))
      EgtErase(EgtGetFirstNameInGroup(Pz, "Box"))
      ' Cancello layer etichette dei componenti interni (buchi)
      Dim nHLId As Integer = EgtGetFirstNameInGroup(Pz, "HoleLabels")
      While nHLId <> GDB_ID.NULL
         EgtErase(nHLId)
         nHLId = EgtGetFirstNameInGroup(Pz, "HoleLabels")
      End While
      ' Attivo visualizzazione misura
      Dim nRegLayId As Integer = EgtGetFirstNameInGroup(Pz, NAME_REGION)
      Dim nId As Integer = EgtGetFirstInGroup(nRegLayId)
      While nId <> GDB_ID.NULL
         If EgtGetType(nId) = GDB_TY.EXT_TEXT Then
            EgtSetStatus(nId, GDB_ST.ON_)
         End If
         nId = EgtGetNext(nId)
      End While
      ' Calcolo dimensione ingombro Pezzo tramite OutLoop
      Dim nOutLoopLayer = EgtGetFirstNameInGroup(Pz, NAME_OUTLOOP)
      Dim b3Part As New BBox3d
      EgtGetBBoxGlob(nOutLoopLayer, GDB_BB.STANDARD, b3Part)
      ' Muovo la regione in Z per evitare problemi in visualizzazione
      EgtMove(nRegLayId, New Vector3d(0, 0, DELTAZ_REG), GDB_RT.GLOB)
      ' Se pezzo con dati TRF
      If m_bTrfData Then
         ' Nome da dati Trf
         Dim nTextId = EgtGetFirstInGroup(nRegLayId)
         While nTextId <> GDB_ID.NULL
            If EgtGetType(nTextId) = GDB_TY.EXT_TEXT Then
               Dim sText As String = m_TrfOrderCode & "-" & m_TrfOrderDesc
               Dim sText2 As String = m_TrfMatCode & "-" & m_TrfSurfCode
               Dim sText3 As String = LenToString(b3Part.DimX(), 0) & " x " & LenToString(b3Part.DimY(), 0) & " x " & LenToString(m_TrfThickness, 0)
               Dim dRatio As Double = Math.Max(b3Part.DimX(), b3Part.DimY()) / Math.Min(b3Part.DimX(), b3Part.DimY())
               If dRatio < 5 Then
                  sText = sText & "<br/>" & sText2 & "<br/>" & sText3
               Else
                  sText = sText & "  " & sText2 & "  " & sText3
               End If
               EgtModifyText(nTextId, sText)
               Dim ptCen As Point3d
               EgtCenterPoint(nTextId, ptCen)
               Dim b3Text As New BBox3d
               EgtGetBBoxGlob(nTextId, GDB_BB.STANDARD, b3Text)
               Dim dCoeff As Double = Math.Min(b3Part.DimX() / b3Text.DimX(), b3Part.DimY() / b3Text.DimY()) / 1.25
               If dCoeff < 1 Then EgtScale(nTextId, New Frame3d(ptCen), dCoeff, dCoeff, dCoeff)
               Exit While
            End If
            nTextId = EgtGetNext(nTextId)
         End While
         ' Info di pezzo da dati Trf
         EgtSetInfo( Pz, "OC", m_TrfOrderCode)
         EgtSetInfo( Pz, "OD", m_TrfOrderDesc)
         EgtSetInfo( Pz, "PC", m_TrfPartCode)
         EgtSetInfo( Pz, "MT", m_TrfMatCode)
         EgtSetInfo( Pz, "SRF", m_TrfSurfCode)
         EgtSetInfo( Pz, "L", DoubleToString( b3Part.DimX(), 1))
         EgtSetInfo( Pz, "W", DoubleToString( b3Part.DimY(), 1))
         EgtSetInfo( Pz, "T", m_TrfThickness)
         EgtSetInfo( Pz, "V1", DoubleToString( b3Part.DimX(), 1))
         EgtSetInfo( Pz, "V2", DoubleToString( b3Part.DimY(), 1))
      ' Se altrimenti pezzo con dati Csv
      ElseIf m_bCsvData Then
         ' Nome del pezzo
         EgtSetName( Pz, m_sCsvName)
         ' Dati Csv
         EgtSetInfo( Pz, INFO_CSV_PART, m_sCsvName)
         EgtSetInfo( Pz, INFO_CSV_ORD, m_sCsvOrder)
         EgtSetInfo( Pz, INFO_CSV_DIST, m_sCsvList)
         EgtSetInfo( Pz, INFO_CSV_MAT, m_MainWindow.m_CurrentMachine.CurrMat.sName)
         EgtSetInfo( Pz, INFO_CSV_V1, DoubleToString( b3Part.DimX(), 1))
         EgtSetInfo( Pz, INFO_CSV_V2, DoubleToString( b3Part.DimY(), 1))
         ' Se definito nome lo inserisco nel testo
         If Not String.IsNullOrWhiteSpace( m_sCsvName) Then
            Dim nTextId = EgtGetFirstInGroup(nRegLayId)
            While nTextId <> GDB_ID.NULL
               If EgtGetType(nTextId) = GDB_TY.EXT_TEXT Then
                  Dim sText As String = String.Empty
                  EgtTextGetContent(nTextId, sText)
                  Dim sNewText = m_sCsvName & "<br/>" & sText
                  EgtModifyText(nTextId, sNewText)
                  Exit While
               End If
               nTextId = EgtGetNext(nTextId)
            End While
         End If
      ' Altrimenti pezzo con dati normali
      Else
         ' Se definito nome lo inserisco nel testo
         If Not String.IsNullOrWhiteSpace(sName) Then
            Dim nTextId = EgtGetFirstInGroup(nRegLayId)
            While nTextId <> GDB_ID.NULL
               If EgtGetType(nTextId) = GDB_TY.EXT_TEXT Then
                  Dim sText As String = String.Empty
                  EgtTextGetContent(nTextId, sText)
                  Dim sNewText = sName & "<br/>" & sText
                  EgtModifyText(nTextId, sNewText)
                  Exit While
               End If
               nTextId = EgtGetNext(nTextId)
            End While
         End If
      End If
      ' Eventuale testo per indicare il sopra (solo nel caso di rettangolo)
      If TopChBx.IsVisible() And TopChBx.IsChecked() Then
         Utility.AddTopToPartRegion( nRegLayId)
      End If
      ' Scrivo testi per nesting
      SideAngle.WriteSideAngleForNest(DrawScene.GetCtx())
      ' Imposto colore testi
      Utility.SetTextColor( nRegLayId)
      ' Esporto il pezzo in un file temporaneo
      Dim sTmpFile As String = m_MainWindow.GetTempDir() & "\FlatPartCompo.Nge"
      If Not EgtSaveObjToFile(1, sTmpFile, NGE.BIN) Then
         Return False
      End If
      ' Passo al contesto principale
      EgtSetCurrentContext(m_MainWindow.m_CurrentProjectPageUC.CurrentProjectScene.GetCtx())
      ' Recupero flag per inserimento diretto in grezzo (altrimenti in parcheggio)
      Dim bDirect As Boolean = (GetPrivateProfileInt(S_NEST, K_DIRECT, 0, m_MainWindow.GetIniFile()) <> 0)
      ' Elimino eventuali precedenti pezzi vuoti
      EgtEraseEmptyParts()
      ' Area dei nuovi pezzi
      Dim dNewArea As Double = 0
      ' Se esiste il file del pezzo
      If My.Computer.FileSystem.FileExists(sTmpFile) Then
         ' eseguo inserimento
         For i As Integer = 1 To nNbr
            ' Inserisco il pezzo
            EgtInsertFile(sTmpFile)
            ' Ne recupero l'Id
            Dim nId2 As Integer = EgtGetLastPart()
            ' Aggiusto per lavorazioni
            EgtAdjustFlatPart(nId2)
            ' Se dati Trf assegno nome univoco
            If m_bTrfData Then EgtSetInfo(nId2, "CsvPart", m_TrfOrderCode & "-" & nId2.ToString())
            ' Aggiorno l'area dei nuovi pezzi
            dNewArea += GeomCalc.GetPartArea( nId2)
            ' Inserisco in parcheggio
            m_MainWindow.m_CadCutPageUC.m_NestPage.StoreOnePart(nId2, True)
            ' Se richiesto posizionamento diretto, lo eseguo
            If bDirect Then
               If m_MainWindow.m_CadCutPageUC.m_NestPage.InsertOnePart(nId2) Then
                  ' Eventuale notifica al VeinMatching
                  VeinMatching.OnInsertPartInRaw(nId2)
               End If
            End If
         Next
         ' Cancello il file
         My.Computer.FileSystem.DeleteFile(sTmpFile)
      End If
      ' Aggiorno Aree totale e da lavorare dei pezzi
      m_MainWindow.m_CurrentProjectPageUC.UpdateTotalArea( dNewArea)
      m_MainWindow.m_CurrentProjectPageUC.UpdateToProduceArea()
      m_MainWindow.m_CurrentProjectPageUC.ShowAreas()
      ' Aggiorno ambiente principale
      EgtZoom(ZM.ALL)
      Return True
   End Function

   ' permette di inserire più di un part
   Private Function MakeMultipleInsert(ByVal nNbr As Integer, sName As String) As Boolean

      Dim InsertColor As Color3d = CompoColor(m_MainWindow.GetIniFile())

      ' Imposto il contesto corrente
      EgtSetCurrentContext(DrawScene.GetCtx())
      Dim Pz As Integer = -1
      Dim NxtPz As Integer = -1

      ' Cancello layer regioni per selezione buchi
      Pz = EgtGetFirstGroupInGroup(GDB_ID.ROOT)

      ' identificativo univoico del gruppo di pezzi, se più di un pezzo
      Dim sGUICode As String = String.Empty

      While Pz <> -1
         ' imposto il contesto corrente
         EgtSetCurrentContext(DrawScene.GetCtx())
         ' cerco un altro pezzo nell'elenco
         NxtPz = EgtGetNextPart(Pz)

         Dim SelectRegion As Integer = EgtGetFirstNameInGroup(Pz, "SelectRegion")
         EgtErase(SelectRegion)
         ' Cancello layer etichette, quotatura,ausiliario e box
         EgtErase(EgtGetFirstNameInGroup(Pz, "LayAux"))
         EgtErase(EgtGetFirstNameInGroup(Pz, "Etichette"))
         EgtErase(EgtGetFirstNameInGroup(Pz, "Quotature"))
         EgtErase(EgtGetFirstNameInGroup(Pz, "Box"))

         ' Cancello layer etichette dei componenti interni (buchi)
         Dim nHLId As Integer = EgtGetFirstNameInGroup(Pz, "HoleLabels")
         While nHLId <> GDB_ID.NULL
            EgtErase(nHLId)
            nHLId = EgtGetFirstNameInGroup(Pz, "HoleLabels")
         End While

         ' Attivo visualizzazione misura
         Dim nRegLayId As Integer = EgtGetFirstNameInGroup(Pz, NAME_REGION)
         Dim nId As Integer = EgtGetFirstInGroup(nRegLayId)
         While nId <> GDB_ID.NULL
            If EgtGetType(nId) = GDB_TY.EXT_TEXT Then
               EgtSetStatus(nId, GDB_ST.ON_)
            End If
            nId = EgtGetNext(nId)
         End While

         ' Calcolo dimensione ingombro Pezzo tramite OutLoop
         Dim nOutLoopLayer = EgtGetFirstNameInGroup(Pz, NAME_OUTLOOP)
         Dim b3Part As New BBox3d
         EgtGetBBoxGlob(nOutLoopLayer, GDB_BB.STANDARD, b3Part)
         ' Muovo la regione in Z per evitare problemi in visualizzazione
         EgtMove(nRegLayId, New Vector3d(0, 0, DELTAZ_REG), GDB_RT.GLOB)

         ' Se pezzo con dati TRF
         If m_bTrfData Then
            ' Nome da dati Trf
            Dim nTextId = EgtGetFirstInGroup(nRegLayId)
            While nTextId <> GDB_ID.NULL
               If EgtGetType(nTextId) = GDB_TY.EXT_TEXT Then
                  Dim sText As String = m_TrfOrderCode & "-" & m_TrfOrderDesc
                  Dim sText2 As String = m_TrfMatCode & "-" & m_TrfSurfCode
                  Dim sText3 As String = LenToString(b3Part.DimX(), 0) & " x " & LenToString(b3Part.DimY(), 0) & " x " & LenToString(m_TrfThickness, 0)
                  Dim dRatio As Double = Math.Max(b3Part.DimX(), b3Part.DimY()) / Math.Min(b3Part.DimX(), b3Part.DimY())
                  If dRatio < 5 Then
                     sText = sText & "<br/>" & sText2 & "<br/>" & sText3
                  Else
                     sText = sText & "  " & sText2 & "  " & sText3
                  End If
                  EgtModifyText(nTextId, sText)
                  Dim ptCen As Point3d
                  EgtCenterPoint(nTextId, ptCen)
                  Dim b3Text As New BBox3d
                  EgtGetBBoxGlob(nTextId, GDB_BB.STANDARD, b3Text)
                  Dim dCoeff As Double = Math.Min(b3Part.DimX() / b3Text.DimX(), b3Part.DimY() / b3Text.DimY()) / 1.25
                  If dCoeff < 1 Then EgtScale(nTextId, New Frame3d(ptCen), dCoeff, dCoeff, dCoeff)
                  Exit While
               End If
               nTextId = EgtGetNext(nTextId)
            End While
            ' Info di pezzo da dati Trf
            EgtSetInfo(Pz, "OC", m_TrfOrderCode)
            EgtSetInfo(Pz, "OD", m_TrfOrderDesc)
            EgtSetInfo(Pz, "PC", m_TrfPartCode)
            EgtSetInfo(Pz, "MT", m_TrfMatCode)
            EgtSetInfo(Pz, "SRF", m_TrfSurfCode)
            EgtSetInfo(Pz, "L", DoubleToString(b3Part.DimX(), 1))
            EgtSetInfo(Pz, "W", DoubleToString(b3Part.DimY(), 1))
            EgtSetInfo(Pz, "T", m_TrfThickness)
            EgtSetInfo(Pz, "V1", DoubleToString(b3Part.DimX(), 1))
            EgtSetInfo(Pz, "V2", DoubleToString(b3Part.DimY(), 1))
            ' Se altrimenti pezzo con dati Csv
         ElseIf m_bCsvData Then
            ' Nome del pezzo
            EgtSetName(Pz, m_sCsvName)
            ' Dati Csv
            EgtSetInfo(Pz, INFO_CSV_PART, m_sCsvName)
            EgtSetInfo(Pz, INFO_CSV_ORD, m_sCsvOrder)
            EgtSetInfo(Pz, INFO_CSV_DIST, m_sCsvList)
            EgtSetInfo(Pz, INFO_CSV_MAT, m_MainWindow.m_CurrentMachine.CurrMat.sName)
            EgtSetInfo(Pz, INFO_CSV_V1, DoubleToString(b3Part.DimX(), 1))
            EgtSetInfo(Pz, INFO_CSV_V2, DoubleToString(b3Part.DimY(), 1))
            ' Se definito nome lo inserisco nel testo
            If Not String.IsNullOrWhiteSpace(m_sCsvName) Then
               Dim nTextId = EgtGetFirstInGroup(nRegLayId)
               While nTextId <> GDB_ID.NULL
                  If EgtGetType(nTextId) = GDB_TY.EXT_TEXT Then
                     Dim sText As String = String.Empty
                     EgtTextGetContent(nTextId, sText)
                     Dim sNewText = m_sCsvName & "<br/>" & sText
                     EgtModifyText(nTextId, sNewText)
                     Exit While
                  End If
                  nTextId = EgtGetNext(nTextId)
               End While
            End If
            ' Altrimenti pezzo con dati normali
         Else
            ' Se definito nome lo inserisco nel testo
            If Not String.IsNullOrWhiteSpace(sName) Then
               Dim nTextId = EgtGetFirstInGroup(nRegLayId)
               While nTextId <> GDB_ID.NULL
                  If EgtGetType(nTextId) = GDB_TY.EXT_TEXT Then
                     Dim sText As String = String.Empty
                     EgtTextGetContent(nTextId, sText)
                     Dim sNewText = sName & "<br/>" & sText
                     EgtModifyText(nTextId, sNewText)
                     Exit While
                  End If
                  nTextId = EgtGetNext(nTextId)
               End While
            End If
         End If
         ' Eventuale testo per indicare il sopra (solo nel caso di rettangolo)
         If TopChBx.IsVisible() And TopChBx.IsChecked() Then
            Utility.AddTopToPartRegion(nRegLayId)
         End If
         ' Scrivo testi per nesting
         SideAngle.WriteSideAngleForNest(DrawScene.GetCtx())
         ' Imposto colore testi
         Utility.SetTextColor(nRegLayId)
         ' Imposto il colore del pezzo inserito nel progetto
         EgtSetColor(nRegLayId, InsertColor)
         Dim EntId As Integer = EgtGetFirstInGroup(nRegLayId)
         While EntId <> GDB_ID.NULL
            If EgtGetType( EntId) = GDB_TY.SRF_FRGN Then EgtSetColor(EntId, InsertColor)
            EntId = EgtGetNext(EntId)
         End While

         ' Esporto il pezzo in un file temporaneo
         Dim sTmpFile As String = m_MainWindow.GetTempDir() & "\FlatPartCompo.Nge"
         If Not EgtSaveObjToFile(Pz, sTmpFile, NGE.BIN) Then
            Return False
         End If

         ' Passo al contesto principale
         EgtSetCurrentContext(m_MainWindow.m_CurrentProjectPageUC.CurrentProjectScene.GetCtx())
         ' Recupero flag per inserimento diretto in grezzo (altrimenti in parcheggio)
         Dim bDirect As Boolean = (GetPrivateProfileInt(S_NEST, K_DIRECT, 0, m_MainWindow.GetIniFile()) <> 0)
         ' Elimino eventuali precedenti pezzi vuoti
         EgtEraseEmptyParts()
         ' Area dei nuovi pezzi
         Dim dNewArea As Double = 0

         If nNbr > 1 Then
            sGUICode = System.Guid.NewGuid.ToString
         End If

         ' Se esiste il file del pezzo
         If My.Computer.FileSystem.FileExists(sTmpFile) Then
            ' eseguo inserimento
            For i As Integer = 1 To nNbr
               ' Inserisco il pezzo
               EgtInsertFile(sTmpFile)
               ' Ne recupero l'Id
               Dim nId2 As Integer = EgtGetLastPart()
               ' Aggiusto per lavorazioni
               EgtAdjustFlatPart(nId2)
               ' Se dati Trf assegno nome univoco
               If m_bTrfData Then EgtSetInfo(nId2, "CsvPart", m_TrfOrderCode & "-" & nId2.ToString())
               ' Aggiorno l'area dei nuovi pezzi
               dNewArea += GeomCalc.GetPartArea(nId2)

               ' assegno l'identificatico del pezzo, se esiste
               If Not String.IsNullOrEmpty(sGUICode) Then
                  Dim sPreGuid As String = CreatePreGuidCode(nId2)
                  EgtSetInfo(nId2, INFO_REFGROUP, sPreGuid & sGUICode)
               End If
               ' muovo il pezzo nella prima posizione di parcheggio libera
               m_MainWindow.m_CadCutPageUC.m_NestPage.StoreOnePart(nId2, True)

               ' ------------------------ AGGIUNGO PEZZO NEL VEINMATCH ----------------------------------
               ' verifico che il pezzo sia un Piano Cucina o un Piano Bagno o un'Aletta
               Dim sCMP As String = String.Empty
               EgtGetInfo(nId2, "CMP", sCMP)
               If sCMP.StartsWith("PCucina") Or sCMP.StartsWith("PBagno") Or sCMP.StartsWith("AlzFront") Then
                  ' Aggiungo riferimento e lo inserisco in VeinMatching
                  VeinMatching.SetRefOnPart(nId2)
                  VeinMatching.AddPartFromDraw(nId2)
                  ' Se richiesto posizionamento diretto, lo eseguo
                  If bDirect Then
                     If m_MainWindow.m_CadCutPageUC.m_NestPage.InsertOnePart(nId2) Then
                        ' Eventuale notifica al VeinMatching
                        VeinMatching.OnInsertPartInRaw(nId2)
                     End If
                  End If
               End If
               ' ------------------------ AGGIUNGO PEZZO NEL VEINMATCH ----------------------------------

            Next
            ' Cancello il file
            My.Computer.FileSystem.DeleteFile(sTmpFile)
         End If
         ' Aggiorno Aree totale
         m_MainWindow.m_CurrentProjectPageUC.UpdateTotalArea(dNewArea)
         ' passo al pezzo successivo
         Pz = NxtPz
      End While
      ' Aggiorno Aree da lavorare dei pezzi
      m_MainWindow.m_CurrentProjectPageUC.UpdateToProduceArea()
      m_MainWindow.m_CurrentProjectPageUC.ShowAreas()
      ' Aggiorno ambiente principale
      EgtZoom(ZM.ALL)
      Return True
   End Function

   Private Sub OkBtn_Click(sender As Object, e As RoutedEventArgs) Handles OkBtn.Click
      m_bBackFromInternalCompo = False
      m_bInternalCompo = False

      m_SceneButtons.MeasureBtn.IsChecked = False
      ' se sto definendo un componente interno non posso uscire
      If m_ActiveComponentPage = Pages.CompoDimension And m_bInternalCompo Then Return
      ' Se errore esco
      If Not m_bDrawOk Then Return
      ' Nome pezzo
      Dim sPartName As String = PartNameTxBx.Text
      ' Leggo numero di pezzi da inserire
      Dim InsNbr As Integer = Int32.Parse(PartNumTxBx.Text)
      ' Passo al contesto principale
      'MakeInsert(InsNbr, sPartName)
      MakeMultipleInsert(InsNbr, sPartName)
      ' Aggiorno ambiente principale
      EgtZoom(ZM.ALL)
      ' Elimino nome del componente precedente
      m_sCompoName = String.Empty
      ' Reset inclinazioni
      m_SideAngleUC.DeleteSideAngle()
      ' Chiudo compo interni nel caso siano aperti
      LeftButtonGrd.Children.Remove(m_MainComponentPage.m_SecondaryComponentPage)
      LeftButtonGrd.Children.Remove(m_CompoDimension.m_InternalCompoPage)
      LeftButtonGrd.Children.Remove(m_CompoDimension.m_AlzFrontPage)
      ' Istruzioni per chiudere ImportPageUC e aprire CadCutPageUC
      m_MainWindow.MainWindowGrid.Children.Remove(m_MainWindow.m_DrawPageUC)
      m_MainWindow.MainWindowGrid.Children.Add(m_MainWindow.m_CurrentProjectPageUC)
      m_MainWindow.m_ActivePage = MainWindow.Pages.CadCut

   End Sub

   ' esco dalla pagina corrente
   Private Sub ExitBtn_Click(sender As Object, e As RoutedEventArgs) Handles ExitBtn.Click
      m_bBackFromInternalCompo = False
      m_bInternalCompo = False

      m_SceneButtons.MeasureBtn.IsChecked = False
      ' Elimino nome del componente precedente
      m_sCompoName = String.Empty
      ' Reset inclinazioni
      m_SideAngleUC.DeleteSideAngle()
      ' Chiudo compo secondari e interni nel caso siano aperti
      LeftButtonGrd.Children.Remove(m_MainComponentPage.m_SecondaryComponentPage)
      LeftButtonGrd.Children.Remove(m_CompoDimension.m_InternalCompoPage)
      LeftButtonGrd.Children.Remove(m_CompoDimension.m_AlzFrontPage)
      ' Istruzioni per chiudere ImportPageUC e aprire CadCutPageUC
      m_MainWindow.MainWindowGrid.Children.Remove(m_MainWindow.m_DrawPageUC)
      m_MainWindow.MainWindowGrid.Children.Add(m_MainWindow.m_CurrentProjectPageUC)
      m_MainWindow.m_ActivePage = MainWindow.Pages.CadCut
   End Sub

   Private Sub TrfDataBtn_Click(sender As Object, e As RoutedEventArgs) Handles TrfDataBtn.Click
      If m_bTrfData Then
         Dim DlgTrfData As New CompoTrfData(m_MainWindow)
         DlgTrfData.SetData(m_TrfOrderCode, m_TrfOrderDesc, m_TrfPartCode, m_TrfMatCode, m_TrfSurfCode, m_TrfThickness)
         If DlgTrfData.ShowDialog() Then
            DlgTrfData.GetData(m_TrfOrderCode, m_TrfOrderDesc, m_TrfPartCode, m_TrfMatCode, m_TrfSurfCode, m_TrfThickness)
         End If
      ElseIf m_bCsvData Then
         Dim DlgCsvData As New CompoCsvData( m_MainWindow)
         DlgCsvData.SetData( m_sCsvOrder, m_sCsvList, m_sCsvName)
         If DlgCsvData.ShowDialog() Then
            DlgCsvData.GetData( m_sCsvOrder, m_sCsvList, m_sCsvName)
         End If
      End If
   End Sub

   Private Sub SideAngleBtn_Click(sender As Object, e As RoutedEventArgs) Handles SideAngleBtn.Click
      m_SceneButtons.MeasureBtn.IsChecked = False
      If SideAngleBtn.IsChecked Then
         ' Imposto modalità
         m_SideAngleUC.m_Mode = SideAngleUC.ModeOpt.SIDEANGLE
         If m_ActiveComponentPage = Pages.CompoDimension Then
            m_PrevSideAnglePage = Pages.CompoDimension
            VariablesGrd.Children.Remove(m_CompoDimension)
         ElseIf m_ActiveComponentPage = Pages.InternalComponent Then
            m_PrevSideAnglePage = Pages.InternalComponent
            LeftButtonGrd.Children.Remove(m_CompoDimension.m_InternalCompoPage)
         ElseIf m_ActiveComponentPage = Pages.AlzFront Then
            m_PrevSideAnglePage = Pages.AlzFront
            LeftButtonGrd.Children.Remove(m_CompoDimension.m_AlzFrontPage)
         End If
         VariablesGrd.Children.Add(m_SideAngleUC)
         FiloTopBtn.IsEnabled = False
         EngraveBtn.IsEnabled = False
         DripCutBtn.IsEnabled = False
         MessageGrid.Visibility = Windows.Visibility.Hidden
         BackBtn.Visibility = Windows.Visibility.Hidden
         ' Se non ci sono loop interni, imposto quello esterno
         If EgtGetFirstNameInGroup(EgtGetFirstPart(), NAME_INLOOP) = GDB_ID.NULL Then
            m_nSelectedLayer = EgtGetFirstNameInGroup(EgtGetFirstPart(), NAME_OUTLOOP)
         Else
            MessageTxBx.Text = EgtMsg(MSG_DRAWPAGEUC + 6)   ' Selezionare un contorno
            MessageBrd.Background = Application.Current.FindResource("OmagCut_Green")
            ' Aggiungo testi su lati già inclinati
            SideAngle.WriteSideAngleForNest(DrawScene.GetCtx())
         End If
         ' In ogni caso, nascondo layer delle misure
         Dim PartId As Integer = EgtGetFirstInGroup(GDB_ID.ROOT)
         EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_AUX), GDB_ST.OFF)
         EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_QUOTATURE), GDB_ST.OFF)
         EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_ETICHETTE), GDB_ST.OFF)
      Else
         VariablesGrd.Children.Remove(m_SideAngleUC)
         If m_PrevSideAnglePage = Pages.CompoDimension Then
            VariablesGrd.Children.Add(m_CompoDimension)
         ElseIf m_PrevSideAnglePage = Pages.InternalComponent Then
            LeftButtonGrd.Children.Add(m_CompoDimension.m_InternalCompoPage)
         End If
         FiloTopBtn.IsEnabled = m_MainWindow.m_CurrentMachine.bMilling
         EngraveBtn.IsEnabled = True
         DripCutBtn.IsEnabled = m_MainWindow.GetKeyOption(MainWindow.KEY_OPT.UNDER_CUT) And
                                Not String.IsNullOrWhiteSpace(m_MainWindow.m_CurrentMachine.sCurrDripSaw)
         MessageGrid.Visibility = Windows.Visibility.Visible
         BackBtn.Visibility = Windows.Visibility.Visible
         ' Deseleziono eventuali pezzi rimasti selezionati
         m_nSelectedLayer = GDB_ID.NULL
         EgtDeselectAll()
         ' Se non sono nei componenti interni, attivo layer delle misure
         If m_PrevSideAnglePage <> Pages.InternalComponent Then
            Dim PartId As Integer = EgtGetFirstInGroup(GDB_ID.ROOT)
            EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_AUX), GDB_ST.ON_)
            EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_QUOTATURE), GDB_ST.ON_)
            EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_ETICHETTE), GDB_ST.ON_)
         End If
         ' Pulisco area messaggi
         MessageTxBx.Text = ""
         MessageBrd.Background = Brushes.Transparent
      End If
   End Sub

   Private Sub EngraveBtn_Click(sender As Object, e As RoutedEventArgs) Handles EngraveBtn.Click
      m_SceneButtons.MeasureBtn.IsChecked = False
      If EngraveBtn.IsChecked Then
         ' Imposto modalità
         m_SideAngleUC.m_Mode = SideAngleUC.ModeOpt.ENGRAVE
         If m_ActiveComponentPage = Pages.CompoDimension Then
            m_PrevSideAnglePage = Pages.CompoDimension
            VariablesGrd.Children.Remove(m_CompoDimension)
         ElseIf m_ActiveComponentPage = Pages.InternalComponent Then
            m_PrevSideAnglePage = Pages.InternalComponent
            LeftButtonGrd.Children.Remove(m_CompoDimension.m_InternalCompoPage)
         ElseIf m_ActiveComponentPage = Pages.AlzFront Then
            m_PrevSideAnglePage = Pages.AlzFront
            LeftButtonGrd.Children.Remove(m_CompoDimension.m_AlzFrontPage)
         End If
         VariablesGrd.Children.Add(m_SideAngleUC)
         FiloTopBtn.IsEnabled = False
         SideAngleBtn.IsEnabled = False
         DripCutBtn.IsEnabled = False
         MessageGrid.Visibility = Windows.Visibility.Hidden
         BackBtn.Visibility = Windows.Visibility.Hidden
         ' Se non ci sono loop interni, imposto quello esterno
         If EgtGetFirstNameInGroup(EgtGetFirstPart(), NAME_INLOOP) = GDB_ID.NULL Then
            m_nSelectedLayer = EgtGetFirstNameInGroup(EgtGetFirstPart(), NAME_OUTLOOP)
         Else
            MessageTxBx.Text = EgtMsg(MSG_DRAWPAGEUC + 6)   ' Selezionare un contorno
            MessageBrd.Background = Application.Current.FindResource("OmagCut_Green")
         End If
         ' In ogni caso, nascondo layer delle misure
         Dim PartId As Integer = EgtGetFirstInGroup(GDB_ID.ROOT)
         EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_AUX), GDB_ST.OFF)
         EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_QUOTATURE), GDB_ST.OFF)
         EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_ETICHETTE), GDB_ST.OFF)
      Else
         VariablesGrd.Children.Remove(m_SideAngleUC)
         If m_PrevSideAnglePage = Pages.CompoDimension Then
            VariablesGrd.Children.Add(m_CompoDimension)
         ElseIf m_PrevSideAnglePage = Pages.InternalComponent Then
            LeftButtonGrd.Children.Add(m_CompoDimension.m_InternalCompoPage)
         End If
         SideAngleBtn.IsEnabled = m_bEnableSideAngle
         DripCutBtn.IsEnabled = m_MainWindow.GetKeyOption(MainWindow.KEY_OPT.UNDER_CUT) And
                                Not String.IsNullOrWhiteSpace(m_MainWindow.m_CurrentMachine.sCurrDripSaw)
         MessageGrid.Visibility = Windows.Visibility.Visible
         BackBtn.Visibility = Windows.Visibility.Visible
         ' Deseleziono eventuali pezzi rimasti selezionati
         m_nSelectedLayer = GDB_ID.NULL
         EgtDeselectAll()
         ' Se non sono nei componenti interni, attivo layer delle misure
         If m_PrevSideAnglePage <> Pages.InternalComponent Then
            Dim PartId As Integer = EgtGetFirstInGroup(GDB_ID.ROOT)
            EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_AUX), GDB_ST.ON_)
            EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_QUOTATURE), GDB_ST.ON_)
            EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_ETICHETTE), GDB_ST.ON_)
         End If
         ' Pulisco area messaggi
         MessageTxBx.Text = ""
         MessageBrd.Background = Brushes.Transparent
      End If
   End Sub

   Private Sub DripCutBtn_Click(sender As Object, e As RoutedEventArgs) Handles DripCutBtn.Click
      m_SceneButtons.MeasureBtn.IsChecked = False
      If DripCutBtn.IsChecked Then
         ' Imposto modalità
         m_SideAngleUC.m_Mode = SideAngleUC.ModeOpt.DRIP
         If m_ActiveComponentPage = Pages.CompoDimension Then
            m_PrevSideAnglePage = Pages.CompoDimension
            VariablesGrd.Children.Remove(m_CompoDimension)
         ElseIf m_ActiveComponentPage = Pages.InternalComponent Then
            m_PrevSideAnglePage = Pages.InternalComponent
            LeftButtonGrd.Children.Remove(m_CompoDimension.m_InternalCompoPage)
         ElseIf m_ActiveComponentPage = Pages.AlzFront Then
            m_PrevSideAnglePage = Pages.AlzFront
            LeftButtonGrd.Children.Remove(m_CompoDimension.m_AlzFrontPage)
         End If
         VariablesGrd.Children.Add(m_SideAngleUC)
         SideAngleBtn.IsEnabled = False
         FiloTopBtn.IsEnabled = False
         EngraveBtn.IsEnabled = False
         MessageGrid.Visibility = Windows.Visibility.Hidden
         BackBtn.Visibility = Windows.Visibility.Hidden
         ' Se non ci sono loop interni, imposto quello esterno
         If EgtGetFirstNameInGroup(EgtGetFirstPart(), NAME_INLOOP) = GDB_ID.NULL Then
            m_nSelectedLayer = EgtGetFirstNameInGroup(EgtGetFirstPart(), NAME_OUTLOOP)
         Else
            MessageTxBx.Text = EgtMsg(MSG_DRAWPAGEUC + 6)   ' Selezionare un contorno
            MessageBrd.Background = Application.Current.FindResource("OmagCut_Green")
         End If
         ' In ogni caso, nascondo layer delle misure
         Dim PartId As Integer = EgtGetFirstInGroup(GDB_ID.ROOT)
         EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_AUX), GDB_ST.OFF)
         EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_QUOTATURE), GDB_ST.OFF)
         EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_ETICHETTE), GDB_ST.OFF)
      Else
         VariablesGrd.Children.Remove(m_SideAngleUC)
         If m_PrevSideAnglePage = Pages.CompoDimension Then
            VariablesGrd.Children.Add(m_CompoDimension)
         ElseIf m_PrevSideAnglePage = Pages.InternalComponent Then
            LeftButtonGrd.Children.Add(m_CompoDimension.m_InternalCompoPage)
         End If
         SideAngleBtn.IsEnabled = m_bEnableSideAngle
         FiloTopBtn.IsEnabled = m_MainWindow.m_CurrentMachine.bMilling
         EngraveBtn.IsEnabled = True
         MessageGrid.Visibility = Windows.Visibility.Visible
         BackBtn.Visibility = Windows.Visibility.Visible
         ' Deseleziono eventuali pezzi rimasti selezionati
         m_nSelectedLayer = GDB_ID.NULL
         EgtDeselectAll()
         ' Se non sono nei componenti interni, attivo layer delle misure
         If m_PrevSideAnglePage <> Pages.InternalComponent Then
            Dim PartId As Integer = EgtGetFirstInGroup(GDB_ID.ROOT)
            EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_AUX), GDB_ST.ON_)
            EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_QUOTATURE), GDB_ST.ON_)
            EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_ETICHETTE), GDB_ST.ON_)
         End If
         ' Pulisco area messaggi
         MessageTxBx.Text = ""
         MessageBrd.Background = Brushes.Transparent
      End If
   End Sub

   Private Sub FiloTopBtn_Click(sender As Object, e As RoutedEventArgs) Handles FiloTopBtn.Click
      m_SceneButtons.MeasureBtn.IsChecked = False
      If FiloTopBtn.IsChecked Then
         ' Imposto modalità
         If m_ActiveComponentPage = Pages.CompoDimension Then
            m_PrevSideAnglePage = Pages.CompoDimension
            VariablesGrd.Children.Remove(m_CompoDimension)
         ElseIf m_ActiveComponentPage = Pages.InternalComponent Then
            m_PrevSideAnglePage = Pages.InternalComponent
            LeftButtonGrd.Children.Remove(m_CompoDimension.m_InternalCompoPage)
         ElseIf m_ActiveComponentPage = Pages.AlzFront Then
            m_PrevSideAnglePage = Pages.AlzFront
            LeftButtonGrd.Children.Remove(m_CompoDimension.m_AlzFrontPage)
         End If
         VariablesGrd.Children.Add( m_FiloTopUC)
         SideAngleBtn.IsEnabled = False
         EngraveBtn.IsEnabled = False
         DripCutBtn.IsEnabled = False
         MessageGrid.Visibility = Windows.Visibility.Hidden
         BackBtn.Visibility = Windows.Visibility.Hidden
         MessageTxBx.Text = EgtMsg( MSG_DRAWPAGEUC + 6)   ' Selezionare un contorno
         MessageBrd.Background = Application.Current.FindResource("OmagCut_Green")
         ' In ogni caso, nascondo layer delle misure
         Dim PartId As Integer = EgtGetFirstInGroup( GDB_ID.ROOT)
         EgtSetStatus(EgtGetFirstNameInGroup( PartId, COMPO_LAYER_AUX), GDB_ST.OFF)
         EgtSetStatus(EgtGetFirstNameInGroup( PartId, COMPO_LAYER_QUOTATURE), GDB_ST.OFF)
         EgtSetStatus(EgtGetFirstNameInGroup( PartId, COMPO_LAYER_ETICHETTE), GDB_ST.OFF)
      Else
         VariablesGrd.Children.Remove( m_FiloTopUC)
         If m_PrevSideAnglePage = Pages.CompoDimension Then
            VariablesGrd.Children.Add( m_CompoDimension)
         ElseIf m_PrevSideAnglePage = Pages.InternalComponent Then
            LeftButtonGrd.Children.Add( m_CompoDimension.m_InternalCompoPage)
         End If
         SideAngleBtn.IsEnabled = m_bEnableSideAngle
         EngraveBtn.IsEnabled = True
         DripCutBtn.IsEnabled = m_MainWindow.GetKeyOption(MainWindow.KEY_OPT.UNDER_CUT) And
                                Not String.IsNullOrWhiteSpace(m_MainWindow.m_CurrentMachine.sCurrDripSaw)
         MessageGrid.Visibility = Windows.Visibility.Visible
         BackBtn.Visibility = Windows.Visibility.Visible
         ' Deseleziono eventuali pezzi rimasti selezionati
         m_nSelectedLayer = GDB_ID.NULL
         EgtDeselectAll()
         ' Se non sono nei componenti interni, attivo layer delle misure
         If m_PrevSideAnglePage <> Pages.InternalComponent Then
            Dim PartId As Integer = EgtGetFirstInGroup(GDB_ID.ROOT)
            EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_AUX), GDB_ST.ON_)
            EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_QUOTATURE), GDB_ST.ON_)
            EgtSetStatus(EgtGetFirstNameInGroup(PartId, COMPO_LAYER_ETICHETTE), GDB_ST.ON_)
         End If
         ' Pulisco area messaggi
         MessageTxBx.Text = ""
         MessageBrd.Background = Brushes.Transparent
      End If
   End Sub

   Private Sub DrawPage_Unloaded(sender As Object, e As RoutedEventArgs)
      ' Seleziono la Tab e la Page di apertura
      Select Case m_ActiveComponentPage
         Case Pages.MainComponent
            LeftButtonGrd.Children.Remove( m_MainComponentPage)
         Case Pages.SecondaryComponent
            LeftButtonGrd.Children.Remove( m_MainComponentPage.m_SecondaryComponentPage)
         Case Pages.InternalComponent
            LeftButtonGrd.Children.Remove( m_MainWindow.m_DrawPageUC.m_CompoDimension.m_InternalCompoPage)
         Case Pages.CompoDimension
            VariablesGrd.Children.Remove( m_CompoDimension)
         Case Pages.SideAngle
            VariablesGrd.Children.Remove( m_SideAngleUC)
         Case Pages.FiloTop
            VariablesGrd.Children.Remove(m_FiloTopUC)
      End Select

      ' Pulisco l'ambiente lua
      ResetLuaVariables()

   End Sub

   Private Class CompoVar

      ' Public Members
      Public m_nInd As Integer
      Public m_sName As String
      Public m_nType As Integer
      Public m_bVal As Boolean
      Public m_nVal As Integer
      Public m_dVal As Double
      Public m_sVal As String

      ' Constants
      Const LUA_NAME As String = LUA_CMP_VARS & ".N"
      Const LUA_TYPE As String = LUA_CMP_VARS & ".T"
      Const LUA_VALUE As String = LUA_CMP_VARS & ".V"

      Public Sub New()
         m_nInd = 0
         m_nType = 0
      End Sub

      Public Overrides Function ToString() As String
         Select Case m_nType
            Case 1        ' booleano
               Return m_bVal.ToString()
            Case 2        ' intero
               Return m_nVal.ToString()
            Case 3        ' lunghezza
               Return DoubleToString(EgtToUiUnits(m_dVal), 4)
            Case 4        ' double
               Return DoubleToString(m_dVal, 4)
            Case 5        ' stringa
               Return m_sVal
         End Select
         Return ""
      End Function

      Public Function FromString(ByVal sVal As String, Optional bConvertUnits As Boolean = True) As Boolean
         Select Case m_nType
            Case 1        ' booleano
               Dim bVal As Boolean = False
               If Boolean.TryParse(sVal, bVal) Then
                  m_bVal = bVal
                  Return True
               End If
            Case 2        ' intero
               Dim nVal As Integer
               If StringToInt(sVal, nVal) Then
                  m_nVal = nVal
                  Return True
               End If
            Case 3        ' lunghezza
               Dim dVal As Double
               If StringToDouble(sVal, dVal) Then
                  If bConvertUnits Then
                     m_dVal = EgtFromUiUnits(dVal)
                  Else
                     m_dVal = dVal
                  End If
                  Return True
               End If
            Case 4        ' double
               Dim dVal As Double
               If StringToDouble(sVal, dVal) Then
                  m_dVal = dVal
                  Return True
               End If
            Case 5        ' stringa
               m_sVal = sVal
               Return True
         End Select
         Return False
      End Function

      Public Function ToLua() As Boolean
         Select Case m_nType
            Case 1
               Return EgtLuaSetGlobBoolVar(LUA_VALUE & m_nInd.ToString(), m_bVal)
            Case 2
               Return EgtLuaSetGlobIntVar(LUA_VALUE & m_nInd.ToString(), m_nVal)
            Case 3, 4
               Return EgtLuaSetGlobNumVar(LUA_VALUE & m_nInd.ToString(), m_dVal)
            Case 5
               Return EgtLuaSetGlobStringVar(LUA_VALUE & m_nInd.ToString(), m_sVal)
         End Select
         Return False
      End Function

      Public Function FromLua() As Boolean
         Select Case m_nType
            Case 1
               Return EgtLuaGetGlobBoolVar(LUA_VALUE & m_nInd.ToString(), m_bVal)
            Case 2
               Return EgtLuaGetGlobIntVar(LUA_VALUE & m_nInd.ToString(), m_nVal)
            Case 3, 4
               Return EgtLuaGetGlobNumVar(LUA_VALUE & m_nInd.ToString(), m_dVal)
            Case 5
               Return EgtLuaGetGlobStringVar(LUA_VALUE & m_nInd.ToString(), m_sVal)
         End Select
         Return False
      End Function

      Public Function NameTypeValueFromLua() As Boolean
         Dim bOk As Boolean = True
         bOk = bOk AndAlso EgtLuaGetGlobStringVar(LUA_NAME & m_nInd.ToString(), m_sName)
         bOk = bOk AndAlso EgtLuaGetGlobIntVar(LUA_TYPE & m_nInd.ToString(), m_nType)
         Return bOk AndAlso FromLua()
      End Function

   End Class

End Class