Imports System.Windows.Interop
Imports System.IO
Imports EgtUILib
Imports EgtWPFLib5
Imports EgtBEAMWALL.Core
Imports EgtBEAMWALL.DataLayer.DatabaseModels

Public Class MySceneHostVM
   Inherits EgtWPFLib5.SceneHostVM

   ' Identificativi per pezzo da selezionare/deselezionare
   Private m_nIdToSel As Integer = GDB_ID.NULL
   Private m_nIdToDesel As Integer = GDB_ID.NULL
   ' Dati movimento
   Private m_dMaxStep As Double = 0
   ' Dati per Drag
   Private m_nRestRadius As Integer = 5
   Private m_bDrag As Boolean = False
   Private m_bDragToStart As Boolean = False
   Private m_bVerify As Boolean = False
   Private m_bFromParking As Boolean = False
   Private m_bDragging As Boolean = False
   Private m_locPrev As System.Drawing.Point
   Private m_ptPrev As Point3d
   Private m_vtTotMove As Vector3d
   Private m_dSnapDist As Double = 0


   Private bReducedCut As Boolean = False
   Private m_bMagnetic As Boolean

#Region "CONSTRUCTOR"

   Sub New()
      MyBase.New()
      AddHandler MainController.OnNewProject, AddressOf OnNewProject
      AddHandler MainController.OnOpenProject, AddressOf OnOpenProject
      AddHandler MainController.OnSavingProject, AddressOf OnSavingProject
      AddHandler MainController.OnSavedProject, AddressOf OnSavedProject
      AddHandler MainController.OnImportingProject, AddressOf OnImportingProject
      AddHandler MainController.OnImportedProject, AddressOf OnImportedProject
      AddHandler MainController.PrepareInputBox, AddressOf PrepareInputBox
      AddHandler MainController.SetInputBoxText, AddressOf SetInputBoxText
      AddHandler MainController.SetInputBoxCheck, AddressOf SetInputBoxCheck
      AddHandler MainController.AddInputBoxCombo, AddressOf AddInputBoxCombo
      AddHandler MainController.UpdateUI, AddressOf UpdateUI
   End Sub

#End Region    ' CONSTRUCTOR

#Region "METHODS"

   Overrides Sub InitScene()
      InitSceneEvents()
      ' Inizializzazione Scena
      PreInitializeScene()
      ' Se tutto bene
      If MainScene.Init() And Map.refMainWindowVM.MainWindowM.GetKeyOption(KEY_OPT.BEAM Or KEY_OPT.WALL) Then
         PostInitializeScene()
         ' Imposto stato gestione mouse diretto della scena a nessuno
         MainScene.SetStatusNull()
         ' Imposto focus pulsante su false 
         MainScene.SetFocusOnMove(False)
         ' Recupero e imposto handle finestra principale
         Dim hMainWnd As IntPtr = New WindowInteropHelper(Application.Current.MainWindow).Handle
         EgtSetMainWindowHandle(hMainWnd)
         EgtSetCurrentContext(MainScene.GetCtx())
         ' inizializzo gestore travi e pareti
         EgtInitBeamMgr(EIB_FL.TS3_POS + EIB_FL.USEUATTR)
         ' inizializzo gestore lavorazioni
         EgtInitMachMgr(Map.refMainWindowVM.MainWindowM.sMachinesRoot, Map.refMainWindowVM.MainWindowM.sToolMakersDir)
         ' Seleziono la macchina impostata nel file ini
         Map.refMachinePanelVM.LoadCurrentMachine()
         Return
      End If
      ' Problemi
      ' Se manca la chiave
      If Map.refMainWindowVM.MainWindowM.nKeyLevel = -1 Or Map.refMainWindowVM.MainWindowM.nKeyLevel = -2 Then
         EgtOutLog("Missing Dongle")
         ' Box di avviso chiave mancante : "Chiave non presente. \n Inserirla e riavviare il programma."  "Errore"
         Dim sText As String = EgtMsg(MSG_MISSINGKEYWD + 2) & vbCrLf & EgtMsg(MSG_MISSINGKEYWD + 3)
         Dim sTitle As String = EgtMsg(MSG_MISSINGKEYWD + 1)
         MessageBox.Show(sText, sTitle, MessageBoxButton.OK, MessageBoxImage.Error)
         ' Altrimenti manca la licenza
      Else
         EgtOutLog("Problems with Licence")
         ' Box di avviso licenza con problemi : "Programma senza licenza. \n Caricala e riavvia il programma."  "Errore"
         Dim sText As String = EgtMsg(MSG_MISSINGKEYWD + 5) & vbCrLf & EgtMsg(MSG_MISSINGKEYWD + 6)
         Dim sTitle As String = EgtMsg(MSG_MISSINGKEYWD + 1)
         If MessageBox.Show(sText, sTitle, MessageBoxButton.OKCancel, MessageBoxImage.Error) = MessageBoxResult.OK Then
            ' Apro dialogo per richiesta file licenza
            Dim LicDlg As New Microsoft.Win32.OpenFileDialog() With {
               .DefaultExt = ".lic",
               .Filter = "Licences (.lic)|*.lic",
               .CheckFileExists = True,
               .ValidateNames = True
            }
            If LicDlg.ShowDialog() = True Then
               ' Recupero il direttorio del file
               Dim sDir As String = Path.GetDirectoryName(LicDlg.FileName)
               ' Se il file non è già nel direttorio di configurazione lo copio
               If Not String.Equals(Path.GetFullPath(sDir), Path.GetFullPath(Map.refMainWindowVM.MainWindowM.sConfigDir), StringComparison.OrdinalIgnoreCase) Then
                  Try
                     File.Copy(LicDlg.FileName, Path.Combine(Map.refMainWindowVM.MainWindowM.sConfigDir, LicDlg.SafeFileName), True)
                  Catch ex As Exception
                  End Try
               End If
               ' Imposto il nuovo file di licenza nell'Ini
               WriteMainPrivateProfileString(S_GENERAL, K_LICENCE, LicDlg.SafeFileName)
            End If
         End If
      End If
      ' Chiudo il programma
      End
   End Sub

   Public Overrides Sub InitSceneEvents()
      AddHandler MainScene.OnCursorPos, AddressOf OnCursorPos
      AddHandler MainScene.OnMouseSetObjFilterForSelect, AddressOf OnMouseSetObjFilterForSelect
      AddHandler MainScene.OnMouseSelectedAll, AddressOf OnMouseSelectedAll
      AddHandler MainScene.OnMouseDeselectedAll, AddressOf OnMouseDeselectedAll
      AddHandler MainScene.OnMouseDownScene, AddressOf OnMouseDownScene
      AddHandler MainScene.OnMouseMoveScene, AddressOf OnMouseMoveScene
      AddHandler MainScene.OnMouseUpScene, AddressOf OnMouseUpScene
      AddHandler MainScene.OnMouseSelectingObj, AddressOf OnMouseSelectingObj
      AddHandler MainScene.OnMouseSelectedObj, AddressOf OnMouseSelectedObj
      AddHandler MainScene.OnMouseSelectedPart, AddressOf OnMouseSelectedPart
      AddHandler MainScene.OnMouseSelectedLayer, AddressOf OnMouseSelectedLayer
      AddHandler MainScene.OnMouseSelectedPath, AddressOf OnMouseSelectedPath
      AddHandler MainScene.OnMousePointFromSelection, AddressOf OnMousePointFromSelection
      AddHandler MainScene.OnMouseDone, AddressOf OnMouseDone
      AddHandler MainScene.OnMouseSelectedPoint, AddressOf OnMouseSelectedPoint
      AddHandler MainScene.OnMouseSelectedDir, AddressOf OnMouseSelectedDir
      AddHandler MainScene.OnMouseMoveSelPoint, AddressOf OnMouseMoveSelPoint
      AddHandler MainScene.OnShowDistance, AddressOf OnShowDistance
      AddHandler MainScene.KeyDown, AddressOf OnKeyDown
      AddHandler MainScene.OnCloseGetDist, AddressOf OnCloseGetDist
      AddHandler MainScene.OnChangedSnapPointType, AddressOf OnChangedSnapPointType
   End Sub

   Private Sub PreInitializeScene()
      ' imposto colore di default
      Dim DefColor As New Color3d(0, 0, 0)
      GetMainPrivateProfileColor(S_GEOMDB, K_DEFAULTCOLOR, DefColor)
      MainScene.SetDefaultMaterial(DefColor)
      ' imposto colori sfondo
      Dim BackTopColor As New Color3d(192, 192, 192)
      GetMainPrivateProfileColor(S_SCENE, K_BACKTOP, BackTopColor)
      Dim BackBotColor As New Color3d(BackTopColor)
      GetMainPrivateProfileColor(S_SCENE, K_BACKBOTTOM, BackBotColor)
      MainScene.SetViewBackground(BackTopColor, BackBotColor)
      ' imposto colore di evidenziazione
      Dim MarkColor As New Color3d(255, 255, 0)
      GetMainPrivateProfileColor(S_SCENE, K_MARK, MarkColor)
      MainScene.SetMarkMaterial(MarkColor)
      ' imposto colore per superfici selezionate
      Dim SelSurfColor As New Color3d(255, 255, 192)
      GetMainPrivateProfileColor(S_SCENE, K_SELSURF, SelSurfColor)
      MainScene.SetSelSurfMaterial(SelSurfColor)
      ' imposto tipo e colore del rettangolo di zoom
      Dim bOutline As Boolean = True
      Dim ZwColor As New Color3d(0, 0, 0)
      GetMainPrivateProfileZoomWin(S_SCENE, K_ZOOMWIN, bOutline, ZwColor)
      MainScene.SetZoomWinAttribs(bOutline, ZwColor)
      ' imposto colore della linea di distanza
      Dim DstLnColor As New Color3d(255, 0, 0)
      GetMainPrivateProfileColor(S_SCENE, K_DISTLINE, DstLnColor)
      MainScene.SetDistLineMaterial(DstLnColor)
      ' imposto parametri OpenGL
      Dim nDriver As Integer = GetMainPrivateProfileInt(S_OPENGL, K_DRIVER, 3)
      Dim b2Buff As Boolean = (GetMainPrivateProfileInt(S_OPENGL, K_DOUBLEBUFFER, 1) <> 0)
      Dim nColorBits As Integer = GetMainPrivateProfileInt(S_OPENGL, K_COLORBITS, 32)
      Dim nDepthBits As Integer = GetMainPrivateProfileInt(S_OPENGL, K_DEPTHBITS, 32)
      MainScene.SetViewAttributes(nDriver, b2Buff, nColorBits, nDepthBits)
   End Sub

   Private Sub PostInitializeScene()
      ' Impostazioni Controller
      MainController.SetScene(MainScene)
      ' imposto tipo coordinate
      MainScene.SetGridCursorPos(True)
      ' modo di visualizzazione
      Dim nShowMode As Integer = GetMainPrivateProfileInt(S_SCENE, K_SHOWMODE, SM.SHADING)
      Map.refShowPanelVM.SetShowMode(DirectCast(nShowMode, SM))
      ' visualizzazione avanzata dei triangoli costituenti le superfici
      Dim bShowTriaAdv As Boolean = (GetMainPrivateProfileInt(S_SCENE, K_SHOWTRIAADV, 1) <> 0)
      EgtSetShowTriaAdv(bShowTriaAdv)
      ' tipo visualizzazione per Zmap
      Dim nShowZmap As Integer = GetMainPrivateProfileInt(S_SCENE, K_SHOWZMAP, 1)
      EgtSetShowZmap(DirectCast(nShowZmap, ZSM), False)
      ' dimensione lineare max in pixel delle textures
      Dim nTxrMaxLinPix As Integer = GetMainPrivateProfileInt(S_SCENE, K_TEXMAXLINPIX, 4096)
      EgtSetTextureMaxLinPixels(nTxrMaxLinPix)
      ' tipo snap point
      MainScene.SetSnapPointType(SP.PT_SKETCH)
      ' visualizzazione assemblato
      Dim nShowBuilding As Boolean = GetMainPrivateProfileInt(S_SCENE, K_SHOWBUILDING, 0) <> 0
      Map.refShowBeamPanelVM.SetShowBuilding(nShowBuilding)
      ' imposto parametri geometrici griglia
      EgtSetGridGeo(100, 1, 10, 100)
   End Sub

