Imports EgtUILib

Public Class MultipleCut

   ' Riferimenti a pagine
   Private m_MainWindow As MainWindow = DirectCast(Application.Current.MainWindow, MainWindow)
   Private WithEvents m_CurrProjPage As CurrentProjectPageUC
   ' Flag di pagina attiva
   Private m_bActive As Boolean = False
   ' Flag di simulazione in corso
   Private m_bSimul As Boolean = False

   ' Origine tavola e dati grezzo
   Private m_bRawOk As Boolean = False
   Private m_ptTabOri As Point3d
   Private m_ptRawMin As Point3d
   Private m_ptRawMax As Point3d
   ' Parametri P1 acquisito
   Private m_bPointP1Ok As Boolean = False
   Private m_ptTipP1 As Point3d
   Private m_vtToolP1 As Vector3d
   ' Parametri P2 acquisito
   Private m_bPointP2Ok As Boolean = False
   Private m_ptTipP2 As Point3d
   Private m_vtToolP2 As Vector3d
   ' Parametri della lavorazione
   Private m_bCutOk As Boolean = False
   Private m_dDepth As Double = 0
   Private m_dLen As Double = 1000
   Private m_dAngO As Double = 180
   Private m_dAngV As Double = 0
   Private m_nNum() As Integer = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
   Private m_dDim() As Double = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
   Private m_bHeadSide As Boolean = False
   ' Array delle modalità di acquisizione dei punti
   Private m_PointsModeArray(2) As String
   ' Punto selezionato nel disegno
   Private m_ptPrev As Point3d
   ' Layer per crocette temporanee
   Private m_nTempLay As Integer = GDB_ID.NULL

   ' Costanti
   Private Const MAX_TAB_DEPTH As Double = 10.0
   Private Const MIN_CUT_LEN As Double = 10.0
   Private Const MAX_SIDE_ANG As Double = 60.0
   ' Costanti che indicano la modalità di acquisizione dei punti
   Private Enum PT_MODE As Integer
      SAW = 0
      LASER = 1
      DRAW = 2
   End Enum
   'Costante che indica il lato in cui posizionare i tagli
   Private Enum CutSide As Integer
      Left
      Right
   End Enum

   Private Sub MultipleCut_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized
      ' Creo lista modalità di acquisizione punto 
      m_PointsModeArray(PT_MODE.SAW) = EgtMsg(MSG_DIRECTCUTPAGEUC + 24)
      m_PointsModeArray(PT_MODE.LASER) = EgtMsg(MSG_DIRECTCUTPAGEUC + 12)
      m_PointsModeArray(PT_MODE.DRAW) = EgtMsg(MSG_DIRECTCUTPAGEUC + 25)
      ' la associo alla combobox
      PointModeCmBx.ItemsSource = m_PointsModeArray
      ' assegno messaggi
      Point1Btn.ToolTip = EgtMsg(MSG_DIRECTCUTPAGEUC + 10)
      Point2Btn.ToolTip = EgtMsg(MSG_DIRECTCUTPAGEUC + 11)
      DepthTxBl.Text = EgtMsg(MSG_DIRECTCUTPAGEUC + 13)
      LenghtTxBl.Text = EgtMsg(MSG_DIRECTCUTPAGEUC + 14)
      DirectionTxBl.Text = EgtMsg(MSG_DIRECTCUTPAGEUC + 15)
      SideAngleTxBl.Text = EgtMsg(MSG_DIRECTCUTPAGEUC + 16)
      NumPzTxBl.Text = EgtMsg(MSG_DIRECTCUTPAGEUC + 17)
      DimPzTxBl.Text = EgtMsg(MSG_DIRECTCUTPAGEUC + 18)
      SideTxBl.Text = EgtMsg(MSG_DIRECTCUTPAGEUC + 23)
      SimulBtn.ToolTip = EgtMsg(MSG_CADCUTPAGEUC + 1)
      OkBtn.ToolTip = EgtMsg(MSG_DIRECTCUTPAGEUC + 30)
      Num1TxBl.Text = "1"
      Num2TxBl.Text = "2"
      Num3TxBl.Text = "3"
      Num4TxBl.Text = "4"
      Num5TxBl.Text = "5"
      Num6TxBl.Text = "6"
      Num7TxBl.Text = "7"
      Num8TxBl.Text = "8"
      Num9TxBl.Text = "9"
      Num10TxBl.Text = "10"
      ' Carico i dati dell'ultimo taglio
      m_dDepth = GetPrivateProfileDouble( S_DIRECTCUTS, K_DC_MULT_DEPTH, m_dDepth, m_MainWindow.GetIniFile())
      m_dLen = GetPrivateProfileDouble( S_DIRECTCUTS, K_DC_MULT_LENGTH, m_dLen, m_MainWindow.GetIniFile())
      m_dAngO = GetPrivateProfileDouble( S_DIRECTCUTS, K_DC_MULT_ANGH, m_dAngO, m_MainWindow.GetIniFile())
      m_dAngV = GetPrivateProfileDouble( S_DIRECTCUTS, K_DC_MULT_ANGV, m_dAngV, m_MainWindow.GetIniFile())
      For nI As Integer = 0 To 9
         m_nNum( nI) = GetPrivateProfileInt( S_DIRECTCUTS, K_DC_MULT_NUM & (nI+1).ToString(), 0, m_MainWindow.GetIniFile())
         m_dDim( nI) = GetPrivateProfileDouble( S_DIRECTCUTS, K_DC_MULT_DIM & (nI+1).ToString(), 0, m_MainWindow.GetIniFile())
      Next
      m_bHeadSide = ( GetPrivateProfileInt( S_DIRECTCUTS, K_DC_MULT_HEADSIDE, 0, m_MainWindow.GetIniFile()) <> 0)
      m_ptTipP1.x = GetPrivateProfileDouble( S_DIRECTCUTS, K_DC_MULT_POSX, m_ptTipP1.x, m_MainWindow.GetIniFile())
      m_ptTipP1.y = GetPrivateProfileDouble( S_DIRECTCUTS, K_DC_MULT_POSY, m_ptTipP1.y, m_MainWindow.GetIniFile())
   End Sub

   Private Sub MultipleCut_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
      ' Attivo la pagina
      m_CurrProjPage = m_MainWindow.m_CurrentProjectPageUC
      m_bActive = True
      ' Se rientro da simulazione
      If m_bSimul Then
         m_bSimul = False
         ' Disabilito registrazione progetto modificato
         EgtDisableModified()
         ' Aggiorno visualizzazione
         SetMachineInCurrPos()
         m_MainWindow.m_DirectCutPageUC.m_bShowMachine = True
         EgtSetMachineLook(m_MainWindow.m_DirectCutPageUC.m_nMachLook)
         EgtDraw()
         Return
      End If
      ' Disabilito registrazione progetto modificato
      EgtDisableModified()
      ' Creo layer temporaneo per crocette
      m_nTempLay = EgtCreateGroup(GDB_ID.ROOT)
      EgtSetLevel(m_nTempLay, GDB_LV.TEMP)
      ' Origine tavola
      m_bRawOk = True
      If Not EgtGetTableRef(1, m_ptTabOri) Then
         m_bRawOk = False
         EgtOutLog("Error on TableRef1")
      End If
      ' Dati del grezzo
      If Not GetRawBox(m_ptRawMin, m_ptRawMax) Then
         m_bRawOk = False
         EgtOutLog("Error on RawBox")
      End If
      ' Reset punto acquisito
      m_bPointP1Ok = False
      m_bPointP2Ok = False
      ' Inizializzo primo punto acquisito dal disegno
      m_ptPrev = m_ptTipP1 + ( m_ptTabOri - Point3d.ORIG())
      m_ptPrev.z = m_ptRawMax.z
      ' Disegno crocetta che indica il punto acquisito
      CreateCross(m_nTempLay, m_ptPrev)
      ' Imposto modalità di acquisizione punti
      PointModeCmBx.SelectedIndex = PT_MODE.DRAW
      SetCoordVisibility(True)
      ShowCoord()
      ' Assegno parametri di lavorazione
      DepthTxBx.Text = LenToString( m_dDepth, 1)
      LenghtTxBx.Text = LenToString( m_dLen, 1)
      DirectionTxBx.Text = DoubleToString( m_dAngO - m_MainWindow.m_CurrentMachine.dDeltaC, 2)
      SideAngleTxBx.Text = DoubleToString( m_dAngV, 2)
      NumPz1TxBx.Text = m_nNum(0).ToString()
      DimPz1TxBx.Text = LenToString( m_dDim(0), 1)
      NumPz2TxBx.Text = m_nNum(1).ToString()
      DimPz2TxBx.Text = LenToString( m_dDim(1), 1)
      NumPz3TxBx.Text = m_nNum(2).ToString()
      DimPz3TxBx.Text = LenToString( m_dDim(2), 1)
      NumPz4TxBx.Text = m_nNum(3).ToString()
      DimPz4TxBx.Text = LenToString( m_dDim(3), 1)
      NumPz5TxBx.Text = m_nNum(4).ToString()
      DimPz5TxBx.Text = LenToString( m_dDim(4), 1)
      NumPz6TxBx.Text = m_nNum(5).ToString()
      DimPz6TxBx.Text = LenToString( m_dDim(5), 1)
      NumPz7TxBx.Text = m_nNum(6).ToString()
      DimPz7TxBx.Text = LenToString( m_dDim(6), 1)
      NumPz8TxBx.Text = m_nNum(7).ToString()
      DimPz8TxBx.Text = LenToString( m_dDim(7), 1)
      NumPz9TxBx.Text = m_nNum(8).ToString()
      DimPz9TxBx.Text = LenToString( m_dDim(8), 1)
      NumPz10TxBx.Text = m_nNum(9).ToString()
      DimPz10TxBx.Text = LenToString( m_dDim(9), 1)
      SideChBx.IsChecked = m_bHeadSide
      ' Reset taglio e disabilito bottone esecuzione
      m_bCutOk = False
      UpdateSimulOkBtn()
      ' Disabilito bottone secondo punto
      Point2Btn.IsEnabled = False
      ' Deseleziono bottone primo punto
      Point1Btn.IsChecked = False
      ' Aggiorno visualizzazione
      EgtDraw()
   End Sub

   Friend Sub MultipleCut_Unloaded(sender As Object, e As RoutedEventArgs) Handles Me.Unloaded
      ' Salvo i dati correnti
      WritePrivateProfileString( S_DIRECTCUTS, K_DC_MULT_DEPTH, DoubleToString( m_dDepth, 2), m_MainWindow.GetIniFile())
      WritePrivateProfileString( S_DIRECTCUTS, K_DC_MULT_LENGTH, DoubleToString( m_dLen, 2), m_MainWindow.GetIniFile())
      WritePrivateProfileString( S_DIRECTCUTS, K_DC_MULT_ANGH, DoubleToString( m_dAngO, 2), m_MainWindow.GetIniFile())
      WritePrivateProfileString( S_DIRECTCUTS, K_DC_MULT_ANGV, DoubleToString( m_dAngV, 2), m_MainWindow.GetIniFile())
      For nI As Integer = 0 To 9
         WritePrivateProfileString( S_DIRECTCUTS, K_DC_MULT_NUM & (nI+1).ToString(), m_nNum( nI).ToString(), m_MainWindow.GetIniFile())
         WritePrivateProfileString( S_DIRECTCUTS, K_DC_MULT_DIM & (nI+1).ToString(), DoubleToString( m_dDim( nI), 2), m_MainWindow.GetIniFile())
      Next
      WritePrivateProfileString( S_DIRECTCUTS, K_DC_MULT_HEADSIDE, If( m_bHeadSide, "1", "0"), m_MainWindow.GetIniFile())
      WritePrivateProfileString( S_DIRECTCUTS, K_DC_MULT_POSX, DoubleToString( m_ptTipP1.x, 2), m_MainWindow.GetIniFile())
      WritePrivateProfileString( S_DIRECTCUTS, K_DC_MULT_POSY, DoubleToString( m_ptTipP1.y, 2), m_MainWindow.GetIniFile())
      ' Se non vado in simulazione
      If Not m_bSimul Then
         ' Dichiaro sottopagina da non riattivare
         m_MainWindow.m_DirectCutPageUC.m_ActiveDirectCutPage = DirectCutPageUC.DirectCutPages.DirectCut
         ' Rimuovo layer temporaneo per crocette
         EgtErase(m_nTempLay)
         ' Rimuovo eventuale pezzo per taglio diretto
         EraseDirectCutPart()
         ' Riattivo eventuali lavorazioni presenti
         ActivateAllMachinings()
         ' Abilito registrazione progetto modificato
         EgtEnableModified()
         ' Nascondo la macchina
         m_MainWindow.m_DirectCutPageUC.m_bShowMachine = False
         EgtSetMachineLook(MCH_LOOK.TAB)
         EgtDraw()
      End If
      ' Dichiaro pagina non attiva
      m_bActive = False
   End Sub

   Public Sub SetEnableParam(ByVal bIsSaw As Boolean)
      DepthTxBx.IsEnabled = bIsSaw
   End Sub

   Private Sub UpdateSimulOkBtn()
      If m_bCutOk Then
         SimulBtn.IsEnabled = True
         SimulBtn.Foreground = Brushes.Black
         OkBtn.IsEnabled = True
         OkBtn.Foreground = Brushes.Black
      Else
         SimulBtn.IsEnabled = False
         SimulBtn.Foreground = Brushes.DarkGray
         OkBtn.IsEnabled = False
         OkBtn.Foreground = Brushes.DarkGray
      End If
   End Sub

   Private Sub OnMyMouseDownScene(sender As Object, e As System.Windows.Forms.MouseEventArgs) Handles m_CurrProjPage.OnMouseDownScene
      ' Verifico di essere il gestore attivo
      If Not m_bActive Then Return
      ' Si può selezionare solo con il tasto sinistro e se stato NULL
      If e.Button <> Windows.Forms.MouseButtons.Left Or
         Not m_CurrProjPage.CurrentProjectScene.IsStatusNull() Then
         Return
      End If
      ' Rimuovo eventuali crocette create acquisendo i punti nel disegno
      EgtEmptyGroup(m_nTempLay)
      ' Acquisisco punto da disegno
      EgtUnProjectPoint(e.Location, m_ptPrev)
      ' Aggiusto Z punto acquisito (è in globale)
      Dim dPtPrevZ As Double = m_ptPrev.z
      m_ptPrev.z = m_ptRawMax.z
      ' Se direzione di vista calcolabile e da sopra posso aggiustare anche XY
      Dim dAngVertDeg, dAngHorizDeg As Double
      If EgtGetGenericView(dAngVertDeg, dAngHorizDeg) Then
         Dim vtDir As Vector3d = Vector3d.FromSpherical(1, dAngVertDeg, dAngHorizDeg)
         If vtDir.z > EPS_SMALL Then
            m_ptPrev.z = dPtPrevZ
            m_ptPrev += vtDir * (m_ptRawMax.z - m_ptPrev.z) / vtDir.z
         End If
      End If
      ' Visualizzo coordinate (rispetto a 0 tavola)
      ShowCoord()
      ' Disegno crocetta che indica il punto acquisito
      CreateCross(m_nTempLay, m_ptPrev)
      EgtDraw()
   End Sub

   Private Sub PointModeCmBx_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles PointModeCmBx.SelectionChanged
      SetCoordVisibility(PointModeCmBx.SelectedIndex = PT_MODE.DRAW)
   End Sub

   Private Sub Point1Btn_Click(sender As Object, e As RoutedEventArgs) Handles Point1Btn.Click
      ' Rimuovo eventuali crocette create acquisendo i punti nel disegno
      EgtEmptyGroup(m_nTempLay)
      ' Reset punto non acquisito
      m_bPointP1Ok = False
      ' Verifico configurazione tavola e grezzo
      If Not m_bRawOk Then Return

      ' Recupero dati utensile e testa corrente
      Dim sTool As String = ""
      Dim sHead As String = ""
      Dim nExit As Integer = 0
      EgtGetCalcTool(sTool, sHead, nExit)

      ' Se acquisizone lama o laser
      If PointModeCmBx.SelectedIndex = PT_MODE.SAW Or PointModeCmBx.SelectedIndex = PT_MODE.LASER Then

         ' Recupero la posizione macchina
         Dim dL1, dL2, dL3, dR1, dR2 As Double
         If Not m_MainWindow.m_CNCommunication.GetAxesPositions(dL1, dL2, dL3, dR1, dR2) Then Return
         ' Ricavo dati lama corrente
         Dim sSaw As String = m_MainWindow.m_CurrentMachine.sCurrSaw
         ' Se punto da laser
         If PointModeCmBx.SelectedIndex = PT_MODE.LASER Then
            ' Imposto come testa corrente il laser (senza utensile ovviamente)
            If Not EgtSetCalcTool("", "H3", 1) Then Return
            ' Trasformo in posizione punta utensile in basso
            If Not EgtGetCalcTipFromPositions(dL1, dL2, dL3, dR1, dR2, True, m_ptTipP1) Then Return
            ' Reimposto eventuale precedente utensile
            EgtSetCalcTool(sTool, sHead, nExit)

            ' Altrimenti da lama
         Else
            ' Reimposto eventuale precedente utensile
            EgtSetCalcTool(sTool, sHead, nExit)

            ' Trasformo in posizione punta utensile in basso
            If Not EgtGetCalcTipFromPositions(dL1, dL2, dL3, dR1, dR2, True, m_ptTipP1) Then Return
         End If
         ' Calcolo direzione asse lama
         If Not EgtGetCalcToolDirFromAngles(dR1, dR2, m_vtToolP1) Then Return
         ' Porto il tip nell'origine tavola
         m_ptTipP1.ToLoc(New Frame3d(m_ptTabOri))
         m_bPointP1Ok = True
         ' Assegno angoli
         Dim dTLen, dTAngV, dTAngO As Double
         m_vtToolP1.ToSpherical(dTLen, dTAngV, dTAngO)
         m_dAngO = dTAngO + 90
         m_dAngV = 90 - dTAngV
         DirectionTxBx.Text = DoubleToString(m_dAngO - m_MainWindow.m_CurrentMachine.dDeltaC, 2)
         SideAngleTxBx.Text = DoubleToString(m_dAngV, 2)

      Else
         ' Assegno punto selezionato nel disegno a m_ptTipP1
         m_ptTipP1 = m_ptPrev
         ' Porto il tip nell'origine tavola
         m_ptTipP1.ToLoc(New Frame3d(m_ptTabOri))
         m_bPointP1Ok = True
         ' Reimposto eventuale precedente utensile
         EgtSetCalcTool(sTool, sHead, nExit)

      End If
      ' Disegno il taglio
      CreateMultipleCut()
      ' Disegno la macchina nella sua posizione reale
      SetMachineInCurrPos()
      m_MainWindow.m_DirectCutPageUC.m_bShowMachine = True
      EgtSetMachineLook(m_MainWindow.m_DirectCutPageUC.m_nMachLook)
      EgtDraw()
      ' Seleziono il bottone per indicare che il primo punto è stato acquisito
      Point1Btn.IsChecked = True
      ' Abilito e deseleziono secondo punto
      Point2Btn.IsEnabled = True
      Point2Btn.IsChecked = False
      ' Annullo secondo punto selezionato
      m_bPointP2Ok = False
   End Sub

   Private Sub Point2Btn_Click(sender As Object, e As RoutedEventArgs) Handles Point2Btn.Click
      ' Rimuovo eventuali crocette create acquisendo i punti nel disegno
      EgtEmptyGroup(m_nTempLay)
      ' Deseleziono il bottone (poichè si seleziona automaticamente) cos' nel caso ci sia un errore rimane deselezionato
      Point2Btn.IsChecked = False
      ' Reset punto non acquisito
      m_bPointP2Ok = False
      ' Verifico configurazione tavola e grezzo
      If Not m_bRawOk Then Return

      ' Recupero dati utensile e testa corrente
      Dim sTool As String = ""
      Dim sHead As String = ""
      Dim nExit As Integer = 0
      EgtGetCalcTool(sTool, sHead, nExit)

      ' Se acquisizone lama o laser
      If PointModeCmBx.SelectedIndex = PT_MODE.SAW Or PointModeCmBx.SelectedIndex = PT_MODE.LASER Then

         ' Recupero la posizione macchina
         Dim dL1, dL2, dL3, dR1, dR2 As Double
         If Not m_MainWindow.m_CNCommunication.GetAxesPositions(dL1, dL2, dL3, dR1, dR2) Then Return
         ' Ricavo dati lama corrente
         Dim sSaw As String = m_MainWindow.m_CurrentMachine.sCurrSaw
         ' Se punto da laser
         If PointModeCmBx.SelectedIndex = PT_MODE.LASER Then
            ' Imposto come testa corrente il laser (senza utensile ovviamente)
            If Not EgtSetCalcTool("", "H3", 1) Then Return
            ' Trasformo in posizione punta utensile in basso
            If Not EgtGetCalcTipFromPositions(dL1, dL2, dL3, dR1, dR2, True, m_ptTipP2) Then Return
            ' Reimposto eventuale precedente utensile
            EgtSetCalcTool(sTool, sHead, nExit)
            ' Altrimenti da lama
         Else
            ' Reimposto eventuale precedente utensile
            EgtSetCalcTool(sTool, sHead, nExit)
            ' Trasformo in posizione punta utensile in basso
            If Not EgtGetCalcTipFromPositions(dL1, dL2, dL3, dR1, dR2, True, m_ptTipP2) Then Return
         End If
         ' Calcolo direzione asse lama
         If Not EgtGetCalcToolDirFromAngles(dR1, dR2, m_vtToolP2) Then Return
         ' Porto il tip nell'origine tavola
         m_ptTipP2.ToLoc(New Frame3d(m_ptTabOri))
         m_bPointP2Ok = True
         ' Assegno angolo verticale da direzione utensile
         Dim dTLen, dTAngV, dTAngO As Double
         m_vtToolP2.ToSpherical(dTLen, dTAngV, dTAngO)
         m_dAngV = 90 - dTAngV
         SideAngleTxBx.Text = DoubleToString(m_dAngV, 2)

      Else
         ' Assegno punto selezionato nel disegno a m_ptTipP2
         m_ptTipP2 = m_ptPrev
         ' Porto il tip nell'origine tavola
         m_ptTipP2.ToLoc(New Frame3d(m_ptTabOri))
         m_bPointP2Ok = True
         ' Reimposto eventuale precedente utensile
         EgtSetCalcTool(sTool, sHead, nExit)

      End If

      ' Se il secondo punto non coincide con il primo, disegno il taglio
      Dim vtDiff As Vector3d = m_ptTipP2 - m_ptTipP1
      vtDiff.z = 0
      Dim dLen As Double
      Dim dAngVertDeg As Double
      Dim dAngOrizzDeg As Double
      vtDiff.ToSpherical(dLen, dAngVertDeg, dAngOrizzDeg)
      If dLen > EPS_SMALL Then
         m_dLen = dLen
         m_dAngO = dAngOrizzDeg
         LenghtTxBx.Text = LenToString(dLen, 1)
         m_dAngO = dAngOrizzDeg
         DirectionTxBx.Text = DoubleToString(m_dAngO - m_MainWindow.m_CurrentMachine.dDeltaC, 2)
         CreateMultipleCut()
         ' Disegno la macchina nella sua posizione reale
         SetMachineInCurrPos()
         m_MainWindow.m_DirectCutPageUC.m_bShowMachine = True
         EgtSetMachineLook(m_MainWindow.m_DirectCutPageUC.m_nMachLook)
         EgtDraw()
         ' Seleziono il bottone per indicare che il secondo punto è stato acquisito
         Point2Btn.IsChecked = True
      Else
         Point1Btn_Click(sender, e)
         ' Deseleziono il bottone per indicare che il secondo punto non è stato acquisito perchè uguale al primo
         Point2Btn.IsChecked = False
      End If
   End Sub

   Private Sub DepthTxBx_EgtClosed(sender As Object, e As EventArgs) Handles DepthTxBx.EgtClosed
      ' Verifico che l'affondamento impostato non sia superiore a quello massimo
      Dim dMaxDepth = m_ptRawMax.z - m_ptRawMin.z + MAX_TAB_DEPTH
      Dim dDepth As Double = 0
      StringToLen(DepthTxBx.Text, dDepth)
      If dDepth < 0 Then
         m_dDepth = 0
      ElseIf dDepth > dMaxDepth Then
         m_dDepth = dMaxDepth
      Else
         m_dDepth = dDepth
      End If
      DepthTxBx.Text = LenToString(m_dDepth, 2)
      ' Disegno il taglio
      CreateMultipleCut()
      SetMachineInCurrPos()
      EgtDraw()
   End Sub

   Private Sub LenghtTxBx_EgtClosed(sender As Object, e As EventArgs) Handles LenghtTxBx.EgtClosed
      ' Verifico che la lunghezza del taglio impostata non sia inferiore a quella minima
      Dim dLenght As Double = 0
      StringToLen(LenghtTxBx.Text, dLenght)
      If dLenght < MIN_CUT_LEN Then
         m_dLen = MIN_CUT_LEN
      Else
         m_dLen = dLenght
      End If
      LenghtTxBx.Text = LenToString(m_dLen, 2)
      ' Disegno il taglio
      CreateMultipleCut()
      SetMachineInCurrPos()
      EgtDraw()
   End Sub

   Private Sub DirectionTxBx_EgtClosed(sender As Object, e As EventArgs) Handles DirectionTxBx.EgtClosed
      ' Assegno il nuovo valore di direzione
      Dim dDirection As Double = 0
      StringToDouble(DirectionTxBx.Text, dDirection)
      dDirection += m_MainWindow.m_CurrentMachine.dDeltaC
      m_dAngO = dDirection
      ' Dichiaro non più usato P2
      m_bPointP2Ok = False
      Point2Btn.IsChecked = False
      ' Disegno il taglio
      CreateMultipleCut()
      SetMachineInCurrPos()
      EgtDraw()
   End Sub

   Private Sub SideAngleTxBx_EgtClosed(sender As Object, e As EventArgs) Handles SideAngleTxBx.EgtClosed
      '  Verifico che l'inclinazione del taglio impostata non sia superiore a quella massima
      Dim dSideAngle As Double = 0
      StringToDouble(SideAngleTxBx.Text, dSideAngle)
      If dSideAngle < 0 Then
         m_dAngV = 0
      ElseIf dSideAngle > MAX_SIDE_ANG Then
         m_dAngV = MAX_SIDE_ANG
      Else
         m_dAngV = dSideAngle
      End If
      SideAngleTxBx.Text = DoubleToString(m_dAngV, 2)
      ' Disegno il taglio
      CreateMultipleCut()
      SetMachineInCurrPos()
      EgtDraw()
   End Sub

   Private Sub XcoordTxBx_EgtClosed(sender As Object, e As EventArgs) Handles XcoordTxBx.EgtClosed
      ' Recupero il valore della coordinata (in 0 Tab)
      Dim dXcoord As Double = 0
      StringToLen(XcoordTxBx.Text, dXcoord)
      XcoordTxBx.Text = LenToString(dXcoord, 2)
      ' lo assegno al punto corrente (in 0 Macc)
      m_ptPrev.x = dXcoord + m_ptTabOri.x
      ' Rimuovo eventuali crocette create acquisendo i punti nel disegno
      EgtEmptyGroup(m_nTempLay)
      ' Disegno crocetta che indica il punto acquisito
      CreateCross(m_nTempLay, m_ptPrev)
      EgtDraw()
   End Sub

   Private Sub YcoordTxBx_EgtClosed(sender As Object, e As EventArgs) Handles YcoordTxBx.EgtClosed
      ' Recupero il valore della coordinata (in 0 Tab)
      Dim dYcoord As Double = 0
      StringToLen(YcoordTxBx.Text, dYcoord)
      YcoordTxBx.Text = LenToString(dYcoord, 2)
      ' lo assegno al punto corrente (in 0 Macc)
      m_ptPrev.y = dYcoord + m_ptTabOri.y
      ' Rimuovo eventuali crocette create acquisendo i punti nel disegno
      EgtEmptyGroup(m_nTempLay)
      ' Disegno crocetta che indica il punto acquisito
      CreateCross(m_nTempLay, m_ptPrev)
      EgtDraw()
   End Sub

   Private Sub SimulBtn_Click(sender As Object, e As RoutedEventArgs) Handles SimulBtn.Click
      ' Verifico ci sia un taglio valido
      If Not m_bCutOk Then Return
      ' Salvo il progetto con le lavorazioni
      EgtSetCurrentContext(m_CurrProjPage.CurrentProjectScene.GetCtx())
      Dim sMchPath As String = m_MainWindow.GetTempDir() & "\" & "DirectProj.nge"
      m_MainWindow.m_CurrentProjectPageUC.SaveFile(sMchPath, False)
      ' Predispongo passaggio a simulazione
      m_bSimul = True
      m_CurrProjPage.m_SceneButtons.MeasureBtn.IsChecked = False
      m_CurrProjPage.CurrProjGrid.Visibility = Windows.Visibility.Hidden
      m_CurrProjPage.CurrentProjectPageGrid.Children.Remove(m_MainWindow.m_DirectCutPageUC)
      m_MainWindow.m_PrevActivePage = MainWindow.Pages.DirectCut
      m_CurrProjPage.CurrentProjectPageGrid.Children.Add(m_MainWindow.m_SimulationPage)
      m_MainWindow.m_ActivePage = MainWindow.Pages.Simulation
   End Sub

   Private Sub OkBtn_Click(sender As Object, e As RoutedEventArgs) Handles OkBtn.Click
