Imports EgtUILib
Public Class SingleCutAuto
   ' 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

   ' ---------------------------- Parametri per RAWPAR -------------------------------------
   ' Colori standard
   Private m_RawCol As New Color3d(64, 192, 255, 40)
   Private m_KerfCol As New Color3d(255, 0, 0, 100)
   ' Dati tavola
   Private m_ptTableMin As Point3d
   Private m_dTableLength As Double = 0
   Private m_dTableWidth As Double = 0
   ' Dimensioni grezzo rettangolare
   Private m_RawLength As Double = 0
   Private m_RawWidth As Double = 0
   Private m_RawHeight As Double = 0
   Private m_RawOffsX As Double = 0
   Private m_RawOffsY As Double = 0
   Private m_RawKerf As Double = 0

   ' Lista dei materiali
   Private m_MaterialsList As New List(Of MachiningMaterial)
   ' ---------------------------- Parametri per RAWPAR -------------------------------------

   ' 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 per UTENSILE -------------------------------------
   Private m_ThickLama As Double
   Private m_DiamLama As Double
   ' parametri calcolati da file DummySAW.lua
   Private m_dSpeed As Double
   Private m_dFeed As Double
   Private m_dStartFeed As Double
   Private m_dEndFeed As Double
   ' ---------------------------- Parametri per UTENSILE -------------------------------------

   Public Shared m_PrecSaw As String = String.Empty
   Public Shared m_PrecSawing As String = String.Empty
   Private m_bPrecRawExist As Boolean = False
   Private m_dPrecKerf As Double = 0

   ' 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_dOffset As Double = 0
   Private m_bSawTh 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

   Private Sub SingleCut_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.Content = EgtMsg(MSG_DIRECTCUTPAGEUC + 10)
      Point2Btn.Content = EgtMsg(MSG_DIRECTCUTPAGEUC + 11)
      DiamLamaTxBl.Text = "Diamtero lama"
      ThickLamaTxBl.Text = "Spessore lama"
      ThickMatTxBl.Text = "Spessore materiale"
      SimulBtn.Content = EgtMsg(MSG_CADCUTPAGEUC + 1)
      OkBtn.Content = EgtMsg(MSG_DIRECTCUTPAGEUC + 30)

      m_RawHeight = GetPrivateProfileDouble(S_RAWPART, K_RAWHEIGHT, 30, m_MainWindow.GetIniFile())
      ThickMatTxBx.Text = LenToString(m_RawHeight, 2)

      ' Carico i dati dell'ultimo taglio
      m_dDepth = GetPrivateProfileDouble(S_DIRECTCUTS, K_DC_SING_DEPTH, m_dDepth, m_MainWindow.GetIniFile())
      m_dLen = GetPrivateProfileDouble(S_DIRECTCUTS, K_DC_SING_LENGTH, m_dLen, m_MainWindow.GetIniFile())
      m_dAngO = GetPrivateProfileDouble(S_DIRECTCUTS, K_DC_SING_ANGH, m_dAngO, m_MainWindow.GetIniFile())
      m_dAngV = GetPrivateProfileDouble(S_DIRECTCUTS, K_DC_SING_ANGV, m_dAngV, m_MainWindow.GetIniFile())
      m_dOffset = GetPrivateProfileDouble(S_DIRECTCUTS, K_DC_SING_OFFSET, m_dOffset, m_MainWindow.GetIniFile())
      m_bSawTh = (GetPrivateProfileInt(S_DIRECTCUTS, K_DC_SING_SAWTH, 0, m_MainWindow.GetIniFile()) <> 0)
      m_ptTipP1.x = GetPrivateProfileDouble(S_DIRECTCUTS, K_DC_SING_POSX, m_ptTipP1.x, m_MainWindow.GetIniFile())
      m_ptTipP1.y = GetPrivateProfileDouble(S_DIRECTCUTS, K_DC_SING_POSY, m_ptTipP1.y, m_MainWindow.GetIniFile())
   End Sub

   Private Sub SingleCut_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
      ' salvo il nome della lavorazione precedente in uso sulla macchina
      m_PrecSaw = m_MainWindow.m_CurrentMachine.sCurrSaw
      ' salvo il nome della lama precedente
      m_PrecSawing = m_MainWindow.m_CurrentMachine.sCurrSawing

      ' 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

      ' 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()
      ' carico la lista dei materiali lavorabili in macchina
      m_MaterialsList.Clear()
      For Each Material As Material In m_MainWindow.m_CurrentMachine.Materials
         m_MaterialsList.Add(New MachiningMaterial(Material.nId, Material.sName))
      Next
      ' Carico l'elenco dei materiali presenti in macchina per l'assegnata lavorazione
      MaterailCmBx.ItemsSource = m_MaterialsList
      ' seleziono il primo elemento della lista
      If m_MaterialsList.Count > 0 Then MaterailCmBx.SelectedIndex = 0

      ' creazione grezzo delle dimensioni della tavola
      RawPart_Loded()
      ' Imposto l'utinsile DummySAW come utensile corrente
      DummySAW_Loaded()
      ' imposto le velocitòà utensile
      UpDateSpeedFeed()
      ' imposto di default l'affondamento lama pari allo spessore della lastra
      m_dDepth = m_RawHeight

      ' 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

   Private Function DummySAW_Loaded() As Boolean
      Dim bOk As Boolean = False
      If EgtTdbSetCurrTool(DUMMY_SAW) And EgtMdbSetCurrMachining(DUMMY_SAWING) Then
         ' Recupero Diametro lama
         bOk = EgtTdbGetCurrToolParam(MCH_TP.TOTDIAM, m_DiamLama)
         DiamLamaTxBx.Text = LenToString(m_DiamLama, 2)
         ' Recupero spessore lama
         bOk = EgtTdbGetCurrToolParam(MCH_TP.THICK, m_ThickLama)
         ThickLamaTxBx.Text = LenToString(m_ThickLama, 2)
         ' Assegno lama corrente
         m_MainWindow.m_CurrentMachine.sCurrSaw = DUMMY_SAW
         ' Assegno lavorazione corrente
         m_MainWindow.m_CurrentMachine.sCurrSawing = DUMMY_SAWING
         ' Assegno posizione di uscita
         bOk = EgtTdbSetCurrToolParam(MCH_TP.EXIT_, "H1")
      Else
         DiamLamaTxBx.Text = "Tonto"
         ThickLamaTxBx.Text = "Tonto"
         ' creo un utensile ausiliario
      End If

      Return bOk
   End Function

   ' calcola i parametri di tagli della lama
   Private Function UpDateSpeedFeed() As Boolean
      Dim bOk As Boolean = True
      Dim tempMat As MachiningMaterial = DirectCast(MaterailCmBx.SelectedItem, MachiningMaterial)
      Dim sLuaPath As String = m_MainWindow.GetCamAutoDir() & "\DummySAW.lua"
      If Not System.IO.File.Exists(sLuaPath) Then
         EgtOutLog("DummySAW error: missing file (" & sLuaPath & ")")
         Return False
      End If
      bOk = EgtLuaExecFile(sLuaPath)
      Dim b As Boolean = EgtLuaSetGlobNumVar("DUM.ThRaw", m_RawHeight)
      EgtLuaSetGlobNumVar("DUM.ThSaw", m_ThickLama)
      EgtLuaSetGlobNumVar("DUM.DimSaw", m_DiamLama)
      EgtLuaSetGlobStringVar("DUM.Mat", tempMat.Name.Trim)
      If Not EgtLuaCallFunction("DUM.CalcParam") Then
         EgtOutLog("Errore calcolo parametri utensile")
      End If
      EgtLuaGetGlobNumVar("DUM.Speed", m_dSpeed)
      EgtLuaGetGlobNumVar("DUM.Feed", m_dFeed)
      EgtLuaGetGlobNumVar("DUM.StartFeed", m_dStartFeed)
      EgtLuaGetGlobNumVar("DUM.EndFeed", m_dEndFeed)

      Dim bOkSet As Boolean = False
      bOkSet = EgtTdbSetCurrToolParam(MCH_TP.FEED, m_dFeed)
      bOkSet = bOkSet And EgtTdbSetCurrToolParam(MCH_TP.STARTFEED, m_dStartFeed)
      bOkSet = bOkSet And EgtTdbSetCurrToolParam(MCH_TP.ENDFEED, m_dEndFeed)
      bOkSet = bOkSet And EgtTdbSetCurrToolParam(MCH_TP.SPEED, m_dSpeed)
      ' resetto le variabili
      EgtLuaResetGlobVar("DUM")
      ' salvo le informazioni dell'utensile
      bOkSet = bOkSet and EgtTdbSaveCurrTool()
      Return bOk
   End Function

   Friend Function RawPart_Loded() As Boolean
      Dim bOk As Boolean = False
      ' Colori standard
      GetPrivateProfileColor(S_RAWPART, K_RAWCOLOR, m_RawCol, m_MainWindow.GetIniFile())
      GetPrivateProfileColor(S_RAWPART, K_KERFCOLOR, m_KerfCol, m_MainWindow.GetIniFile())
      ' Dimensioni tavola
      Dim ptMin, ptMax As Point3d
      If EgtGetTableArea(1, ptMin, ptMax) Then
         m_ptTableMin = ptMin
         m_dTableLength = ptMax.x - ptMin.x
         m_dTableWidth = ptMax.y - ptMin.y
      End If
      ' Origine tavola
      Dim ptRef1 As Point3d
      If EgtGetTableRef(1, ptRef1) Then
         If Not Point3d.SameApprox(m_ptTableMin, ptRef1) Then
            EgtOutLog("Error : TableMin e TableRef1 are different")
         End If
      End If
      ' Nascondo eventuali pezzi in parcheggio
      HideParkedParts()
      ' Deseleziono pezzi
      EgtDeselectAll()
      VeinMatching.OnDeselectAll()
      ' aggiorno dati grezzo-> grande come la tavola
      Dim dVal As Double
      m_RawKerf = 0
      m_RawLength = m_dTableLength
      m_RawWidth = m_dTableWidth
      m_RawHeight = If(StringToLen(ThickMatTxBx.Text, dVal), dVal, 20)
      m_RawOffsX = 1
      m_RawOffsY = 1
      ' recupero il grezzo corrente
      Dim nRawId As Integer = GetCurrentRaw()
      If nRawId = GDB_ID.NULL And m_RawHeight > EPS_SMALL Then
         m_CurrProjPage.m_nRawId = EgtAddRawPart(Point3d.ORIG(), m_RawLength - 2 * m_RawOffsX + 2 * m_RawKerf, m_RawWidth - 2 * m_RawOffsY + 2 * m_RawKerf, m_RawHeight, m_RawCol)
         bOk = True
         ' se esiste e da cancellare
      ElseIf m_RawHeight < EPS_SMALL Then
         EgtRemoveRawPart(nRawId)
         m_CurrProjPage.m_nRawId = GDB_ID.NULL
         bOk = True
         ' Altrimenti lo modifico
      Else
         ' salvo il valore del Kerf precedente
         EgtGetInfo(nRawId, KEY_KERF, m_dPrecKerf)
         m_bPrecRawExist = True
         m_CurrProjPage.m_nRawId = nRawId
         'EgtModifyRawPart(nRawId, Point3d.ORIG(), m_RawLength + 2 * m_RawKerf, m_RawWidth + 2 * m_RawKerf, m_RawHeight, m_RawCol)
         bOk = True
      End If

      AdjustRawPartKerf()
      AdjustRawPartPosition()

      ' Dati del grezzo
      If Not GetRawBox(m_ptRawMin, m_ptRawMax) Then
         m_bRawOk = False
         EgtOutLog("Error on RawBox")
      End If
      ' Aggiorno visualizzazione
      EgtZoom(ZM.ALL)
      Return bOk
   End Function

   Private Function AdjustRawPartKerf() As Boolean
      If m_bPrecRawExist Then Return True
      ' Se non c'è il grezzo, esco
      If m_CurrProjPage.m_nRawId = GDB_ID.NULL Then Return False
      ' Cancello eventuale vecchio contorno di kerf
      Dim nKerfId As Integer = EgtGetFirstNameInGroup(m_CurrProjPage.m_nRawId, NAME_KERF)
      EgtErase(nKerfId)
      ' box grezzo
      Dim ptMin, ptMax As Point3d
      GetRawBox(ptMin, ptMax)
      ptMin.x += m_RawKerf
      ptMin.y += m_RawKerf
      ptMin.z = ptMax.z
      ptMax.x -= m_RawKerf
      ptMax.y -= m_RawKerf
      ' Creo il nuovo contorno del kerf
      nKerfId = EgtCreateRectangle2P(m_CurrProjPage.m_nRawId, ptMin, ptMax, GDB_RT.GLOB)
      EgtSetName(nKerfId, NAME_KERF)
      EgtSetColor(nKerfId, m_KerfCol)
      ' Salvo il valore del kerf (sempre in mm)
      EgtSetInfo(m_CurrProjPage.m_nRawId, KEY_KERF, m_RawKerf)
      Return True
   End Function

   Private Function AdjustRawPartPosition() As Boolean
      If m_bPrecRawExist Then Return True
      ' Sistemo la posizione
      Dim ptRef As New Point3d(m_RawOffsX - m_RawKerf, m_RawOffsY - m_RawKerf, m_MainWindow.m_CurrentMachine.dAdditionalTable)
      If EgtMoveToCornerRawPart(m_CurrProjPage.m_nRawId, ptRef, MCH_CR.BL) Then
         OkBtn.IsEnabled = True
         m_CurrProjPage.ClearMessage()
      Else
         OkBtn.IsEnabled = False
         m_CurrProjPage.SetErrorMessage(EgtMsg(MSG_RAWPARTPAGEUC + 47))      ' Errore nella posizione o dimensione del grezzo
      End If
      Return True
   End Function

   Friend Sub SingleCut_Unloaded(sender As Object, e As RoutedEventArgs) Handles Me.Unloaded
      ' Salvo i dati correnti
      WritePrivateProfileString(S_DIRECTCUTS, K_DC_SING_DEPTH, DoubleToString(m_dDepth, 2), m_MainWindow.GetIniFile())
      WritePrivateProfileString(S_DIRECTCUTS, K_DC_SING_LENGTH, DoubleToString(m_dLen, 2), m_MainWindow.GetIniFile())
      WritePrivateProfileString(S_DIRECTCUTS, K_DC_SING_ANGH, DoubleToString(m_dAngO, 2), m_MainWindow.GetIniFile())
      WritePrivateProfileString(S_DIRECTCUTS, K_DC_SING_ANGV, DoubleToString(m_dAngV, 2), m_MainWindow.GetIniFile())
      WritePrivateProfileString(S_DIRECTCUTS, K_DC_SING_OFFSET, DoubleToString(m_dOffset, 2), m_MainWindow.GetIniFile())
      WritePrivateProfileString(S_DIRECTCUTS, K_DC_SING_SAWTH, If(m_bSawTh, "1", "0"), m_MainWindow.GetIniFile())
      WritePrivateProfileString(S_DIRECTCUTS, K_DC_SING_POSX, DoubleToString(m_ptTipP1.x, 2), m_MainWindow.GetIniFile())
      WritePrivateProfileString(S_DIRECTCUTS, K_DC_SING_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

   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

   ' selezione del tipo di acquisizione punti
   Private Sub PointModeCmBx_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles PointModeCmBx.SelectionChanged
      SetCoordVisibility(PointModeCmBx.SelectedIndex = PT_MODE.DRAW)
   End Sub

   ' acquisizione primo punto
   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

      ' Se acquisizione 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
            ' Ora imposto la lama corrente
            If Not EgtSetCalcTool(sSaw, "H1", 1) Then Return
            ' Altrimenti da lama
         Else
            ' Imposto la lama corrente
            If Not EgtSetCalcTool(sSaw, "H1", 1) Then Return
            ' 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)

         ' Altrimenti punto da click di mouse
      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
         ' Ricavo dati lama corrente
         Dim sSaw As String = m_MainWindow.m_CurrentMachine.sCurrSaw
         ' Imposto la lama corrente
         If Not EgtSetCalcTool(sSaw, "H1", 1) Then Return
      End If

      ' se già esiste un secondo punto allora costruisco il nuovo taglio
      If m_bPointP2Ok Then
         ' 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(m_dLen, 1)
            'DirectionTxBx.Text = DoubleToString(m_dAngO - m_MainWindow.m_CurrentMachine.dDeltaC, 2)
            CreateSingleCut()
            ' 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
      Else
         ' Abilito e deseleziono secondo punto
         Point2Btn.IsEnabled = True
         Point2Btn.IsChecked = False
         ' Annullo secondo punto selezionato
         m_bPointP2Ok = False
      End If

      ' Disegno il taglio
      CreateSingleCut()
      ' 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

      ' 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
            ' Ora imposto la lama corrente
            If Not EgtSetCalcTool(sSaw, "H1", 1) Then Return
            ' Altrimenti da lama
         Else
            ' Imposto la lama corrente
            If Not EgtSetCalcTool(sSaw, "H1", 1) Then Return
            ' 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 angoli
         Dim dTLen, dTAngV, dTAngO As Double
         m_vtToolP2.ToSpherical(dTLen, dTAngV, dTAngO)
         m_dAngV = 90 - dTAngV
         'SideAngleTxBx.Text = DoubleToString(m_dAngV, 2)

         ' Altrimenti punto da click di mouse
      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
         ' Ricavo dati lama corrente
         Dim sSaw As String = m_MainWindow.m_CurrentMachine.sCurrSaw
         ' Imposto la lama corrente
         If Not EgtSetCalcTool(sSaw, "H1", 1) Then Return
      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(m_dLen, 1)
         'DirectionTxBx.Text = DoubleToString(m_dAngO - m_MainWindow.m_CurrentMachine.dDeltaC, 2)
         CreateSingleCut()
         ' 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

   ' selezione del tipo di materiale
   Private Sub MaterailCmBx_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles MaterailCmBx.SelectionChanged
      ' aggiorno i parametri di taglio
      UpDateSpeedFeed()
   End Sub

   'Diametro lama
   Private Sub DiamLamaTxBx_EgtClosed(sender As Object, e As EventArgs) Handles DiamLamaTxBx.EgtClosed
      Dim Diameter As Double = 0
      StringToLen(DiamLamaTxBx.Text, Diameter)
      m_DiamLama = Diameter
      DiamLamaTxBx.Text = LenToString(m_DiamLama, 2)
      EgtTdbSetCurrToolParam(MCH_TP.DIAM, m_DiamLama)
      ' aggiorno i parametri di taglio
      UpDateSpeedFeed()
      ' Disegno il taglio
      CreateSingleCut()
      SetMachineInCurrPos()
      EgtDraw()
   End Sub

   'Spessore lama
   Private Sub ThickLamaTxBl_EgtClosed(sender As Object, e As EventArgs) Handles ThickLamaTxBx.EgtClosed
      ' Recupero il valore dello spessore
      Dim dThickness As Double = 0
      StringToLen(ThickLamaTxBx.Text, dThickness)
      m_ThickLama = dThickness
      ThickLamaTxBx.Text = LenToString(m_ThickLama, 2)
      Dim Test As ToolsDbPageUC = m_MainWindow.m_MachinePageUC.m_ToolsDbPageUC
      EgtTdbSetCurrToolParam(MCH_TP.THICK, m_ThickLama)
      ' aggiorno i parametri di taglio
      UpDateSpeedFeed()
      ' Disegno il taglio
      CreateSingleCut()
      SetMachineInCurrPos()
      EgtDraw()
   End Sub

   ' Spessore materiale
   Private Sub ThickMatTxBl_EgtClosed(sender As Object, e As EventArgs) Handles ThickMatTxBx.EgtClosed
      ' Recupero il valore dello spessore
      Dim dThickness As Double = 0
      StringToLen(ThickMatTxBx.Text, dThickness)
      m_RawHeight = dThickness
      ThickMatTxBx.Text = LenToString(m_RawHeight, 2)
      ' aggiorno i parametri di taglio
      UpDateSpeedFeed()
      'aggiorno la dimesione del grezzo
      RawPart_Loded()
      ' Disegno il taglio
      CreateSingleCut()
      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
      ' reimposto il precedetne utensile e lavorazione
      m_MainWindow.m_CurrentMachine.sCurrSaw = m_PrecSaw
      m_MainWindow.m_CurrentMachine.sCurrSawing = m_PrecSawing
      m_MainWindow.m_DirectCutPageUC.LeftButtonGrid.Children.Remove(Me)
   End Sub

   Private Function CreateSingleCut() As Boolean
      ' Verifico sia definito il punto iniziale e il grezzo
      If Not m_bPointP1Ok Or Not m_bRawOk Then
         m_bCutOk = False
         Return False
      End If
      ' Rimuovo eventuali crocette create acquisendo i punti nel disegno
      EgtEmptyGroup(m_nTempLay)
      ' Spessore grezzo
      Dim dRawHeight As Double = m_ptRawMax.z - m_ptRawMin.z
      ' Recupero spessore lama corrente
      Dim sSaw As String = m_MainWindow.m_CurrentMachine.sCurrSaw
      EgtTdbSetCurrTool(sSaw)
      Dim dThick As Double = 0
      EgtTdbGetCurrToolParam(MCH_TP.THICK, dThick)
      ' Rimuovo eventuale vecchio pezzo per taglio diretto
      EraseDirectCutPart()
      ' Disattivo eventuali lavorazioni presenti
      DeactivateAllMachinings()
      ' Creo nuovo pezzo per il taglio diretto
      Dim nPartId = CreateDirectCutPart()
      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)
      If Math.Abs(m_dOffset) > 10 * EPS_SMALL Then
         Dim dTotOffset = m_dOffset
         If m_bSawTh Then dTotOffset += If(m_dOffset > 0, dThick, -dThick)
         EgtOffsetCurve(nCutId, dTotOffset, OFF_TYPE.EXTEND)
      End If
      ' Imposto affondamento e angolo di fianco sul taglio
      EgtSetInfo(nCutId, INFO_DEPTH, m_dDepth)
      EgtSetInfo(nCutId, INFO_SIDE_ANGLE, m_dAngV)
      ' Creo layer per crocetta 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 CreateCross(nLayerId As Integer, ptP As Point3d) As Boolean
      ' Aggiungo crocette
      ptP += New Vector3d(0, 0, 0.15)
      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))
      Dim nPntId = EgtCreateGeoPoint(nLayerId, ptP)
      EgtSetColor(nPntId, New Color3d(255, 0, 0))
      Return True
   End Function

   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