#End Region    ' METHODS

#Region "ProjectManager"

   Public Overrides Function NewProject() As Boolean
      EgtSetCurrentContext(MainScene.GetCtx())
      Dim bOk As Boolean = MainController.NewProject()
      MainScene.SetStatusNull()
      Return bOk
   End Function

   Public Overrides Function OpenProject(sFilePath As String) As Boolean
      EgtSetCurrentContext(MainScene.GetCtx())
      Dim bOk As Boolean = False
      If String.IsNullOrEmpty(sFilePath) Then
         ' Recupero cartella dell'ultimo progetto aperto
         Dim sDir As String = MainController.GetCurrFile()
         If String.IsNullOrWhiteSpace(sDir) Then
            GetMainPrivateProfileString(S_MRUFILES, K_FILE, "", sDir)
         End If
         If Not String.IsNullOrWhiteSpace(sDir) Then
            sDir = Path.GetDirectoryName(sDir)
         End If
         bOk = MainController.OpenProject(sDir)
      Else
         bOk = MainController.OpenProject(sFilePath, False)
      End If
      MainScene.SetStatusNull()
      Return bOk
   End Function

   Public Overrides Function SaveProject() As Boolean
      Dim bOk As Boolean = MyBase.SaveProject()
      ' Imposto stato gestione mouse diretto della scena a nessuno
      MainScene.SetStatusNull()
      Return bOk
   End Function

   Public Overrides Function SaveAsProject() As Boolean
      Dim bOk As Boolean = MyBase.SaveAsProject()
      ' Imposto stato gestione mouse diretto della scena a nessuno
      MainScene.SetStatusNull()
      Return bOk
   End Function

   Public Overrides Function ImportProject() As Boolean
      Dim sDir As String = String.Empty
      GetMainPrivateProfileString(S_MRUIMPORT, K_FILE & "1", "", sDir)
      If Not String.IsNullOrWhiteSpace(sDir) Then
         sDir = Path.GetDirectoryName(sDir)
      End If
      sDir.TrimEnd("\"c)
      Return MainController.ImportProject(sDir)
   End Function

#End Region    ' ProjectManager

#Region "SCENE EVENTS"

   Private Sub OnCursorPos(ByVal sender As Object, ByVal sCursorPos As String)
      Map.refMyStatusBarVM.SetCurrPos(sCursorPos)
   End Sub

   Private Sub OnMouseSetObjFilterForSelect(sender As Object, bZeroDim As Boolean, bCurve As Boolean,
                                            bSurf As Boolean, bVolume As Boolean, bExtra As Boolean)
      ' Se in modalità edit L250
      If Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Map.refFreeContourManagerVM.bIsActive Then
         MainController.MouseSetObjFilterForSelect(bZeroDim, bCurve, bSurf, bVolume, bExtra)
      End If
   End Sub

   Private Sub OnMouseSelectedAll(ByVal sender As Object, bOnlyVisble As Boolean)
      ' Se in modalità edit L250
      If Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Map.refFreeContourManagerVM.bIsActive Then
         MainController.MouseSelectedAll(bOnlyVisble)
      End If
   End Sub

   Private Sub OnMouseDeselectedAll(ByVal sender As Object)
      ' Se in modalità edit L250
      If Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Map.refFreeContourManagerVM.bIsActive Then
         MainController.MouseDeselectedAll()
      End If
   End Sub

   Private Sub OnMouseDownScene(sender As Object, e As Forms.MouseEventArgs)
      If e.Button = Forms.MouseButtons.Middle Then Return
      If Map.refInstrumentPanelVM.GetDistIsChecked Then Return
      Select Case Map.refMainMenuVM.SelPage
         Case Pages.VIEW
            If Not IsNothing(Map.refProjectVM.BTLStructureVM) Then
               If Map.refFreeContourManagerVM.bIsActive AndAlso
                  ( Map.refFreeContourManagerVM.SelType = FreeContourManagerVM.FreeContourTypes.ONEWITHANGLES Or
                    Map.refFreeContourManagerVM.bIsOpeningCurveCompo) Then
                  ' passo entità selezionata
                  Map.refFreeContourManagerVM.OnMouseSelectedObj(EgtGetFirstSelectedObj(), True)
               ElseIf Map.refShowBeamPanelVM.bShowAll Then
                  View_Part_OnMouseDownScene(sender, e)
               Else
                  View_Feature_OnMouseDownScene(sender, e)
               End If
            End If
         Case Pages.MACHINING
            If Not IsNothing(Map.refMachGroupPanelVM) AndAlso Not IsNothing(Map.refMachGroupPanelVM.SelectedMachGroup) Then
               Dim SelectedMachGroup As MyMachGroupVM = Map.refMachGroupPanelVM.SelectedMachGroup
               If EgtGetCurrMachGroup() = GDB_ID.NULL Then Return
               If SelectedMachGroup.nType = BWType.BEAM Then
                  Beam_OnMouseDownScene(sender, e)
               ElseIf SelectedMachGroup.nType = BWType.WALL Then
                  Wall_OnMouseDownScene(sender, e)
               End If
            End If
      End Select
   End Sub

   Private Sub OnMouseMoveScene(sender As Object, e As Forms.MouseEventArgs)
      If e.Button = Forms.MouseButtons.Middle Then Return
      If Map.refInstrumentPanelVM.GetDistIsChecked Then Return
      Select Case Map.refMainMenuVM.SelPage
         Case Pages.VIEW
            If Not IsNothing(Map.refProjectVM.BTLStructureVM) Then
               If Map.refFreeContourManagerVM.bIsActive Then Return
               If Map.refShowBeamPanelVM.bShowAll Then
                  View_Part_OnMouseMoveScene(sender, e)
               Else
                  View_Feature_OnMouseMoveScene(sender, e)
               End If
            End If
         Case Pages.MACHINING
            If Not IsNothing(Map.refMachGroupPanelVM) AndAlso Not IsNothing(Map.refMachGroupPanelVM.SelectedMachGroup) Then
               Dim SelectedMachGroup As MyMachGroupVM = Map.refMachGroupPanelVM.SelectedMachGroup
               If EgtGetCurrMachGroup() = GDB_ID.NULL Then Return
               If SelectedMachGroup.nType = BWType.BEAM Then
                  Beam_OnMouseMoveScene(sender, e)
               ElseIf SelectedMachGroup.nType = BWType.WALL Then
                  Wall_OnMouseMoveScene(sender, e)
               End If
            End If
      End Select
   End Sub

   Private Sub OnMouseUpScene(sender As Object, e As Forms.MouseEventArgs)
      If e.Button = Forms.MouseButtons.Middle Then Return
      If Map.refInstrumentPanelVM.GetDistIsChecked Then Return
      Select Case Map.refMainMenuVM.SelPage
         Case Pages.VIEW
            If Not IsNothing(Map.refProjectVM.BTLStructureVM) Then
               If Map.refFreeContourManagerVM.bIsActive AndAlso Map.refFreeContourManagerVM.SelType = FreeContourManagerVM.FreeContourTypes.ONEWITHANGLES Then
                  Return
               ElseIf Map.refShowBeamPanelVM.bShowAll Then
                  View_Part_OnMouseUpScene(sender, e)
               Else
                  View_Feature_OnMouseUpScene(sender, e)
               End If
            End If
         Case Pages.MACHINING
            If Not IsNothing(Map.refMachGroupPanelVM) AndAlso Not IsNothing(Map.refMachGroupPanelVM.SelectedMachGroup) Then
               Dim SelectedMachGroup As MyMachGroupVM = Map.refMachGroupPanelVM.SelectedMachGroup
               If EgtGetCurrMachGroup() = GDB_ID.NULL Then Return
               If SelectedMachGroup.nType = BWType.BEAM Then
                  Beam_OnMouseUpScene(sender, e)
               ElseIf SelectedMachGroup.nType = BWType.WALL Then
                  Wall_OnMouseUpScene(sender, e)
               End If
            End If
      End Select
   End Sub

   Private Sub OnMouseSelectingObj(ByVal sender As Object, ByVal nId As Integer, ByRef bOk As Boolean)
      ' Se in modalità edit L250
      If Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Map.refFreeContourManagerVM.bIsActive Then
         bOk = Map.refFreeContourManagerVM.OnMouseSelectingObj(nId)
      End If
   End Sub

   Private Sub OnMouseSelectedObj(ByVal sender As Object, ByVal nId As Integer, ByVal bLast As Boolean)
      MainController.MouseSelectedObj(nId, bLast)
   End Sub

   Private Sub OnMouseSelectedPart(ByVal sender As Object, ByVal nId As Integer)
      ' Se in modalità edit L250
      If Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Map.refFreeContourManagerVM.bIsActive Then
         MainController.MouseSelectedPart(nId)
      End If
   End Sub

   Private Sub OnMouseSelectedLayer(ByVal sender As Object, ByVal nId As Integer)
      ' Se in modalità edit L250
      If Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Map.refFreeContourManagerVM.bIsActive Then
         MainController.MouseSelectedLayer(nId)
      End If
   End Sub

   Private Sub OnMouseSelectedPath(ByVal sender As Object, ByVal nId As Integer, ByVal bHaltOnFork As Boolean)
      ' Se in modalità edit L250
      If Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Map.refFreeContourManagerVM.bIsActive Then
         MainController.MouseSelectedPath(nId, bHaltOnFork)
      End If
   End Sub

   Private Sub OnMousePointFromSelection(ByVal sender As Object, ByVal nId As Integer, ByVal PtP As Point3d, ByVal nAux As Integer)
      ' Se in modalità edit L250
      If Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Map.refFreeContourManagerVM.bIsActive Then
         MainController.SetPointFromSelection(nId, PtP, nAux)
      End If
   End Sub

   Private Sub OnMouseDone(ByVal sender As Object)
      ' Se in modalità edit L250
      If Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Map.refFreeContourManagerVM.bIsActive Then
         MainController.Done(Map.refFreeContourInputVM.Text)
      End If
   End Sub

   Private Sub OnMouseSelectedPoint(ByVal sender As Object, ByVal PtP As Point3d, ByVal nSep As SEP, ByVal nId As Integer)
      ' Se in modalità edit L250
      If Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Map.refFreeContourManagerVM.bIsActive Then
         Dim bDone As Boolean = (Keyboard.Modifiers And ModifierKeys.Control) <> ModifierKeys.Control
         MainController.MouseSelectedPoint(PtP, nSep, nId, bDone)
      End If
   End Sub

   Private Sub OnMouseSelectedDir(ByVal sender As Object, ByVal VtDir As Vector3d)
      ' Se in modalità edit L250
      If Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Map.refFreeContourManagerVM.bIsActive Then
         MainController.SetLastVector3d(VtDir)
      End If
   End Sub

   Private Sub OnMouseMoveSelPoint(ByVal sender As Object, ByVal PtP As Point3d)
      ' Se in modalità edit L250
      If Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Map.refFreeContourManagerVM.bIsActive Then
         MainController.MouseMoveInSelectionPoint(PtP)
      End If
   End Sub

   Private Sub OnShowDistance(ByVal sender As Object, ByVal sDistance As String)
      Map.refMyStatusBarVM.SetOutputMessage(sDistance)
   End Sub

   Private Sub OnKeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs)
      ' Se in modalità edit L250
      If Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Map.refFreeContourManagerVM.bIsActive Then
         ' Con DEL eseguo cancellazione delle entità selezionate
         If e.KeyData = System.Windows.Forms.Keys.Delete Then
            MainController.SetLastInteger(GDB_ID.SEL)
            MainController.ExecuteCommand(Controller.CMD.DELETE)
            ' Con SPAZIO ripeto l'ultimo comando
         ElseIf e.KeyData = System.Windows.Forms.Keys.Space Then
            MainController.RepeatLastCommand()
            ' Con 'A' e in modalità continuazione, forzo il passaggio ad arco
         ElseIf e.KeyData = System.Windows.Forms.Keys.A And MainController.GetContinue() Then
            MainController.ContinueArcPDP()
            ' Con 'L'  e in modalità continuazione, forzo il passaggio a retta
         ElseIf e.KeyData = System.Windows.Forms.Keys.L And MainController.GetContinue() Then
            MainController.ContinueLine2P()
            ' Con 'V' cambio lo stato del check
         ElseIf e.KeyData = System.Windows.Forms.Keys.V Then
            Map.refFreeContourInputVM.ChangeInputBoxCheck()
         End If
      End If
   End Sub

   Private Sub OnCloseGetDist(sender As System.Object)
      Map.refInstrumentPanelVM.SetGetDistance_IsChecked(False)
   End Sub

   Private Sub OnChangedSnapPointType(ByVal sender As Object, ByVal nSpType As SP, ByVal bUser As Boolean)
      Dim BtnColor As Brush
      If bUser Then
         BtnColor = New SolidColorBrush(SystemColors.ControlColor)
      Else
         BtnColor = Brushes.Bisque
      End If
      Select Case nSpType
         Case SP.PT_SKETCH
            Map.refMyStatusBarVM.SetSnapPointType(EgtMsg(1102), BtnColor)             'Sketch Point
         Case SP.PT_GRID
            Map.refMyStatusBarVM.SetSnapPointType(EgtMsg(1104), BtnColor)             'Grid Point
         Case SP.PT_END
            Map.refMyStatusBarVM.SetSnapPointType(EgtMsg(1106), BtnColor)             'End Point
         Case SP.PT_MID
            Map.refMyStatusBarVM.SetSnapPointType(EgtMsg(1108), BtnColor)             'Mid Point
         Case SP.CENTER
            Map.refMyStatusBarVM.SetSnapPointType(EgtMsg(1110), BtnColor)             'Center
         Case SP.CENTROID
            Map.refMyStatusBarVM.SetSnapPointType(EgtMsg(1112), BtnColor)             'Centroid
         Case SP.PT_NEAR
            Map.refMyStatusBarVM.SetSnapPointType(EgtMsg(1114), BtnColor)             'Near Point
         Case SP.PT_INTERS
            Map.refMyStatusBarVM.SetSnapPointType(EgtMsg(1116), BtnColor)             'Inters Point
         Case SP.PT_TANGENT
            Map.refMyStatusBarVM.SetSnapPointType(EgtMsg(1118), BtnColor)             'Tang Point
         Case SP.PT_PERPENDICULAR
            Map.refMyStatusBarVM.SetSnapPointType(EgtMsg(1120), BtnColor)             'Perp Point
         Case SP.PT_MINDIST
            Map.refMyStatusBarVM.SetSnapPointType(EgtMsg(1122), BtnColor)             'MinDist Point
         Case Else
            Map.refMyStatusBarVM.SetSnapPointType("---", BtnColor)
      End Select
   End Sub