#If TRIAL Then
      m_CurrProjPage.SetWarningMessage("Trial Version")
#Else
      ' Verifico non sia versione Ufficio
      If m_MainWindow.GetKeyOption( MainWindow.KEY_OPT.OFFICE_TYPE) Then
          m_CurrProjPage.SetWarningMessage( "Office Version")
          Return
      End If
      ' Verifico ci sia un taglio valido
      If Not m_bCutOk Then Return
      ' Salvo il progetto con le lavorazioni
      Dim sMchPath As String = m_MainWindow.GetTempDir() & "\" & "DirectProj.nge"
      m_MainWindow.m_CurrentProjectPageUC.SaveFile(sMchPath, False)
      ' Genero file CNC (lancio anche se errore in precedenza)
      Dim sCncPath As String = m_MainWindow.GetCncDir() & "\DirectCut" & m_MainWindow.m_CurrentMachine.sIsoFileExt
      Dim bOk As Boolean = EgtGenerate(sCncPath, "OmagCut ver." & m_MainWindow.GetVersion())
      ' Se errore in generazione, segnalo l'errore ed esco
      If Not bOk Then
         m_CurrProjPage.SetErrorMessage(EgtMsg(90314))       'Errore nella generazione del programma CN
         Return
      End If
      ' Download programma (eventuali errori sono segnalati dalla funzione)
      If m_MainWindow.m_CNCommunication.SendProgram(sCncPath, 900) Then
         ' copio il progetto corrente come progetto in lavorazione
         Dim sWrkPath As String = m_MainWindow.GetTempDir() & "\" & "WorkProj.nge"
         My.Computer.FileSystem.CopyFile(sMchPath, sWrkPath, True)
         ' lancio eventuale lua post-trasmissione
         m_MainWindow.ExecSentProgScript( True)
      End If
