Imports System.Runtime.InteropServices
Imports EgtUILib
Imports EgtWPFLib

Public Class SimulationPageUC
   ' Riferimenti a pagine
   Private m_MainWindow As MainWindow = DirectCast(Application.Current.MainWindow, MainWindow)
   Private m_CurrProjPage As CurrentProjectPageUC

   ' Funzioni di callback per output in interfaccia da LUA
   Private m_ProcEventsCallback As New ProcessEventsCallback(AddressOf ProcessEvents)
   Private m_OutTextCallback As New OutTextCallback(AddressOf ProcessOutText)

   ' Stato di visualizzazione della macchina
   Private m_nMachLook As Integer = MCH_LOOK.ALL
   ' Stato ripartenza
   Private m_nRestart As Integer = 0
   ' Utensile corrente
   Private m_sCurrTool As String = String.Empty
   ' Stato di comando corrente
   Private m_nStatus As MCH_SIM_ST = MCH_SIM_ST.UI_STOP
   ' Stato bottone Play
   Private m_bPlay As Boolean = True
   ' Coefficiente per valore Slider
   Private m_SliderX As Double = 1
   ' Flag di esecuzione in corso
   Private m_bSimExecuting As Boolean = False
   Friend Function GetSimExecuting() As Boolean
      Return m_bSimExecuting
   End Function
   ' Numero di assi in simulazione
   Private m_SimulationAxesNum As Integer = 5
   ' Flag di abilitazione della stima
   Private m_bEstim As Boolean = False

   Friend Sub ResetSimulation()
      ' Termino la simulazione
      SetStatus(MCH_SIM_ST.UI_STOP)
      EgtSimExit()
      ' Salvo valore dello slider
      Dim sVal As String = DoubleToString(SpeedSlider.Value, 1)
      WritePrivateProfileString(S_SIMUL, K_SLIDERVAL, sVal, m_MainWindow.GetIniFile())
      ' Torno alla prima fase
      EgtSetCurrPhase(1, True)
      ' Ripristino visibilità standard
      EgtSetMachineLook(MCH_LOOK.TAB)
      ' Visualizzo eventuali testi con dati su aree
      m_CurrProjPage.SetAreasStatus( True)
   End Sub

   Private Sub SimulationPage_Initialized(sender As Object, e As EventArgs)
      ' Impostazioni box stime
      m_bEstim = (GetPrivateProfileInt(S_MACH_ESTIMATIONS, K_ENABLEEST, 0, m_MainWindow.GetMachIniFile()) <> 0)
      If Not m_bEstim Then EstimGrid.Visibility = Windows.Visibility.Hidden
      TimeTxBl.Text = EgtMsg(MSG_SIMULATIONPAGEUC + 15)        ' Tempo
      CutLenTxBl.Text = EgtMsg(MSG_SIMULATIONPAGEUC + 16)      ' Lunghezza
      NetAreaTxBl.Text = EgtMsg(MSG_SIMULATIONPAGEUC + 17)     ' Area pezzi
      UsageTxBl.Text = EgtMsg(MSG_SIMULATIONPAGEUC + 18)       ' Utilizzo
      ' Impostazioni box assi
      m_SimulationAxesNum = GetPrivateProfileInt(S_AXES, K_SIMULATIONAXESNUM, 5, m_MainWindow.GetMachIniFile())
      For Index As Integer = 0 To AxesUniformGrid.Children.Count - 1
         If Index > m_SimulationAxesNum - 1 And Index < AxesUniformGrid.Children.Count - 2 Then
            If TypeOf AxesUniformGrid.Children(Index) Is Grid Then
               Dim AxisGrid As Grid = DirectCast(AxesUniformGrid.Children(Index), Grid)
               AxisGrid.Visibility = Windows.Visibility.Collapsed
            End If
         End If
      Next
      If m_SimulationAxesNum <= 5 Then
         AxesUniformGrid.Rows = 7
         AxesBoder.SetValue(Grid.RowSpanProperty, 2)
         AxesBoder.SetValue(Grid.RowProperty, 2)
         StepBtn.SetValue(Grid.RowProperty, 4)
         PlayPauseBtn.SetValue(Grid.RowProperty, 4)
         StopBtn.SetValue(Grid.RowProperty, 4)
         SpeedSlider.SetValue(Grid.RowProperty, 5)
      End If
      ' Pulsante Play
      PlayPauseImage.Source = New System.Windows.Media.Imaging.BitmapImage(New Uri("/Resources/Play.png", UriKind.Relative))
      ' abilito la visualizzazione del pulsante per la sola generazione del codice CN
      If GetPrivateProfileInt(S_GENERAL, K_GENERATECN, 0, m_MainWindow.GetIniFile()) <> 0 Then
         GenerateCN_Btn.Visibility = Visibility.Visible
      Else
         GenerateCN_Btn.Visibility = Visibility.Hidden
      End If
   End Sub

   Private Sub SimulationPage_Loaded(sender As Object, e As RoutedEventArgs)
      m_CurrProjPage = m_MainWindow.m_CurrentProjectPageUC
      Dim bOk As Boolean = True
      ' Elimino eventuale attrezzaggio da OmagOFFICE
      EgtEraseCurrSetup()
      ' Verifico l'attrezzaggio degli utensili utilizzati
      Dim sMissingTools As String = String.Empty
      Dim bSetup As Boolean = VerifySetup(sMissingTools)
      ' Costringo ad aggiornare UI
      UpdateUI()
      ' Aggiorno flag per lavaggio
      m_CurrProjPage.UpdateWashingFlag()
      ' Aggiorno flag per tastatura per tagli con angolo di fianco
      m_CurrProjPage.UpdateSideAngCutProbeFlag()
      ' Se pezzi piani e non taglio diretto e non c'è ordine delle lavorazioni, ricalcolo tutto e ne faccio uno automatico
      Dim nPrjType As Integer = m_CurrProjPage.GetCurrentProjectType()
      Dim bDirectCut As Boolean = (GetDirectCutPart() <> GDB_ID.NULL)
      If nPrjType = CurrentProjectPageUC.PRJ_TYPE.FLATS And
         Not bDirectCut And
         Not m_CurrProjPage.GetOrderMachiningFlag() Then
         ResetAllMachinings()
         bOk = SortAllMachinings()
         If bOk Then m_CurrProjPage.SetOrderMachiningFlag()
         Dim bModif As Boolean = TestAllMachiningsForStrict()
         If bModif Then
             m_CurrProjPage.SetWarningMessage(EgtMsg(90321))   'Ridotte alcune lavorazioni per evitare interferenze
         Else
             m_CurrProjPage.SetInfoMessage(EgtMsg(90399))      'Aggiornate tutte le lavorazioni
         End If
      End If
      ' Costringo ad aggiornare UI
      UpdateUI()
      ' Disabilito impostazione modificato
      EgtDisableModified()
      ' Aggiorno le lavorazioni
      bOk = UpdateAllMachiningsToolpaths() And bOk
      ' Eventuale eliminazione Home finale
      If bDirectCut And Not m_MainWindow.m_CurrentMachine.bDirectCutsFinalHome Then
         RemoveFinalHome()
      End If
      ' Aggiorno posizionamento ventose sui pezzi per eventuali tagli da sotto con lama
      bOk = UpdateVacuumsForDrip() And bOk
      ' Se errore in setup, lo segnalo
      If Not bSetup Then
         m_CurrProjPage.SetErrorMessage(EgtMsg(90322) & " " & sMissingTools)  'Mancano gli utensili : ... 
      ' Se errore in generazione, segnalo l'errore
      ElseIf Not bOk Then
         m_CurrProjPage.SetErrorMessage(EgtMsg(90314))       'Errore nella generazione del programma CN
      End If
      ' Costringo ad aggiornare UI
      UpdateUI()
      ' Se abilitate, eseguo la stima di tempi, lunghezze ...
      If m_bEstim Then
         EgtSetCurrPhase(1)
         EgtEstimate(m_MainWindow.GetTempDir() & "\MachProj.html", "OmagCut ver." & m_MainWindow.GetVersion())
         ' Visualizzo i risultati
         Dim nTotalTime As Integer = 0
         EgtGetInfo(EgtGetCurrMachGroup(), "Ttot", nTotalTime)
         Dim tsTotalTime As New TimeSpan(0, 0, nTotalTime)
         TimeTxBx.Text = tsTotalTime.ToString("hh\:mm\:ss")
         Dim dTotalLength As Double = 0
         EgtGetInfo(EgtGetCurrMachGroup(), "Ltot", dTotalLength)
         If EgtUiUnitsAreMM() Then
            CutLenTxBx.Text = DoubleToString(dTotalLength / 1000, 1) & " m"
         Else
            CutLenTxBx.Text = DoubleToString(dTotalLength / (ONEINCH * 12), 1) & " ft"
         End If
         Dim dNetArea As Double = 0
         EgtGetInfo(EgtGetCurrMachGroup(), "NetArea", dNetArea)
         If EgtUiUnitsAreMM() Then
            NetAreaTxBx.Text = DoubleToString(dNetArea / 1000000, 2) & " m²"
         Else
            NetAreaTxBx.Text = DoubleToString(dNetArea / (ONEINCH * 12 * ONEINCH * 12), 1) & " ft²"
         End If
         Dim dRawArea As Double = 0
         EgtGetInfo(EgtGetCurrMachGroup(), "RawArea", dRawArea)
         Dim dUsage As Double = If(dRawArea > EPS_SMALL, dNetArea / dRawArea, 1)
         UsageTxBx.Text = DoubleToString(dUsage * 100, 1) & " %"
      End If
      ' Salvo il progetto con le lavorazioni
      Dim sMchPath As String = m_MainWindow.GetTempDir() & "\MachProj.nge"
      m_CurrProjPage.SaveFile(sMchPath, False)
      ' Nascondo eventuale contorno da foto
      m_CurrProjPage.ShowContour(False)
      ' Nascondo eventuali testi con dati su aree
      m_CurrProjPage.SetAreasStatus( false)
      ' Recupero eventuale fase di ripartenza
      m_nRestart = m_MainWindow.m_CurrentProjectPageUC.GetProjectNcRestart()
      ' Imposto prima fase
      EgtSetCurrPhase(1)
      ShowAllCurrPhaseMachinings()
      ' Costringo ad aggiornare UI
      UpdateUI()
      ' Visualizzo opportunamente la macchina
      m_nMachLook = MCH_LOOK.ALL
      EgtSetMachineLook(m_nMachLook)
      ' Imposto vista 3d isometrica di tutto
      EgtSetView(VT.ISO_SE, False)
      EgtZoom(ZM.ALL)
      ' Registro funzione su aggiornamento interfaccia da sotto
      EgtSetProcessEvents(m_ProcEventsCallback)
      EgtSetOutText(m_OutTextCallback)
      ' Avvio ambiente di simulazione
      EgtSimInit()
      EgtSimStart()
      ' Imposto stato corrente
      SetStatus(MCH_SIM_ST.UI_STOP)
      m_bPlay = True
      m_SliderX = GetPrivateProfileDouble(S_SIMUL, K_SLIDERX, 1, m_MainWindow.GetIniFile())
      Dim SliderVal As Double = GetPrivateProfileDouble(S_SIMUL, K_SLIDERVAL, 10, m_MainWindow.GetIniFile())
      SpeedSlider.Value = SliderVal
      EgtSimSetStep(SpeedSlider.Value * m_SliderX)
      ' Carico utensili specializzato
      LoadCurrTools()
      EgtDraw()
      ShowCncData()
      If (m_MainWindow.m_OptionsPageUC.ThemesCmBx.SelectedIndex = 0) Then
         PlayPauseImage.Source = New System.Windows.Media.Imaging.BitmapImage(New Uri("/Resources/Play.png", UriKind.Relative))
      Else
         PlayPauseImage.Source = New System.Windows.Media.Imaging.BitmapImage(New Uri("/Resources/NewIcons/Play.png", UriKind.Relative))
      End If
   End Sub

   Private Sub StepBtn_Click(sender As Object, e As RoutedEventArgs) Handles StepBtn.Click
      m_CurrProjPage.ClearMessage()
      ' Se stato stop, devo avviare simulazione
      If m_nStatus = MCH_SIM_ST.UI_STOP Then
         SetStatus(MCH_SIM_ST.UI_STEP)
         ExecSim()
         ' Aggiorno bottone
         SetPlayPauseBtnToPlay()
      ' Alrimenti imposto solo il nuovo stato
      Else
         SetStatus(MCH_SIM_ST.UI_STEP)
         ' Aggiornamenti per bottone Play/Pause
         SetPlayPauseBtnToPause()
      End If
   End Sub

   Private Sub PlayPauseBtn_Click(sender As Object, e As RoutedEventArgs) Handles PlayPauseBtn.Click
      m_CurrProjPage.ClearMessage()
      If m_bPlay Then
         ' Aggiorno bottone
         SetPlayPauseBtnToPause()
         ' Eseguo
         If m_nStatus = MCH_SIM_ST.UI_STOP Then
            ' Lancio simulazione
            SetStatus(MCH_SIM_ST.UI_PLAY)
            ExecSim()
            ' Aggiorno bottone
            SetPlayPauseBtnToPlay()
         ElseIf m_nStatus = MCH_SIM_ST.UI_PAUSE Then
            SetStatus(MCH_SIM_ST.UI_PLAY)
         End If
      Else
         ' Aggiorno bottone
         SetPlayPauseBtnToPlay()
         ' Se play o step, imposto stato pausa
         If m_nStatus = MCH_SIM_ST.UI_PLAY Or m_nStatus = MCH_SIM_ST.UI_STEP Then
            SetStatus(MCH_SIM_ST.UI_PAUSE)
         End If
      End If
   End Sub

   Private Sub SetPlayPauseBtnToPlay()
      m_bPlay = True
      If (m_MainWindow.m_OptionsPageUC.ThemesCmBx.SelectedIndex = 0) Then
         PlayPauseImage.Source = New System.Windows.Media.Imaging.BitmapImage(New Uri("/Resources/Play.png", UriKind.Relative))
      Else
         PlayPauseImage.Source = New System.Windows.Media.Imaging.BitmapImage(New Uri("/Resources/NewIcons/Play.png", UriKind.Relative))
      End If
      'PlayPauseImage.Source = New System.Windows.Media.Imaging.BitmapImage(New Uri("/Resources/Play.png", UriKind.Relative))
   End Sub

   Private Sub SetPlayPauseBtnToPause()
      m_bPlay = False
      If (m_MainWindow.m_OptionsPageUC.ThemesCmBx.SelectedIndex = 0) Then
         PlayPauseImage.Source = New System.Windows.Media.Imaging.BitmapImage(New Uri("/Resources/Pause.png", UriKind.Relative))
      Else
         PlayPauseImage.Source = New System.Windows.Media.Imaging.BitmapImage(New Uri("/Resources/NewIcons/Pause.png", UriKind.Relative))
      End If
      'PlayPauseImage.Source = New System.Windows.Media.Imaging.BitmapImage(New Uri("/Resources/Pause.png", UriKind.Relative))
   End Sub

   Private Sub StopBtn_Click(sender As Object, e As RoutedEventArgs) Handles StopBtn.Click
      m_CurrProjPage.ClearMessage()
      ' Se stato già stop, porto in home
      If m_nStatus = MCH_SIM_ST.UI_STOP Then
         ' Vado in home
         EgtSimHome()
         ' Imposto prima fase
         EgtSetCurrPhase(1, True)
         ' Aggiorno visualizzazione
         EgtDraw()
         ' Aggiorno dati CNC
         ShowCncData()
      End If
      ' Imposto il nuovo stato
      SetStatus(MCH_SIM_ST.UI_STOP)
   End Sub

   Private Sub SetStatus(nStatus As MCH_SIM_ST)
      m_nStatus = nStatus
      EgtSimSetUiStatus(m_nStatus)
   End Sub

   Private Sub SpeedSlider_ValueChanged(sender As Object, e As RoutedPropertyChangedEventArgs(Of Double))
      If e.OldValue <> 0 Then
         EgtSimSetStep(SpeedSlider.Value * m_SliderX)
      End If
   End Sub

   Private Sub SkipForRestart()
      ' Se non c'è restart esco
      If m_nRestart = 0 Then Return
      ' Se tagli diretti restart non valido ed esco
      If GetDirectCutPart() <> GDB_ID.NULL Then Return
      ' Info
      m_CurrProjPage.SetInfoMessage( EgtMsg(90359) & " (" & m_nRestart.ToString() & ")")        'Restart (n)
      ' Salto
      While m_nStatus <> MCH_SIM_ST.UI_STOP
         ' Eseguo movimento
         Dim nMove As Integer
         Dim bMove As Boolean = EgtSimMove(nMove)
         If Not bMove Then Exit While
         ' Aggiorno visualizzazione e dati CNC (saltando le parti già fatte se in restart)
         Dim nPhase As Integer = EgtGetCurrPhase()
         Dim sOpeName As String = ""
         Dim nOpeType As Integer = 0
         EgtSimGetOperationInfo( sOpeName, nOpeType)
         If ( nPhase = m_nRestart And nOpeType <> MCH_OY.DISP) Or nPhase > m_nRestart Then
            Exit While 
         End If
      End While
      ' Aggiorno visualizzazione
      EgtDraw()
      ShowCncData()
      ' Info
      m_CurrProjPage.SetInfoMessage( EgtMsg(90359) & " (" & m_nRestart.ToString() & ")")        'Restart (n)
      ' Aspetto nuova partenza
      m_nStatus = MCH_SIM_ST.UI_PAUSE
      SetPlayPauseBtnToPlay()
   End Sub

   Private Sub ExecSim()
      m_bSimExecuting = True
      EgtSimStart( False)
      LoadCurrTools()
      SkipForRestart()
      EgtSimSetStep(SpeedSlider.Value * m_SliderX)
      While m_nStatus <> MCH_SIM_ST.UI_STOP
         ' Se simulazione in svolgimento
         If m_nStatus = MCH_SIM_ST.UI_PLAY Or m_nStatus = MCH_SIM_ST.UI_STEP Then
            ' Eseguo movimento
            Dim nMove As Integer
            Dim bMove As Boolean = EgtSimMove(nMove)
            ' Se arrivato a fine step e sono in step
            If bMove Then
               If m_nStatus = MCH_SIM_ST.UI_STEP And nMove = MCH_SIM.END_STEP Then
                  ' Imposto stato Pausa
                  SetStatus(MCH_SIM_ST.UI_PAUSE)
                  ' Aggiornamenti per bottone Play/Pause
                  SetPlayPauseBtnToPlay()
               End If
            ' Se movimento non riuscito
            Else
               SetStatus(MCH_SIM_ST.UI_STOP)
               ' Aggiornamenti per bottone Play/Pause
               SetPlayPauseBtnToPlay()
               Select Case nMove
               Case MCH_SIM.END_
                  m_CurrProjPage.SetInfoMessage(EgtMsg(MSG_SIMULATIONPAGEUC + 1))         'Simulazione completata
               Case MCH_SIM.STOP_
                  ' Simulazione fermata dall'utente (non necessita messaggio)
               Case MCH_SIM.OUTSTROKE
                  Dim sInfo As String = String.Empty
                  EgtGetOutstrokeInfo(sInfo)
                  m_CurrProjPage.SetErrorMessage(EgtMsg(MSG_SIMULATIONPAGEUC + 2) & " " & sInfo)        'Extracorsa ...
               Case MCH_SIM.DIR_ERR
                  m_CurrProjPage.SetErrorMessage(EgtMsg(MSG_SIMULATIONPAGEUC + 3))        'Direzione utensile irraggiungibile
               Case Else
                  If EgtGetLastMachMgrErrorId() <> 0 Then
                     Dim sErr As String = EgtGetLastMachMgrErrorString()
                     m_CurrProjPage.SetErrorMessage(sErr)
                  Else
                     m_CurrProjPage.SetErrorMessage(EgtMsg(MSG_SIMULATIONPAGEUC + 4))        'Errore
                  End If
               End Select
            End If
            ' Aggiorno stato visualizzazione macchina (dipende anche da utensile)
            UpdateMachView()
            ' Aggiorno visualizzazione
            EgtDraw()
            ' Aggiorno dati CNC
            ShowCncData()
         Else
            ' Per evitare di ciclare rapidissimamente e consumare inutilmente CPU
            System.Threading.Thread.Sleep(1)
         End If
         ' Costringo ad aggiornare UI
         UpdateUI()
      End While
      m_bSimExecuting = False
   End Sub

   Private Sub ShowCncData()
      ' Assi
      Dim nInd As Integer = 0
      ShowAxisNameVal(nInd, A1Name.Text, A1Value.Text)
      ShowAxisNameVal(nInd, A2Name.Text, A2Value.Text)
      ShowAxisNameVal(nInd, A3Name.Text, A3Value.Text)
      ShowAxisNameVal(nInd, A4Name.Text, A4Value.Text)
      ShowAxisNameVal(nInd, A5Name.Text, A5Value.Text)
      If m_SimulationAxesNum >= 6 Then
         ShowAxisNameVal(nInd, A6Name.Text, A6Value.Text)
      End If
      If m_SimulationAxesNum >= 7 Then
         ShowAxisNameVal(nInd, A7Name.Text, A7Value.Text)
      End If
      If m_SimulationAxesNum >= 8 Then
         ShowAxisNameVal(nInd, A8Name.Text, A8Value.Text)
      End If
      If m_SimulationAxesNum >= 9 Then
         ShowAxisNameVal(nInd, A9Name.Text, A9Value.Text)
      End If
      If m_SimulationAxesNum = 10 Then
         ShowAxisNameVal(nInd, A10Name.Text, A10Value.Text)
      End If
      ' Tipo di movimento e feed
      ShowMoveTypeFeed()
      ' Nome utensile e speed
      ShowToolNameSpeed()
   End Sub

   Private Function ShowAxisNameVal(ByRef nInd As Integer, ByRef sToken As String, ByRef sVal As String) As Boolean
      Dim sName As String = String.Empty
      Dim sInfo As String = String.Empty
      Dim bLinear As Boolean = True
      Dim dVal As Double = 0
      If EgtSimGetAxisInfoPos(nInd, sName, sInfo, bLinear, dVal) Then
         If sInfo <> "**" Then
            sToken = sInfo
            sVal = If(bLinear, LenToString(dVal, -3), DoubleToString(dVal, -3))
            nInd += 1
            Return True
         Else
            nInd += 1
            Return ShowAxisNameVal(nInd, sToken, sVal)
         End If
      Else
         sToken = String.Empty
         sVal = String.Empty
         nInd += 1
         Return False
      End If
   End Function

   Private Function ShowMoveTypeFeed() As Boolean
      Dim nG As Integer = 0
      Dim dFeed As Double = 0
      If EgtSimGetMoveInfo(nG, dFeed) Then
         If nG <> 0 Then
            GCodeTxBl.Text = "G" & nG.ToString()
            FValueTxBl.Text = "F" & LenToString(dFeed, 0)
         Else
            GCodeTxBl.Text = "G" & nG.ToString()
            FValueTxBl.Text = ""
         End If
         Return True
      Else
         GCodeTxBl.Text = ""
         FValueTxBl.Text = ""
         Return False
      End If
   End Function

   Private Function ShowToolNameSpeed() As Boolean
      Dim sTool As String = String.Empty
      Dim dSpeed As Double = 0
      If EgtSimGetToolInfo(sTool, dSpeed) Then
         TNameTxBl.Text = sTool
         SValueTxBl.Text = "S" & DoubleToString(dSpeed, 0)
         Return True
      Else
         TNameTxBl.Text = ""
         SValueTxBl.Text = ""
         Return False
      End If
   End Function

   Private Function LoadCurrTools() As Boolean
      ' Se macchina senza cambio utensile automatico devo caricare gli utensili
      If m_MainWindow.m_CurrentMachine.MountedToolConfig <> CurrentMachine.MountedToolConfigs.TOOLCHANGER Then
         ' Imposto la lama corrente
         Dim sSaw As String = m_MainWindow.m_CurrentMachine.sCurrSaw
         If Not EgtLoadTool("H1", 1, sSaw) Then Return False
         ' Imposto eventuale secondo utensile montato
         If m_MainWindow.m_CurrentMachine.MountedToolConfig = CurrentMachine.MountedToolConfigs.SAWANDAUXTOOL Then
            Dim sTool As String = m_MainWindow.m_CurrentMachine.sCurrDrill
            If String.IsNullOrEmpty(sTool) Then sTool = m_MainWindow.m_CurrentMachine.sCurrMill
            If Not String.IsNullOrEmpty(sTool) AndAlso Not EgtLoadTool("H1", 2, sTool) Then Return False
         End If
         ' Per MultiCut con TC manuale, impostazione eventuale secondo utensile montato su prima testa
         If EgtGetHeadId("H101") <> GDB_ID.NULL And
            m_MainWindow.m_CurrentMachine.MountedToolConfig = CurrentMachine.MountedToolConfigs.MANUALTOOLCHANGER And
            m_MainWindow.m_CurrentMachine.ManualToolChangerNbr > 0 Then
            Dim sTool As String = m_MainWindow.m_CurrentMachine.ManualToolChanger(0).sTool
            If Not String.IsNullOrEmpty(sTool) AndAlso Not EgtLoadTool("H1", 2, sTool) Then Return False
         End If
      End If
      ' Imposto eventuale lama per taglio da sotto
      Dim sDripSaw As String = m_MainWindow.m_CurrentMachine.sCurrDripSaw
      If Not String.IsNullOrEmpty(sDripSaw) Then
         EgtLoadTool("H105", 1, sDripSaw)
      End If
      ' Imposto eventuale foretto per foro da sotto
      Dim sDripDrill As String = m_MainWindow.m_CurrentMachine.sCurrDripDrill
      If Not String.IsNullOrEmpty(sDripDrill) Then
         EgtLoadTool("H106", 1, sDripDrill)
      End If
      Return True
   End Function

   Private Sub MachViewModeBtn_Click(sender As Object, e As RoutedEventArgs) Handles MachViewModeBtn.Click
      ' aggiorno lo stato
      Select Case m_nMachLook
      Case MCH_LOOK.ALL
         m_nMachLook = MCH_LOOK.TAB_HEAD
      Case MCH_LOOK.TAB_HEAD
         m_nMachLook = MCH_LOOK.TAB_TOOL
      Case Else
         m_nMachLook = MCH_LOOK.ALL
      End Select
      ' aggiorno lo stato della macchina e la sua visualizzazione
      EgtSetMachineLook(m_nMachLook)
      EgtDraw()
   End Sub

   Private Sub UpdateMachView()
      ' Se cambiato utensile, aggiorno stato visualizzazione macchina
      Dim sTool As String = String.Empty
      Dim dSpeed As Double = 0
      If EgtSimGetToolInfo(sTool, dSpeed) Then
         If sTool <> m_sCurrTool Then
            m_sCurrTool = sTool
            EgtSetMachineLook(m_nMachLook)
         End If
      End If
   End Sub

   Private Sub ExitBtnUC_Click(sender As Object, e As RoutedEventArgs)
      ' Mi assicuro di terminare la simulazione
      ResetSimulation()
      ' Nascondo tutte le lavorazioni
      HideAllMachinings()
      ' Cancello eventuali messaggi
      m_CurrProjPage.ClearMessage()
      ' Imposto vista 2D
      EgtSetView(VT.TOP, False)
      EgtZoom(ZM.ALL)
      ' Abilito impostazione modificato
      EgtEnableModified()
      ' Reset funzione callback su evento aggiornamento interfaccia da sotto
      EgtSetProcessEvents(Nothing)
      EgtSetOutText(Nothing)
      ' Esco dalla pagina
      m_MainWindow.m_CurrentProjectPageUC.CurrentProjectPageGrid.Children.Remove(Me)
      m_CurrProjPage.CurrProjGrid.Visibility = Windows.Visibility.Visible
      If m_MainWindow.m_PrevActivePage = MainWindow.Pages.CadCut Then
         m_MainWindow.m_CurrentProjectPageUC.CurrentProjectPageGrid.Children.Add(m_MainWindow.m_CadCutPageUC)
         m_MainWindow.m_ActivePage = MainWindow.Pages.CadCut
      ElseIf m_MainWindow.m_PrevActivePage = MainWindow.Pages.FrameCut Then
         m_MainWindow.m_CurrentProjectPageUC.CurrentProjectPageGrid.Children.Add(m_MainWindow.m_FrameCutPageUC)
         m_MainWindow.m_ActivePage = MainWindow.Pages.FrameCut
      Else
         m_MainWindow.m_CurrentProjectPageUC.CurrentProjectPageGrid.Children.Add(m_MainWindow.m_DirectCutPageUC)
         m_MainWindow.m_ActivePage = MainWindow.Pages.DirectCut
      End If

   End Sub

   Private Sub GenerateXPIUC_Click(sender As Object, e As RoutedEventArgs)
      Dim bOk As Boolean = True
      EgtSetCurrentContext(m_CurrProjPage.CurrentProjectScene.GetCtx())
      ' Elimino eventuale attrezzaggio da OmagOFFICE
      EgtEraseCurrSetup()
      ' Verifico l'attrezzaggio degli utensili utilizzati
      Dim sMissingTools As String = String.Empty
      If Not VerifySetup(sMissingTools) Then
         m_CurrProjPage.SetErrorMessage(EgtMsg(90322) & " " & sMissingTools)  'Mancano gli utensili : ... 
         Return
      End If
      ' Costringo ad aggiornare UI
      UpdateUI()
      ' Aggiorno flag per lavaggio
      m_CurrProjPage.UpdateWashingFlag()
      ' Aggiorno flag per tastatura per tagli con angolo di fianco
      m_CurrProjPage.UpdateSideAngCutProbeFlag()
      ' Se pezzi piani e non c'è ordine delle lavorazioni, ricalcolo tutto e ne faccio uno automatico
      Dim nPrjType As Integer = m_CurrProjPage.GetCurrentProjectType()
      Dim bDirectCut As Boolean = (GetDirectCutPart() <> GDB_ID.NULL)
      If nPrjType = CurrentProjectPageUC.PRJ_TYPE.FLATS And
         Not bDirectCut And
         Not m_CurrProjPage.GetOrderMachiningFlag() Then
         ResetAllMachinings()
         bOk = SortAllMachinings()
         If bOk Then
            m_CurrProjPage.SetOrderMachiningFlag()
            Dim bModif As Boolean = TestAllMachiningsForStrict()
            If bModif Then
               m_CurrProjPage.SetWarningMessage(EgtMsg(90321))     'Ridotte alcune lavorazioni per evitare interferenze
            Else
               m_CurrProjPage.SetInfoMessage(EgtMsg(90399))        'Aggiornate tutte le lavorazioni
            End If
            EgtDraw()
         End If
      End If
      ' Costringo ad aggiornare UI
      UpdateUI()
      ' Disabilito impostazione modificato
      EgtDisableModified()
      ' Aggiorno le lavorazioni
      bOk = UpdateAllMachiningsToolpaths() And bOk
      ' Aggiorno posizionamento ventose sui pezzi per eventuali tagli da sotto con lama
      bOk = UpdateVacuumsForDrip() And bOk
      ' Costringo ad aggiornare UI
      UpdateUI()
      ' Inserisco indice di progetto
      m_CurrProjPage.SetProjectIndexFlag()
      ' Inserisco il materiale
      m_CurrProjPage.SetProjectMaterial()
      ' Salvo il progetto con le lavorazioni
      Dim sMchPath As String = m_MainWindow.GetTempDir() & "\MachProj.nge"
      m_CurrProjPage.SaveFile(sMchPath)
      ' Costringo ad aggiornare UI
      UpdateUI()
      ' Se modalità Ufficio, copio il progetto ed esco
      If m_MainWindow.GetKeyOption(MainWindow.KEY_OPT.OFFICE_TYPE) Then
         ' Ripristino come fase corrente quella iniziale
         EgtSetCurrPhase(1)
         ' Chiedo il nome del file esportato
         Dim MySaveNameWD As New SaveNameWD(m_MainWindow, SaveNameWD.SAVE_TYPE.PRJ_COPY)
         MySaveNameWD.ShowDialog()
         Return
      End If
      ' Se presente ripartenza, ne chiedo conferma
      Dim nPhaseRestart As Integer = m_CurrProjPage.GetProjectNcRestart()
      If nPhaseRestart <> 0 Then
         ' Confermi ripartenza dalla fase NNN ?
         Dim AskNcRestart As New EgtMsgBox(m_MainWindow, "", String.Format(EgtMsg(90326), nPhaseRestart),
                                        EgtMsgBox.Buttons.YES_NO_CANCEL, EgtMsgBox.Icons.NULL, 2)
         Select Case AskNcRestart.m_nPressedBtn
            Case 1         ' YES
            Case 2         ' NO
               EgtEnableModified()
               m_CurrProjPage.ResetProjectNcRestart()
               nPhaseRestart = 0
               EgtDisableModified()
            Case Else      ' CANCEL
               Return
         End Select
      End If
      ' Se abilitate, eseguo le stime
      If GetPrivateProfileInt(S_MACH_ESTIMATIONS, K_ENABLEEST, 0, m_MainWindow.GetMachIniFile()) <> 0 Then
         EgtEstimate(m_MainWindow.GetTempDir() & "\MachProj.html", "OmagCut ver." & m_MainWindow.GetVersion())
      End If
      ' Genero file CNC (lancio anche se errore in precedenza) -> recupero la tavola corrente! CamAuto.GetCurrentTable()
      Dim nIndexTab As Integer = CamAuto.GetCurrentTable()
      Dim sIndexTab As String = String.Empty
      If nIndexTab > 0 Then
         sIndexTab = nIndexTab.ToString
      End If
      Dim sFileName As String = "CadCut" & sIndexTab
      Dim sCncPath As String = m_MainWindow.GetCncDir() & "\" & sFileName & m_MainWindow.m_CurrentMachine.sIsoFileExt
      bOk = EgtGenerate(sCncPath, "OmagCut ver." & m_MainWindow.GetVersion()) And bOk
      ' Costringo ad aggiornare UI
      UpdateUI()
      ' Ripristino come fase corrente quella iniziale
      EgtSetCurrPhase(1)
      If bOk Then
         m_CurrProjPage.SetInfoMessage("Genarato file " & sFileName & m_MainWindow.m_CurrentMachine.sIsoFileExt)
      Else
         m_CurrProjPage.SetErrorMessage(EgtMsg(90314))       'Errore nella generazione del programma CN
      End If
   End Sub

   Private Function ProcessEvents(nProg As Integer, nPause As Integer) As Integer
      ' Visualizzo assi
      ShowCncData()
      ' Costringo ad aggiornare UI
      UpdateUI()
      Return 0
   End Function

   Private Function ProcessOutText(ByRef psText As IntPtr) As Boolean
      ' Emetto stringa di testo
      Dim sText As String = (Marshal.PtrToStringUni(psText))
      If Not String.IsNullOrWhiteSpace(sText) Then
         m_CurrProjPage.SetInfoMessage(sText)
      Else
         m_CurrProjPage.ClearMessage()
      End If
      ' Costringo ad aggiornare UI
      UpdateUI()
      Return True
   End Function

End Class