#End Region    ' SCENE EVENTS

#Region "CONTROLLER EVENTS"

   Private Sub OnNewProject(sender As Object, bOk As Boolean)
      Map.refMainWindowVM.SetTitle(" New - EgtBEAMWALL")
      Map.refProjectVM.BTLStructureVM = New BTLStructureVM(BTLStructureM.CreateNewBTLStructure())
      ' carico filtri di ricerca
      Map.refProjectVM.BTLStructureVM.LoadFilters()
      EgtDraw()
      MainScene.SetStatusNull()
   End Sub

   Private Sub OnOpenProject(sender As Object, sFile As String, bOk As Boolean)
      Dim ProjectType As ProjectType = If(Map.refMainMenuVM.SelPage = Pages.VIEW, ProjectType.PROJ, ProjectType.PROD)
      Dim ProjId As Integer = If(ProjectType = ProjectType.PROJ, Map.refProjManagerVM.nLoadingProjId, 0)
      ' Procedo a seconda del risultato
      If bOk Then
         LoadingWndHelper.UpdateLoadingWnd(ActiveIds.OPENPROJ, 2, EgtMsg(63005), 50, 70)           ' Loading part list
         LoadingWndHelper.UpdateLoadingWnd(ActiveIds.OPENPROD, 2, EgtMsg(63005), 50, 70)           ' Loading part list
         ' leggo struttura BTL
         Map.refProjectVM.BTLStructureVM = New BTLStructureVM(BTLStructureM.CreateBTLStructure(ProjId))
         ' verifico se volume pezzi calcolato
         Dim bIsCalculated As Boolean = False
         For Each BTLPart In Map.refProjectVM.BTLStructureVM.BTLPartVMList
            If BTLPart.BTLPartM.dVolume > 0 Then Continue For
            bIsCalculated = True
            BTLPart.CalcBTLPartVolume()
         Next
         If bIsCalculated Then
            Dim CurrProject As String = ""
            EgtGetCurrFilePath(CurrProject)
            EgtSaveFile(CurrProject, NGE.CMPTEXT)
         End If
         WriteMainPrivateProfileString(S_GENERAL, K_LASTPROJ, sFile)
         ' in base al tipo progetto aggiungo il file in apertura alla lista degli MRU
         If ProjectType = ProjectType.PROJ Then
            ' nel caso PROJ ricavo il percorso del file tramite il ProjId
            Dim PjFileVM As ProjFileVM
            If Not IsNothing(ProjId) AndAlso ProjId <> 0 Then
               PjFileVM = New ProjFileVM(DbControllers.m_ProjController.FindByProjIdConv(ProjId))
               If Not IsNothing(PjFileVM.ProjFileM) AndAlso Not IsNothing(PjFileVM.sProjPath) Then Map.refProjManagerVM.m_MruFiles.Add(PjFileVM.sProjPath)
            End If
            ' imposto macchina del progetto
            Map.refMachinePanelVM.SelectedMachine = Map.refMachinePanelVM.MachineList.FirstOrDefault(Function(x) x.Name = Map.refProjManagerVM.TempCurrProj.sMachine)
            ' aggiorno le colonne in base al tipo progetto
            Map.refRawPartListVM.UpdateColumns(Map.refProjectVM.BTLStructureVM.BTLStructureM.nPROJTYPE)
            Map.refFeatureInPartInRawPartListVM.UpdateColumns(CurrentMachine.nType)
            Map.refTopPanelVM.ManageQParamsRowVisibility(Map.refProjectVM.BTLStructureVM.BTLStructureM.nPROJTYPE <> BWType.BEAM)
            Map.refPartInRawPartListVM.UpdateColumns(Map.refProjectVM.BTLStructureVM.BTLStructureM.nPROJTYPE)
            Map.refProjManagerVM.CurrProj = Map.refProjManagerVM.TempCurrProj
            DbControllers.m_ProjController.LockByProjId(Map.refProjManagerVM.CurrProj.nProjId, True, Map.refMainWindowVM.MainWindowM.GetKeyNumber())
            ' carico lista macchine e macchina del progetto per il pulsante Reset Macchina del CALCPanel
            Map.refCALCPanelVM.LoadMachineList()
         ElseIf ProjectType = ProjectType.PROD Then
            ' se salvato, carico progetto in lista mru
            If Not Map.refProdManagerVM.TempCurrProd.bIsNew Then
               Map.refProdManagerVM.m_MruFiles.Add(sFile)
            End If
            ' imposto macchina del progetto
            Map.refMachinePanelVM.SelectedMachine = If(Not IsNothing(Map.refProdManagerVM.TempCurrProd),
            Map.refMachinePanelVM.MachineList.FirstOrDefault(Function(x) x.Name = Map.refProdManagerVM.TempCurrProd.sMachine),
            Map.refMachinePanelVM.MachineList.FirstOrDefault(Function(x) x.Name = Map.refProjManagerVM.CurrProj.sMachine))
            SectionXMaterial.SetType(Map.refProjectVM.BTLStructureVM.BTLStructureM.nPROJTYPE)
            Core.ViewPanelVM.UpdateBWType(Map.refProjectVM.BTLStructureVM.BTLStructureM.nPROJTYPE)
            ' aggiorno le colonne in base al tipo progetto
            Map.refRawPartListVM.UpdateColumns(Map.refProjectVM.BTLStructureVM.BTLStructureM.nPROJTYPE)
            Map.refFeatureInPartInRawPartListVM.UpdateColumns(CurrentMachine.nType)
            Map.refTopPanelVM.ManageQParamsRowVisibility(Map.refProjectVM.BTLStructureVM.BTLStructureM.nPROJTYPE <> BWType.BEAM)
            Map.refPartInRawPartListVM.UpdateColumns(Map.refProjectVM.BTLStructureVM.BTLStructureM.nPROJTYPE)
            If Not IsNothing(Map.refProdManagerVM.TempCurrProd) Then Map.refProdManagerVM.CurrProd = Map.refProdManagerVM.TempCurrProd
            DbControllers.m_ProdController.LockByProdId(Map.refProdManagerVM.CurrProd.nProdId, True, Map.refMainWindowVM.MainWindowM.GetKeyNumber())
            ' carico lista macchine e macchina del progetto per il pulsante Reset Macchina del CALCPanel
            Map.refCALCPanelVM.LoadMachineList()
         End If
         If Map.refMainMenuVM.SelPage = Pages.VIEW Then
            LoadingWndHelper.UpdateLoadingWnd(ActiveIds.OPENPROJ, 3, EgtMsg(63006), 70, 100)          ' Loading graphics
            ' mostro tutti i pezzi
            Map.refShowBeamPanelVM.ShowAll(True)
         ElseIf Map.refMainMenuVM.SelPage = Pages.MACHINING Then
            ' recupero indice di modifica progetto quando caricato
            Dim CommIndex As Integer = -1
            Dim ActiveSessionList As List(Of StatusMapModel) = DbControllers.m_StatusMapController.GetProd(m_SupervisorId)
            For Each ActiveSession In ActiveSessionList
               If Not IsNothing(Map.refProdManagerVM.CurrProd) AndAlso ActiveSession.ItemId = Map.refProdManagerVM.CurrProd.nProdId Then
                  CommIndex = ActiveSession.Index
               End If
            Next
            LoadingWndHelper.UpdateLoadingWnd(ActiveIds.OPENPROD, 3, EgtMsg(63002), 70, 100)       ' Loading machining groups
            LoadingWndHelper.UpdateLoadingWnd(ActiveIds.GOTOPROD, 3, EgtMsg(63002), 50, 100)       ' Loading machining groups
            ' carico gruppi di lavorazione
            Map.refProjectVM.MachGroupPanelVM = New MyMachGroupPanelVM(MyMachGroupPanelM.CreateMyMachGroupPanel(Map.refMachinePanelVM.MachineList.ToList()))
            ' fisso indice sessione di comunicazione 
            If CommIndex > -1 Then
               Map.refProdManagerVM.CurrProd.SetModificationIndex(CommIndex)
            End If
            ' seleziono primo gruppo
            If Map.refProjectVM.MachGroupPanelVM.MachGroupVMList.Count > 0 Then
               Map.refProjectVM.MachGroupPanelVM.SelFirstMachGroup()
            Else
               Map.refProjectVM.BTLStructureVM.HideAll()
            End If
         End If
      Else
         ' in base al tipo progetto rimuovo il file in apertura dalla lista degli MRU
         If ProjectType = ProjectType.PROJ Then
            ' nel caso PROJ ricavo il percorso del file tramite il ProjId
            Dim PjFileVM As ProjFileVM
            If Not IsNothing(ProjId) AndAlso ProjId <> 0 Then
               PjFileVM = New ProjFileVM(DbControllers.m_ProjController.FindByProjIdConv(ProjId))
               If Not IsNothing(PjFileVM.ProjFileM) AndAlso Not IsNothing(PjFileVM.sProjPath) Then Map.refProjManagerVM.m_MruFiles.Remove(PjFileVM.sProjPath)
            End If
         End If
         If ProjectType = ProjectType.PROD Then Map.refProdManagerVM.m_MruFiles.Remove(sFile)
         MessageBox.Show(EgtMsg(10003) & " '" & sFile & "'", EgtMsg(10001), MessageBoxButton.OK, MessageBoxImage.Error)        'Error opening file
         Map.refProjManagerVM.NewProject()
         If Map.refMainMenuVM.SelPage = Pages.MACHINING Then
            Map.refProjectVM.MachGroupPanelVM = New MyMachGroupPanelVM(MyMachGroupPanelM.CreateMyMachGroupPanel(Map.refMachinePanelVM.MachineList.ToList()))
         End If
      End If
      ' carico filtri di ricerca
      If Not IsNothing(Map.refProjectVM.BTLStructureVM) Then Map.refProjectVM.BTLStructureVM.LoadFilters()

      MainScene.SetStatusNull()
   End Sub

   Private Sub OnSavingProject(ByVal sender As Object, sFile As String)
   End Sub

   Private Sub OnSavedProject(ByVal sender As Object, ByVal sFile As String, ByVal bOk As Boolean)
      Dim ProjectType As ProjectType = If(Map.refMainMenuVM.SelPage = Pages.VIEW, ProjectType.PROJ, ProjectType.PROD)
      Dim ProjId As Integer = If(ProjectType = ProjectType.PROJ, Map.refProjManagerVM.nLoadingProjId, 0)
      ' Se salvataggio non riuscito, esco subito
      If Not bOk Then
         ' in base al tipo progetto rimuovo il file in salvataggio dalla lista degli MRU
         If ProjectType = ProjectType.PROJ Then
            ' nel caso PROJ ricavo il percorso del file tramite il ProjId
            Dim PjFileVM As ProjFileVM
            If Not IsNothing(ProjId) AndAlso ProjId <> 0 Then
               PjFileVM = New ProjFileVM(DbControllers.m_ProjController.FindByProjIdConv(ProjId))
               If Not IsNothing(PjFileVM.ProjFileM) AndAlso Not IsNothing(PjFileVM.sProjPath) Then Map.refProjManagerVM.m_MruFiles.Remove(PjFileVM.sProjPath)
            End If
         End If
         If ProjectType = ProjectType.PROD Then Map.refProdManagerVM.m_MruFiles.Remove(sFile)
         Dim sMsg As String = EgtMsg(10004) & " '" & sFile & "'"            'Error saving file
         MessageBox.Show(sMsg, EgtMsg(10001), MessageBoxButton.OK, MessageBoxImage.Error)     ' Error
         Return
      End If
      ' in base al tipo progetto aggiungo il file in salvataggio alla lista degli MRU
      If ProjectType = ProjectType.PROJ Then
         ' nel caso PROJ ricavo il percorso del file tramite il ProjId
         Dim PjFileVM As ProjFileVM
         If Not IsNothing(ProjId) AndAlso ProjId <> 0 Then
            PjFileVM = New ProjFileVM(DbControllers.m_ProjController.FindByProjIdConv(ProjId))
            If Not IsNothing(PjFileVM.ProjFileM) AndAlso Not IsNothing(PjFileVM.sProjPath) Then Map.refProjManagerVM.m_MruFiles.Add(PjFileVM.sProjPath)
         End If
      End If
      If ProjectType = ProjectType.PROD Then Map.refProdManagerVM.m_MruFiles.Add(sFile)
      ' Salvo nome ultimo file
      WriteMainPrivateProfileString(S_GENERAL, K_LASTPROJ, sFile)
   End Sub

   Private Sub OnImportingProject(sender As Object, nType As Integer, ByRef nFlag As Integer)
      If nType = FT.BTL Or nType = FT.BTLX Then
         Dim sBTLFlag As String
         If Map.refProjManagerVM.nProjType = Core.ConstBeam.BWType.BEAM Then
            sBTLFlag = K_BTLFLAG
         Else
            sBTLFlag = K_WALLBTLFLAG
         End If
         nFlag = GetMainPrivateProfileInt(S_IMPORT, sBTLFlag, EIB_FL.TS3_POS + EIB_FL.SORT + EIB_FL.USEUATTR)
      Else
         MessageBox.Show(Application.Current.MainWindow, EgtMsg(10005), EgtMsg(10001), MessageBoxButton.OK, MessageBoxImage.Error)   ' File type unknown  - Error
      End If
   End Sub

   Private Sub OnImportedProject(ByVal sender As Object, ByVal sFile As String, ByVal bOk As Boolean)
      Dim bFirstPart As Boolean = EgtGetFirstPart() <> GDB_ID.NULL
      If bOk OrElse bFirstPart Then
         LoadingWndHelper.UpdateLoadingWnd(ActiveIds.IMPORTBTL, 2, EgtMsg(63005), 50, 70)          ' Loading parts
         ' leggo struttura BTL
         Map.refProjectVM.BTLStructureVM = New BTLStructureVM(BTLStructureM.CreateBTLStructure(0))
         Dim nPartId As Integer = EgtGetFirstPart()
         While nPartId <> GDB_ID.NULL
            ' scrivo in ogni pezzo ProjId
            EgtSetInfo(nPartId, BTL_PRT_PROJ, Map.refProjManagerVM.nLoadingProjId)
            nPartId = EgtGetNextPart(nPartId)
            ' scrivo Id negli outline 
            Dim nPRId As Integer = 1
            Dim nOutlineLayer As Integer = EgtGetFirstNameInGroup(nPartId, OUTLINE)
            If nOutlineLayer <> GDB_ID.NULL Then
               Dim nOutlineId As Integer = EgtGetFirstInGroup(nOutlineLayer)
               While nOutlineId <> GDB_ID.NULL
                  ' verifico che sia feature
                  If EgtExistsInfo(nOutlineId, MGR_FTR_PRC) Then
                     EgtSetInfo(nOutlineId, MGR_FTR_PRID, nPRId)
                     nPRId += 1
                  End If
                  nOutlineId = EgtGetNext(nOutlineId)
               End While
            End If
         End While
         ' scrivo info proj e type su layer BtlInfo
         Dim nBTLInfoLayer As Integer = EgtGetFirstNameInGroup(GDB_ID.ROOT, BTLINFO)
         EgtSetInfo(nBTLInfoLayer, BTL_PRT_PROJ, Map.refProjManagerVM.nLoadingProjId)
         EgtSetInfo(nBTLInfoLayer, BTL_GEN_PROJTYPE, Map.refProjManagerVM.CurrProj.nType)
         ' scrivo info proj su layer AsseBase
         Dim nAsseBaseLayer As Integer = EgtGetFirstNameInGroup(GDB_ID.ROOT, ASSEBASE)
         EgtSetInfo(nAsseBaseLayer, BTL_PRT_PROJ, Map.refProjManagerVM.nLoadingProjId)
      Else
         Dim sMsg As String = EgtMsg(10006) & " '" & sFile & "'"            'Error importing file
         MessageBox.Show(Application.Current.MainWindow, sMsg, EgtMsg(10001), MessageBoxButton.OK, MessageBoxImage.Error)   ' Error
         Map.refProjManagerVM.NewProject()
      End If

      MainScene.SetStatusNull()
   End Sub

   Private Sub PrepareInputBox(ByVal sTitle As String, ByVal sLabel As String, ByVal sCheckLabel As String,
                                 ByVal bShowCombo As Boolean, ByVal bShowBtn As Boolean)
      Map.refFreeContourInputVM.PrepareInputBox(sTitle, sLabel, sCheckLabel, bShowCombo, bShowBtn)
   End Sub

   Private Sub SetInputBoxText(ByVal sText As String)
      Map.refFreeContourInputVM.SetInputBoxText(sText)
   End Sub

   Private Sub SetInputBoxCheck(ByVal bCheck As Boolean)
      Map.refFreeContourInputVM.SetInputBoxCheck(bCheck)
   End Sub

   Private Sub AddInputBoxCombo(ByVal sText As String, ByVal bSelected As Boolean)
      Map.refFreeContourInputVM.AddInputBoxCombo(sText, bSelected)
   End Sub

   Private Sub UpdateUI(ByVal sender As Object, ByVal bReloadUI As Boolean)
      If Map.refFreeContourManagerVM.bIsActive Then
         ' pulisco input e relativi messaggi
         Map.refFreeContourInputVM.ResetInputBox()
         Map.refFreeContourManagerVM.UpdateUi()
      End If
      If MainController.GetContinue() Then
         Map.refMyStatusBarVM.SetOutputMessage(EgtMsg(399))      ' Continue : 'L' with line, 'A' with arc
      Else
         Map.refMyStatusBarVM.ClearOutputMessage()
      End If
   End Sub