#End If
   End Sub

   Private Sub ExitBtn_Click(sender As Object, e As RoutedEventArgs) Handles ExitBtn.Click
      m_MainWindow.m_DirectCutPageUC.LeftButtonGrid.Children.Remove(Me)
   End Sub

   Private Function CreateMultipleCut() As Boolean
      ' Verifico siano definiti punto iniziale punto finale e grezzo
      If Not m_bPointP1Ok Or Not m_bRawOk Then
         m_bCutOk = False
         Return False
      End If
      ' Spessore grezzo
      Dim dRawHeight As Double = m_ptRawMax.z - m_ptRawMin.z
      ' Rimuovo eventuale vecchio pezzo per taglio diretto
      EraseDirectCutPart()
      ' Disattivo eventuali lavorazioni presenti
      DeactivateAllMachinings()
      ' Creo nuovo pezzo per il taglio diretto
      Dim nPartId = EgtCreateGroup(GDB_ID.ROOT)
      EgtSetName(nPartId, NAME_DIRECTCUT)
      ' Creo layer di taglio
      Dim nLayerId = EgtCreateGroup(nPartId)
      EgtSetName(nLayerId, NAME_OUTLOOP)
      ' Creo il taglio
      Dim ptStart As Point3d = m_ptTipP1
      ptStart.z = 0
      Dim nCutId = EgtCreateLinePDL(nLayerId, ptStart, m_dAngO, m_dLen)
      ' Imposto affondamento e angolo di fianco sul taglio
      EgtSetInfo(nCutId, INFO_DEPTH, m_dDepth)
      EgtSetInfo(nCutId, INFO_SIDE_ANGLE, m_dAngV)
      ' Funzione che crea i tagli successivi al primo
      MultiplyCut(nLayerId, nCutId)
      ' Creo layer per crocette di riferimento
      Dim nCrossLayerId = EgtCreateGroup(nPartId)
      ' Aggiungo crocetta/e
      If m_bPointP1Ok Then
         CreateCross(nCrossLayerId, ptStart)
      End If
      If m_bPointP2Ok Then
         Dim ptEnd As Point3d = m_ptTipP2
         ptEnd.z = 0
         CreateCross(nCrossLayerId, ptEnd)
      End If
      ' Calcolo punto di inserimento nel grezzo
      Dim ptMin, ptMax As Point3d
      EgtGetBBoxGlob(nPartId, GDB_BB.STANDARD, ptMin, ptMax)
      Dim ptIns As Point3d = ptMin + (m_ptTabOri - m_ptRawMin)
      ptIns.z = dRawHeight
      ' Inserisco il pezzo nel grezzo
      EgtAddPartToRawPart(nPartId, ptIns, m_MainWindow.m_CurrentProjectPageUC.m_nRawId)
      ' Inserisco la lavorazione
      m_bCutOk = AddMachinings(nPartId) AndAlso UpdateAllMachiningsToolpaths()
      EgtSetCurrPhase(1)
      ' Eventuale eliminazione Home finale
      If Not m_MainWindow.m_CurrentMachine.bDirectCutsFinalHome Then
         RemoveFinalHome()
      End If
      UpdateSimulOkBtn()
      Return m_bCutOk
   End Function

   Private Function AddOneSpanCut( sDimPz As String, sNumPz As String, dThick As Double,
                                   vtPerp As Vector3d, dPerpMove As Double, nCutId As Integer, nLayerId As Integer) As double
      Dim dDimPz As Double = 0
      Dim nNumPz As Integer = 0
      StringToLen( sDimPz, dDimPz)
      StringToInt( sNumPz, nNumPz)
      Dim dPerpMoveNew As Double = 0
      If dDimPz <> 0 And nNumPz > 0 Then
         For Index As Integer = 1 To nNumPz
            ' Calcolo spostamento
            Dim vtPerpMove As Vector3d = vtPerp * ( dPerpMove + Index * ( dDimPz + dThick))
            ' Creo copie
            Dim nCut2Id = EgtCopyGlob( nCutId, nLayerId)
            EgtMove( nCut2Id, vtPerpMove, GDB_RT.GLOB)
         Next
         dPerpMovenew = nNumPz * ( dDimPz + dThick)
      End If
      Return dPerpMove + dPerpMoveNew
   End Function

   Private Function MultiplyCut(nLayerId As Integer, nCutId As Integer) As Boolean
      ' Recupero lo spessore del taglio della lama o del waterjet correntemente attiva
      Dim nType As Integer = 0
      EgtTdbGetCurrToolParam( MCH_TP.TYPE, nType)
      Dim dThick As Double = 0
      EgtTdbGetCurrToolParam( If( nType = MCH_TY.SAW_STD, MCH_TP.THICK, MCH_TP.DIAM), dThick)
      ' Ricalcolo lo spessore in base all'inclinazione
      dThick = dThick / Math.Cos(m_dAngV * Math.PI / 180)
      ' Imposto angolo di rotazione a seconda del lato dei tagli
      Dim dRotAngO As Double = If(SideChBx.IsChecked(), -90, 90)
      ' Variabile che contiene la somma degli spostamenti
      Dim dPerpMove As Double = 0
      ' Definisco vettore di spostamento
      Dim vtDelta As Vector3d = Vector3d.FromPolar( 1, m_dAngO + dRotAngO)
      ' Calcolo primo gruppo di tagli
      dPerpMove = AddOneSpanCut( DimPz1TxBx.Text, NumPz1TxBx.Text, dThick, vtDelta, dPerpMove, nCutId, nLayerId)
      ' Calcolo secondo gruppo di tagli
      dPerpMove = AddOneSpanCut( DimPz2TxBx.Text, NumPz2TxBx.Text, dThick, vtDelta, dPerpMove, nCutId, nLayerId)
      ' Calcolo terzo gruppo di tagli
      dPerpMove = AddOneSpanCut( DimPz3TxBx.Text, NumPz3TxBx.Text, dThick, vtDelta, dPerpMove, nCutId, nLayerId)
      ' Calcolo quarto gruppo di tagli
      dPerpMove = AddOneSpanCut( DimPz4TxBx.Text, NumPz4TxBx.Text, dThick, vtDelta, dPerpMove, nCutId, nLayerId)
      ' Calcolo quinto gruppo di tagli
      dPerpMove = AddOneSpanCut( DimPz5TxBx.Text, NumPz5TxBx.Text, dThick, vtDelta, dPerpMove, nCutId, nLayerId)
      ' Calcolo sesto gruppo di tagli
      dPerpMove = AddOneSpanCut( DimPz6TxBx.Text, NumPz6TxBx.Text, dThick, vtDelta, dPerpMove, nCutId, nLayerId)
      ' Calcolo settimo gruppo di tagli
      dPerpMove = AddOneSpanCut( DimPz7TxBx.Text, NumPz7TxBx.Text, dThick, vtDelta, dPerpMove, nCutId, nLayerId)
      ' Calcolo ottavo gruppo di tagli
      dPerpMove = AddOneSpanCut( DimPz8TxBx.Text, NumPz8TxBx.Text, dThick, vtDelta, dPerpMove, nCutId, nLayerId)
      ' Calcolo nono gruppo di tagli
      dPerpMove = AddOneSpanCut( DimPz9TxBx.Text, NumPz9TxBx.Text, dThick, vtDelta, dPerpMove, nCutId, nLayerId)
      ' Calcolo decimo gruppo di tagli
      dPerpMove = AddOneSpanCut( DimPz10TxBx.Text, NumPz10TxBx.Text, dThick, vtDelta, dPerpMove, nCutId, nLayerId)
      Return True
   End Function

   Private Function CreateCross(nLayerId As Integer, ptP As Point3d) As Boolean
      ' Aggiungo crocette
      Dim vtCrossX As New Vector3d(20, 0, 0)
      Dim vtCrossY As New Vector3d(0, 20, 0)
      Dim nCrossId1 = EgtCreateLine(nLayerId, ptP + (-vtCrossX), ptP + vtCrossX)
      EgtSetColor(nCrossId1, New Color3d(255, 0, 0))
      Dim nCrossId2 = EgtCreateLine(nLayerId, ptP + (-vtCrossY), ptP + vtCrossY)
      EgtSetColor(nCrossId2, New Color3d(255, 0, 0))
      Return True
   End Function

   Private Sub NumPzsTxBx_EgtClosed(sender As Object, e As EventArgs) Handles NumPz1TxBx.EgtClosed,  DimPz1TxBx.EgtClosed,
                                                                              NumPz2TxBx.EgtClosed,  DimPz2TxBx.EgtClosed,
                                                                              NumPz3TxBx.EgtClosed,  DimPz3TxBx.EgtClosed,
                                                                              NumPz4TxBx.EgtClosed,  DimPz4TxBx.EgtClosed,
                                                                              NumPz5TxBx.EgtClosed,  DimPz5TxBx.EgtClosed,
                                                                              NumPz6TxBx.EgtClosed,  DimPz6TxBx.EgtClosed,
                                                                              NumPz7TxBx.EgtClosed,  DimPz7TxBx.EgtClosed,
                                                                              NumPz8TxBx.EgtClosed,  DimPz8TxBx.EgtClosed,
                                                                              NumPz9TxBx.EgtClosed,  DimPz9TxBx.EgtClosed,
                                                                              NumPz10TxBx.EgtClosed, DimPz10TxBx.EgtClosed,
                                                                              SideChBx.Click
      StringToInt( NumPz1TxBx.Text, m_nNum(0))
      StringToLen( DimPz1TxBx.Text, m_dDim(0))
      StringToInt( NumPz2TxBx.Text, m_nNum(1))
      StringToLen( DimPz2TxBx.Text, m_dDim(1))
      StringToInt( NumPz3TxBx.Text, m_nNum(2))
      StringToLen( DimPz3TxBx.Text, m_dDim(2))
      StringToInt( NumPz4TxBx.Text, m_nNum(3))
      StringToLen( DimPz4TxBx.Text, m_dDim(3))
      StringToInt( NumPz5TxBx.Text, m_nNum(4))
      StringToLen( DimPz5TxBx.Text, m_dDim(4))
      StringToInt( NumPz6TxBx.Text, m_nNum(5))
      StringToLen( DimPz6TxBx.Text, m_dDim(5))
      StringToInt( NumPz7TxBx.Text, m_nNum(6))
      StringToLen( DimPz7TxBx.Text, m_dDim(6))
      StringToInt( NumPz8TxBx.Text, m_nNum(7))
      StringToLen( DimPz8TxBx.Text, m_dDim(7))
      StringToInt( NumPz9TxBx.Text, m_nNum(8))
      StringToLen( DimPz9TxBx.Text, m_dDim(8))
      StringToInt( NumPz10TxBx.Text, m_nNum(9))
      StringToLen( DimPz10TxBx.Text, m_dDim(9))
      m_bHeadSide = SideChBx.IsChecked
      ' Disegno il taglio
      CreateMultipleCut()
      SetMachineInCurrPos()
      EgtDraw()
   End Sub

   Private Sub SetCoordVisibility(bShow As Boolean)
      XcoordTxBl.Visibility = If(bShow, Windows.Visibility.Visible, Windows.Visibility.Hidden)
      XcoordTxBx.Visibility = If(bShow, Windows.Visibility.Visible, Windows.Visibility.Hidden)
      YcoordTxBl.Visibility = If(bShow, Windows.Visibility.Visible, Windows.Visibility.Hidden)
      YcoordTxBx.Visibility = If(bShow, Windows.Visibility.Visible, Windows.Visibility.Hidden)
   End Sub

   Private Sub ShowCoord()
      Dim ptText As Point3d = m_ptPrev
      ptText.ToLoc(New Frame3d(m_ptTabOri))
      XcoordTxBx.Text = LenToString(ptText.x, 2)
      YcoordTxBx.Text = LenToString(ptText.y, 2)
   End Sub

   Private Function SetMachineInCurrPos() As Boolean
      ' Recupero la posizione macchina
      Dim dL1, dL2, dL3, dR1, dR2 As Double
      If Not m_MainWindow.m_CNCommunication.GetAxesPositions(dL1, dL2, dL3, dR1, dR2) Then Return False
      ' Recupero il nome degli assi macchina
      Dim sL1 As String = String.Empty
      Dim sL2 As String = String.Empty
      Dim sL3 As String = String.Empty
      Dim sR1 As String = String.Empty
      Dim sR2 As String = String.Empty
      If Not m_MainWindow.m_CNCommunication.GetAxesNames(sL1, sL2, sL3, sR1, sR2) Then Return False
      ' Visualizzo macchina in posizione
      EgtSetAxisPos(sL1, dL1)
      EgtSetAxisPos(sL2, dL2)
      EgtSetAxisPos(sL3, dL3)
      EgtSetAxisPos(sR1, dR1)
      EgtSetAxisPos(sR2, dR2)
      Return True
   End Function

End Class