#End Region    ' CONTROLLER EVENTS

#Region "MACHINING EVENTS"

#Region "Beam"

   Friend Sub Beam_OnMouseDownScene(sender As Object, e As Forms.MouseEventArgs)
      ' Verifico se selezionato indicativo di pezzo
      EgtSetObjFilterForSelWin(True, True, True, True, True)
      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 pezzo cui appartiene
         Dim nPartId As Integer = EgtGetParent(EgtGetParent(nId))
         Dim MyMachGroup As MyMachGroupVM = DirectCast(Map.refMachGroupPanelVM.SelectedMachGroup, MyMachGroupVM)
         Dim bPartInTable As Boolean = MyMachGroup.PartVMList.Any(Function(x) x.PartM.nRawPartId = EgtGetParent(nPartId))
         Dim bFound As Boolean = False
         If EgtIsPart(nPartId) OrElse EgtIsDuplo(nPartId) OrElse bPartInTable Then bFound = True
         If Not bFound Then
            nId = EgtGetNextObjInSelWin()
            Continue While
         End If
         Dim nStat As Integer = GDB_ST.ON_
         EgtGetStatus(nPartId, nStat)
         ' Se già selezionato
         If nStat = GDB_ST.SEL Then
            ' Memorizzo Id da deselezionare
            m_nIdToDesel = nPartId
         Else
            ' Memorizzo Id da selezionare
            m_nIdToSel = nPartId
         End If
         Exit While
         nId = EgtGetNextObjInSelWin()
      End While
      ' Dati per drag
      m_bDragToStart = True
   End Sub

   Friend Sub Beam_OnMouseMoveScene(sender As Object, e As System.Windows.Forms.MouseEventArgs)
      ' Se drag non abilitato o già in esecuzione, esco
      If Not m_bDragToStart Then Return
      ' Se primo movimento di drag, verifico di aver superato la soglia di movimento in pixel
      If m_bDragToStart Then
         If Math.Abs(e.Location.X - m_locPrev.X) < m_nRestRadius And
            Math.Abs(e.Location.Y - m_locPrev.Y) < m_nRestRadius Then
            Return
         End If
         m_bDragToStart = False
      End If
   End Sub

   Friend Sub Beam_OnMouseUpScene(sender As Object, e As System.Windows.Forms.MouseEventArgs)
      ' Se eseguito drag
      If Not m_bDragToStart Then
         ' Se selezione da eseguire
      ElseIf m_nIdToSel <> GDB_ID.NULL Then
         ' Se pezzo da selezionare non è già selezionato
         Dim SelMachgroup As MyMachGroupVM = Map.refProjectVM.MachGroupPanelVM.SelectedMachGroup
         If Not IsNothing(SelMachgroup) AndAlso
            (IsNothing(SelMachgroup.SelPart) OrElse SelMachgroup.SelPart.nPartId <> m_nIdToSel) Then
            ' Eseguo la selezione nel machgroup corrente
            SelMachgroup.SelPart = SelMachgroup.PartVMList.FirstOrDefault(Function(x) x.nPartId = m_nIdToSel)
            ' eseguo la selezione nella lista pezzi
            Dim nBTLPartId As Integer = MyMachGroupPanelM.DuploGetOriginal(m_nIdToSel)
            If Not IsNothing(nBTLPartId) Then
               Map.refProjectVM.BTLStructureVM.SetSelBTLPart(Map.refProjectVM.BTLStructureVM.BTLPartVMList.FirstOrDefault(Function(x) x.nPartId = nBTLPartId), True)
            End If
         End If
      End If
      ' Reset
      m_bDrag = False
      m_nIdToSel = GDB_ID.NULL
      m_nIdToDesel = GDB_ID.NULL
      EgtDraw()
   End Sub

#End Region       ' Beam

#Region "Wall"

   Friend Sub Wall_OnMouseDownScene(sender As Object, e As Forms.MouseEventArgs)
      ' Per default no drag
      m_bDrag = False
      ' Verifico se selezionato indicativo di pezzo
      EgtSetObjFilterForSelWin(True, True, True, True, True)
      Dim nSel As Integer
      EgtSelect(e.Location, Scene.DIM_SEL, Scene.DIM_SEL, nSel)
      Dim nId As Integer = EgtGetFirstObjInSelWin()
      While nId <> GDB_ID.NULL
         ' scarto box per evitare selezione pezzo esterno in finestre
         Dim sName As String = ""
         EgtGetName(nId, sName)
         If sName = "Box" Then
            nId = EgtGetNextObjInSelWin()
            Continue While
         End If
         ' Recupero l'identificativo del pezzo cui appartiene
         Dim nPartId As Integer = EgtGetParent(EgtGetParent(nId))
         Dim MyMachGroup As MyMachGroupVM = DirectCast(Map.refMachGroupPanelVM.SelectedMachGroup, MyMachGroupVM)
         Dim bPartInTable As Boolean = (EgtGetParent(nPartId) = MyMachGroup.MyMachGroupM.nRawPartId)
         If EgtIsPart(nPartId) OrElse EgtIsDuplo(nPartId) OrElse bPartInTable Then
            Dim nStat As Integer = GDB_ST.ON_
            EgtGetStatus(nPartId, nStat)
            ' Se già selezionato
            If nStat = GDB_ST.SEL Then
               ' Memorizzo Id da deselezionare
               m_nIdToDesel = nPartId
            Else
               ' Memorizzo Id da selezionare
               m_nIdToSel = nPartId
            End If
            ' Drag possibile
            m_bDrag = True
            Exit While
         End If
         nId = EgtGetNextObjInSelWin()
      End While
      ' Dati per drag
      m_locPrev = e.Location
      m_bDrag = m_bDrag AndAlso EgtUnProjectPoint(e.Location, m_ptPrev)
      m_bDragToStart = m_bDrag
      m_bVerify = m_bDrag AndAlso (Keyboard.Modifiers And ModifierKeys.Shift) > 0
      m_vtTotMove = Vector3d.NULL()
   End Sub

   Friend Sub Wall_OnMouseMoveScene(sender As Object, e As System.Windows.Forms.MouseEventArgs)
      ' Se drag non abilitato o già in esecuzione, esco
      If Not m_bDrag Or m_bDragging Then Return
      ' Se primo movimento di drag, verifico di aver superato la soglia di movimento in pixel
      If m_bDragToStart Then
         'If Math.Abs(e.Location.X - m_locPrev.X) < m_nRestRadius And
         '   Math.Abs(e.Location.Y - m_locPrev.Y) < m_nRestRadius Then
         '   Return
         'End If
         m_bDragToStart = False
      End If
      ' Determino cosa muovere
      Dim nMoveId = If(m_nIdToSel <> GDB_ID.NULL, m_nIdToSel, GDB_ID.SEL)
      ' se modalita' nesting manuale non attiva, esco
      If GetMainPrivateProfileInt(S_NEST, K_MANUALNEST, 0) <= 0 Then Return
      ' Inizio esecuzione di drag
      m_bDragging = True
      ' Ricavo il punto corrente in coordinate mondo
      Dim ptCurr As Point3d
      EgtUnProjectPoint(e.Location, ptCurr)
      ' Ricavo il vettore di movimento
      Dim vtMove As Vector3d = ptCurr - m_ptPrev
      ' Muovo i pezzi selezionati di quanto possibile
      If vtMove.SqLen() > EPS_SMALL * EPS_SMALL Then
         ' verifico se il pezzo da muovere e' selezionato
         If nMoveId = GDB_ID.SEL Then
            ' muovo tutti i pezzi selezionati
            Dim nPartId As Integer = EgtGetFirstSelectedObj()
            While nPartId <> GDB_ID.NULL
               EgtMovePartInRawPart(nPartId, vtMove)
               ' aggiorno valore nel PartVM
               Dim PartVM As PartVM = Map.refProjectVM.MachGroupPanelVM.SelectedMachGroup.PartVMList.FirstOrDefault(Function(x) x.nPartId = nPartId)
               If Not IsNothing(PartVM) Then
                  PartVM.NotifyPropertyChanged(NameOf(PartVM.dPOSX))
                  PartVM.NotifyPropertyChanged(NameOf(PartVM.sPOSX))
                  PartVM.NotifyPropertyChanged(NameOf(PartVM.dPOSY))
                  PartVM.NotifyPropertyChanged(NameOf(PartVM.sPOSY))
               End If
               nPartId = EgtGetNextSelectedObj()
            End While
         Else
            EgtMovePartInRawPart(nMoveId, vtMove)
            ' aggiorno valore nel PartVM
            Dim PartVM As PartVM = Map.refProjectVM.MachGroupPanelVM.SelectedMachGroup.PartVMList.FirstOrDefault(Function(x) x.nPartId = nMoveId)
            If Not IsNothing(PartVM) Then
               PartVM.NotifyPropertyChanged(NameOf(PartVM.dPOSX))
               PartVM.NotifyPropertyChanged(NameOf(PartVM.sPOSX))
               PartVM.NotifyPropertyChanged(NameOf(PartVM.dPOSY))
               PartVM.NotifyPropertyChanged(NameOf(PartVM.sPOSY))
            End If
         End If
         EgtDraw()
      End If
      ' Aggiorno il punto precedente
      m_ptPrev = ptCurr
      ' Terminata esecuzione di drag
      m_bDragging = False
   End Sub

   Private Sub Move(nMoveId As Integer, vtMove As Vector3d, ptCurr As Point3d)
      ' Se movimento con sola verifica finale
      If m_bVerify Then
         Dim x = EgtMove(nMoveId, vtMove)
         m_vtTotMove += vtMove
         ' altrimenti caso con verifica durante il movimento
      Else
         '' Aggiorno regioni per nesting
         'UpdateNestRegions()                                   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
         'EnableReferenceRegion(False)
         ' muovo il pezzo
         EgtMovePartInRawPart(nMoveId, vtMove) 'EgtMovePart(nMoveId, bReducedCut, vtMove)
         EgtSaveCollInfo()
         ' se movimento risultante nullo, provo con movimento tangente
         Dim bTgMoved As Boolean = False
         If vtMove.IsSmall() Then
            ' riprovo con movimento tangente
            Dim vtTgMove As Vector3d = ptCurr - m_ptPrev
            EgtTgMovePartOnCollision(nMoveId, bReducedCut, vtTgMove)
            bTgMoved = (Not vtTgMove.IsSmall())
         End If
         ' se abilitato magnetico (allineamento + snap), lo provo
         Dim bAlignMoved As Boolean = False
         Dim bSnapMoved As Boolean = False
         If m_bMagnetic Then
            'If Not GetLockOnRotation(nMoveId) Then
            EgtAlignPartOnCollision(nMoveId, bReducedCut, bAlignMoved)
            'End If
            If m_dSnapDist > EPS_SMALL Then
               EgtRestoreCollInfo()
               EgtMovePartToSnapPointOnCollision(nMoveId, bReducedCut, m_dSnapDist, bSnapMoved)
            End If
         End If
      End If
   End Sub

   Friend Sub Wall_OnMouseUpScene(sender As Object, e As System.Windows.Forms.MouseEventArgs)
      ' Se eseguito drag
      If Not m_bDragToStart Then
         ' Se movimento con sola verifica finale
         If m_bVerify Then
            ' Determino cosa verificare
            Dim nMoveId = If(m_nIdToSel <> GDB_ID.NULL, m_nIdToSel, GDB_ID.SEL)
            '' Aggiorno regioni per nesting 
            'UpdateNestRegions()                                                      !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            'EnableReferenceRegion(False)
            ' Eseguo verifica
            If EgtVerifyPart(nMoveId, bReducedCut) Then
               ' Non superata riporto alla posizione iniziale
            Else
               EgtMove(nMoveId, -m_vtTotMove)
            End If
            'm_bFromParking = False
            ' altrimenti caso con verifica durante il movimento
         Else
            ' Basta reset alla fine
         End If
         ' Se selezione da eseguire
      ElseIf m_nIdToSel <> GDB_ID.NULL Then
         ' se non sono in modalita' manuale
         If GetMainPrivateProfileInt(S_NEST, K_MANUALNEST, 0) <= 0 Then
            ' deseleziono tutto per evitare selezioni multiple
            EgtDeselectAll()
         End If
         ' Eseguo la selezione
         EgtSelectObj(m_nIdToSel)
         ' Se pezzo da selezionare non è già selezionato
         Dim SelMachgroup As MyMachGroupVM = Map.refProjectVM.MachGroupPanelVM.SelectedMachGroup
         If Not IsNothing(SelMachgroup) AndAlso
            (IsNothing(SelMachgroup.SelPart) OrElse SelMachgroup.SelPart.nPartId <> m_nIdToSel) Then
            ' Eseguo la selezione nel machgroup corrente
            SelMachgroup.SetSelPart(SelMachgroup.PartVMList.FirstOrDefault(Function(x) x.nPartId = m_nIdToSel))
            ' eseguo la selezione nella lista pezzi
            DirectCast(SelMachgroup.SelPart, PartVM).SelectBTLPart()
         End If
         ' Se deselezione da eseguire
      ElseIf m_nIdToDesel <> GDB_ID.NULL Then
         ' se sono in modalita' manuale, permetto la deselezione
         If GetMainPrivateProfileInt(S_NEST, K_MANUALNEST, 0) > 0 Then
            EgtDeselectObj(m_nIdToDesel)
         End If
      End If
      ' Reset
      m_bDrag = False
      m_nIdToSel = GDB_ID.NULL
      m_nIdToDesel = GDB_ID.NULL
      '' Se nessun pezzo selezionato, reset flag posizione selezionati
      'If EgtGetSelectedObjCount() = 0 Then
      '   m_nPartPos = PART_POS.NONE_TABLE
      'End If
      EgtDraw()
   End Sub

#End Region    ' Wall

#End Region    ' WALL EVENTS

#Region "VIEW EVENTS"

#Region "Part"

   Friend Sub View_Part_OnMouseDownScene(sender As Object, e As Forms.MouseEventArgs)
      ' Verifico se selezionato indicativo di pezzo
      EgtSetObjFilterForSelWin(True, True, True, True, True)
      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 pezzo cui appartiene
         Dim nPartId As Integer = EgtGetParent(EgtGetParent(nId))
         Dim bFound As Boolean = False
         If Map.refShowBeamPanelVM.ShowBuilding_IsChecked Then
            Dim nLayerId As Integer = EgtGetParent(nPartId)
            Dim sLayerName As String = ""
            EgtGetName(nLayerId, sLayerName)
            If sLayerName = ASSEBASE Then
               Dim nSou As Integer
               If EgtGetInfo(nPartId, GDB_SI_COPY, nSou) Then nPartId = nSou
               bFound = True
            End If
         Else
            If EgtIsPart(nPartId) Then bFound = True
         End If
         If Not bFound Then
            nId = EgtGetNextObjInSelWin()
            Continue While
         End If
         Dim nStat As Integer = GDB_ST.ON_
         EgtGetStatus(nPartId, nStat)
         ' Se già selezionato
         If nStat = GDB_ST.SEL Then
            ' Memorizzo Id da deselezionare
            m_nIdToDesel = nPartId
         Else
            ' Memorizzo Id da selezionare
            m_nIdToSel = nPartId
         End If
         Exit While
         nId = EgtGetNextObjInSelWin()
      End While
      ' Dati per drag
      m_bDragToStart = True
   End Sub

   Friend Sub View_Part_OnMouseMoveScene(sender As Object, e As System.Windows.Forms.MouseEventArgs)
      ' Se drag non abilitato o già in esecuzione, esco
      If Not m_bDragToStart Then Return
      ' Se primo movimento di drag, verifico di aver superato la soglia di movimento in pixel
      If m_bDragToStart Then
         If Math.Abs(e.Location.X - m_locPrev.X) < m_nRestRadius And
            Math.Abs(e.Location.Y - m_locPrev.Y) < m_nRestRadius Then
            Return
         End If
         m_bDragToStart = False
      End If
   End Sub

   Friend Sub View_Part_OnMouseUpScene(sender As Object, e As System.Windows.Forms.MouseEventArgs)
      ' Se eseguito drag
      If Not m_bDragToStart Then
         ' Se selezione da eseguire
      ElseIf m_nIdToSel <> GDB_ID.NULL Then
         Dim CurrPart As BTLPartVM = Map.refProjectVM.BTLStructureVM.BTLPartVMList.FirstOrDefault(Function(x) x.nPartId = m_nIdToSel)
         If e.Button = Forms.MouseButtons.Left Then
            ' imposto highlight
            Map.refProjectVM.BTLStructureVM.SetSelectionType(BTLStructureVM.SelectionTypes.HIGHLIGHT)
            ' gestisco evidenziazione pezzo
            If (Keyboard.Modifiers And ModifierKeys.Shift) = ModifierKeys.Shift OrElse (Keyboard.Modifiers And ModifierKeys.Control) = ModifierKeys.Control Then
               If IsNothing(CurrPart) Then Return
               If Map.refProjectVM.BTLStructureVM.SelBTLParts.Contains(CurrPart) Then
                  Map.refProjectVM.BTLStructureVM.SelBTLParts.Remove(CurrPart)
               Else
                  Map.refProjectVM.BTLStructureVM.SelBTLParts.Add(CurrPart)
               End If
            Else
               If Map.refProjectVM.BTLStructureVM.SelBTLParts.Count > 0 Then
                  If Map.refProjectVM.BTLStructureVM.SelBTLParts.Contains(CurrPart) Then
                     For RemoveIndex = Map.refProjectVM.BTLStructureVM.SelBTLParts.Count - 1 To 0 Step -1
                        If Map.refProjectVM.BTLStructureVM.SelBTLParts(RemoveIndex) IsNot CurrPart Then
                           Map.refProjectVM.BTLStructureVM.SelBTLParts.Remove(Map.refProjectVM.BTLStructureVM.SelBTLParts(RemoveIndex))
                        End If
                     Next
                     'While Map.refProjectVM.BTLStructureVM.SelBTLParts.Count > 1
                     '   If Map.
                     'End While
                  Else
                     Map.refProjectVM.BTLStructureVM.SelBTLParts.Clear()
                     Map.refProjectVM.BTLStructureVM.SelBTLParts.Add(CurrPart)
                  End If
               Else
                  Map.refProjectVM.BTLStructureVM.SelBTLParts.Add(CurrPart)
               End If
            End If
         ElseIf e.Button = Forms.MouseButtons.Right Then
            ' imposto selezione
            Map.refProjectVM.BTLStructureVM.SetSelectionType(BTLStructureVM.SelectionTypes.SELECT_)
            ' seleziono il pezzo
            If Map.refProjectVM.BTLStructureVM.SelBTLParts.Count > 0 Then
               Map.refProjectVM.BTLStructureVM.SelBTLParts.Clear()
            End If
            Map.refProjectVM.BTLStructureVM.SelBTLParts.Add(CurrPart)
         End If


         '   ' Se pezzo da selezionare non è già selezionato
         '   If IsNothing(Map.refProjectVM.BTLStructureVM.SelBTLPart) OrElse
         '      Map.refProjectVM.BTLStructureVM.SelBTLPartsCnt = 0 OrElse
         '      Map.refProjectVM.BTLStructureVM.SelBTLPart.nPartId <> m_nIdToSel Then
         '      ' Eseguo la selezione
         '      For Each BTLPart In Map.refProjectVM.BTLStructureVM.BTLPartVMList
         '         If BTLPart.nPartId = m_nIdToSel Then
         '            BTLPart.SetIsSelected(True)
         '         ElseIf BTLPart.IsSelected Then
         '            BTLPart.SetIsSelected(False)
         '         End If
         '      Next
         '   End If
      End If
      ' Reset
      m_bDrag = False
      m_nIdToSel = GDB_ID.NULL
      m_nIdToDesel = GDB_ID.NULL
      EgtDraw()
   End Sub

#End Region       ' Part

#Region "Feature"

   Friend Sub View_Feature_OnMouseDownScene(sender As Object, e As Forms.MouseEventArgs)
      ' Verifico se selezionato indicativo di pezzo
      EgtSetObjFilterForSelWin(True, True, True, True, True)
      Dim nSel As Integer
      EgtSelect(e.Location, Scene.DIM_SEL, Scene.DIM_SEL, nSel)
      Dim nId As Integer = EgtGetFirstObjInSelWin()
      While nId <> GDB_ID.NULL
         ' Verifico se e' una feature
         Dim nFeatureLayer As Integer = EgtGetParent(nId)
         Dim sFeatureLayerName As String = ""
         EgtGetName(nFeatureLayer, sFeatureLayerName)
         If (sFeatureLayerName <> PROCESSINGS AndAlso sFeatureLayerName <> OUTLINE) OrElse EgtGetType(nId) <> GDB_TY.SRF_MESH Then
            nId = EgtGetNextObjInSelWin()
            Continue While
         End If
         Dim nStat As Integer = GDB_ST.ON_
         EgtGetStatus(nId, nStat)
         ' Se già selezionato
         If nStat = GDB_ST.SEL Then
            ' Memorizzo Id da deselezionare
            m_nIdToDesel = nId
         Else
            ' Memorizzo Id da selezionare
            m_nIdToSel = nId
         End If
         Exit While
         nId = EgtGetNextObjInSelWin()
      End While
      ' Dati per drag
      m_bDragToStart = True
   End Sub

   Friend Sub View_Feature_OnMouseMoveScene(sender As Object, e As System.Windows.Forms.MouseEventArgs)
      ' Se drag non abilitato o già in esecuzione, esco
      If Not m_bDragToStart Then Return
      ' Se primo movimento di drag, verifico di aver superato la soglia di movimento in pixel
      If m_bDragToStart Then
         If Math.Abs(e.Location.X - m_locPrev.X) < m_nRestRadius And
            Math.Abs(e.Location.Y - m_locPrev.Y) < m_nRestRadius Then
            Return
         End If
         m_bDragToStart = False
      End If
   End Sub

   Friend Sub View_Feature_OnMouseUpScene(sender As Object, e As System.Windows.Forms.MouseEventArgs)
      ' Se eseguito drag
      If Not m_bDragToStart Then
         ' Se selezione da eseguire
      ElseIf m_nIdToSel <> GDB_ID.NULL Then
         ' Se feature da selezionare non è già selezionata
         If Not IsNothing(Map.refProjectVM.BTLStructureVM.SelBTLPart) AndAlso
            (IsNothing(Map.refProjectVM.BTLStructureVM.SelBTLPart.SelBTLFeatureVM) OrElse Map.refProjectVM.BTLStructureVM.SelBTLPart.SelBTLFeatureVM.nFeatureId <> m_nIdToSel) Then
            ' Eseguo la selezione
            Map.refProjectVM.BTLStructureVM.SelBTLPart.SelBTLFeatureVM = Map.refProjectVM.BTLStructureVM.SelBTLPart.BTLFeatureVMList.FirstOrDefault(Function(x) x.nFeatureId = m_nIdToSel)
         End If
      End If
      ' Reset
      m_bDrag = False
      m_nIdToSel = GDB_ID.NULL
      m_nIdToDesel = GDB_ID.NULL
      EgtDraw()
   End Sub

#End Region    ' Feature

#End Region    ' VIEW EVENTS

End Class
