Imports System.Collections.ObjectModel
Imports System.ComponentModel
Imports EgtUILib

Public Class FrameMachiningUC

   ' Riferimenti a pagine
   Private m_MainWindow As MainWindow = DirectCast(Application.Current.MainWindow, MainWindow)
   Private WithEvents m_CurrProjPage As CurrentProjectPageUC
   Friend m_ProjectMgr As ProjectMgrUC
   Private m_CurrMachine As CurrentMachine
   Private m_FrameCutPageUC As FrameCutPageUC

   ' Lista per lavorazioni di sgrossatura con lama
   Private m_SawRoughingList As New ObservableCollection(Of String)
   ' Lista per lavorazioni di finitura con lama
   Private m_SawFinishingList As New ObservableCollection(Of String)
   ' Lista per lavorazioni di spatolatura con lama
   Private m_SawSideFinList As New ObservableCollection(Of String)
   ' Lista per lavorazioni singole con lama
   Private m_SawSingleList As New ObservableCollection(Of String)
   ' Flag per disabilitare ricalcolo lavorazioni su impostazione selezione combo
   Private m_DisableCalc As Boolean = False
   ' Trim iniziale della lavorazione
   Friend m_dStartTrim As Double = 0
   ' Trim finale della lavorazione
   Friend m_dEndTrim As Double = 0
   ' Lavora dalla parte opposta
   Friend m_bOtherSide As Boolean = False

   ' Costante per lavorazione non definita
   Private Const NO_MACHINING As String = "-----"

   Private Sub FrameCutPage_Initialized(sender As Object, e As EventArgs) Handles Me.Initialized
      ' Associo ComboBox e Liste
      SawRoughingCmBx.ItemsSource = m_SawRoughingList
      SawFinishingCmBx.ItemsSource = m_SawFinishingList
      SawSideFinCmBx.ItemsSource = m_SawSideFinList
      SawSingleCmBx.ItemsSource = m_SawSingleList

      ' Imposto accorciamenti iniziale e finale di lavorazione
      m_dStartTrim = GetPrivateProfileDouble(S_FRAME, K_STARTTRIM, 0, m_MainWindow.GetIniFile())
      StartTrimTxBx.Text = LenToString(m_dStartTrim, 3)
      m_dEndTrim = GetPrivateProfileDouble(S_FRAME, K_ENDTRIM, 0, m_MainWindow.GetIniFile())
      EndTrimTxBx.Text = LenToString(m_dEndTrim, 3)

      ' Imposto eventuale check per lavorazione lato opposto
      m_bOtherSide = ( GetPrivateProfileInt(S_FRAME, K_OTHERSIDE, 0, m_MainWindow.GetIniFile()) <> 0)
      OthSideChBx.IsChecked = m_bOtherSide

      ' Imposto i messaggi letti dal file dei messaggi
      SawRoughingTxBl.Text = EgtMsg(MSG_FRAMECUTPAGEUC + 4)     'Sgrossatura
      SawFinishingTxBl.Text = EgtMsg(MSG_FRAMECUTPAGEUC + 5)    'Finitura
      SawSideFinTxBl.Text = EgtMsg(MSG_FRAMECUTPAGEUC + 6)      'Spatolatura
      StartTrimTxBl.Text = EgtMsg(MSG_FRAMECUTPAGEUC + 10)      'Accorcia inizio
      EndTrimTxBl.Text = EgtMsg(MSG_FRAMECUTPAGEUC + 11)        'Accorcia fine
      SawSingleTxBl.Text = EgtMsg(MSG_FRAMECUTPAGEUC + 12)      'Taglio singolo
      OthSideTxBl.Text = EgtMsg( 90623)                         'Lato Opposto
   End Sub

   Private Sub FrameCutPage_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
      m_CurrProjPage = m_MainWindow.m_CurrentProjectPageUC
      m_FrameCutPageUC = m_MainWindow.m_FrameCutPageUC
      m_CurrMachine = m_MainWindow.m_CurrentMachine
      ' Aggiorno liste lavorazioni disponibili
      UpdateMachiningList(MCH_MY.SAWROUGHING, m_CurrMachine.sCurrSaw, m_SawRoughingList)
      UpdateMachiningList(MCH_MY.SAWFINISHING, MCH_SAWFIN_SUB.ALONG, m_CurrMachine.sCurrSaw, m_SawFinishingList)
      UpdateMachiningList(MCH_MY.SAWFINISHING, MCH_SAWFIN_SUB.ACROSS, m_CurrMachine.sCurrSaw, m_SawSideFinList)
      UpdateMachiningList(MCH_MY.SAWING, m_CurrMachine.sCurrSaw, m_SawSingleList)
      ' Imposto lavorazioni correnti
      m_DisableCalc = True
      If SawRoughingCmBx.Items.Contains(m_CurrMachine.sCurrSawRoughing) Then
         SawRoughingCmBx.SelectedItem = m_CurrMachine.sCurrSawRoughing
      Else
         SawRoughingCmBx.SelectedItem = NO_MACHINING
         m_CurrMachine.sCurrSawRoughing = String.Empty
      End If
      If SawFinishingCmBx.Items.Contains(m_CurrMachine.sCurrSawFinishing) Then
         SawFinishingCmBx.SelectedItem = m_CurrMachine.sCurrSawFinishing
      Else
         SawFinishingCmBx.SelectedItem = NO_MACHINING
         m_CurrMachine.sCurrSawFinishing = String.Empty
      End If
      If SawSideFinCmBx.Items.Contains(m_CurrMachine.sCurrSawSideFinishing) Then
         SawSideFinCmBx.SelectedItem = m_CurrMachine.sCurrSawSideFinishing
      Else
         SawSideFinCmBx.SelectedItem = NO_MACHINING
         m_CurrMachine.sCurrSawSideFinishing = String.Empty
      End If
      If SawSingleCmBx.Items.Contains(m_CurrMachine.sCurrSawSingle) Then
         SawSingleCmBx.SelectedItem = m_CurrMachine.sCurrSawSingle
      Else
         SawSingleCmBx.SelectedItem = NO_MACHINING
         m_CurrMachine.sCurrSawSingle = String.Empty
      End If
      m_DisableCalc = False
   End Sub

   Private Sub UpdateMachiningList(MachiningType As Integer, CurrTool As String, ByRef MachiningList As ObservableCollection(Of String))
      ' Pulisco la lista
      MachiningList.Clear()
      ' Cerco tutte le lavorazioni che utilizzano l'utensile corrente e le aggiungo alla lista
      Dim MachiningName As String = String.Empty
      Dim bFound As Boolean = EgtMdbGetFirstMachining(MachiningType, MachiningName)
      While bFound
         EgtMdbSetCurrMachining(MachiningName)
         Dim sTuuid As String = String.Empty
         Dim sTool As String = String.Empty
         EgtMdbGetCurrMachiningParam(MCH_MP.TUUID, sTuuid)
         EgtTdbGetToolFromUUID(sTuuid, sTool)
         If sTool = CurrTool And VerifyMatThickCompatibility() Then
            MachiningList.Add(MachiningName)
         End If
         bFound = EgtMdbGetNextMachining(MachiningType, MachiningName)
      End While
      ' Aggiungo la lavorazione nulla
      MachiningList.Add(NO_MACHINING)
   End Sub

   Private Sub UpdateMachiningList(MachiningType As Integer, MachiningSubType As Integer, CurrTool As String, ByRef MachiningList As ObservableCollection(Of String))
      ' Pulisco la lista
      MachiningList.Clear()
      ' Cerco tutte le lavorazioni che utilizzano l'utensile corrente e le aggiungo alla lista
      Dim MachiningName As String = String.Empty
      Dim bFound As Boolean = EgtMdbGetFirstMachining(MachiningType, MachiningName)
      While bFound
         EgtMdbSetCurrMachining(MachiningName)
         Dim SubType As Integer
         EgtMdbGetCurrMachiningParam(MCH_MP.SUBTYPE, SubType)
         Dim sTuuid As String = String.Empty
         Dim sTool As String = String.Empty
         EgtMdbGetCurrMachiningParam(MCH_MP.TUUID, sTuuid)
         EgtTdbGetToolFromUUID(sTuuid, sTool)
         If sTool = CurrTool And SubType = MachiningSubType And VerifyMatThickCompatibility() Then
            MachiningList.Add(MachiningName)
         End If
         bFound = EgtMdbGetNextMachining(MachiningType, MachiningName)
      End While
      ' Aggiungo la lavorazione nulla
      MachiningList.Add(NO_MACHINING)
   End Sub

   Private Function VerifyMatThickCompatibility() As Boolean
      If Not IsNothing(m_CurrMachine.CurrMat) Then
         Dim SysNotes As String = String.Empty
         EgtMdbGetCurrMachiningParam(MCH_MP.SYSNOTES, SysNotes)
         If SysNotes <> String.Empty Then
            Dim MachiningMaterials() = SysNotes.Split(";".ToCharArray)
            SysNotes = String.Empty
            For Each Material As Object In MachiningMaterials
               Dim Param() As String = Material.Split(",".ToCharArray)
               If Param(0) = m_CurrMachine.CurrMat.nId.ToString() Then
                  Dim dRawHeight = GetRawHeight()
                  Dim MatMinH As Double = 0
                  StringToDouble(Param(1), MatMinH)
                  Dim MatMaxH As Double = 0
                  StringToDouble(Param(2), MatMaxH)
                  If dRawHeight > MatMinH - EPS_SMALL And dRawHeight < MatMaxH + EPS_SMALL Then
                     Return True
                  End If
               End If
            Next
            Return False
         Else
            Return True
         End If
      Else
         Return True
      End If
   End Function

   Private Sub SawRoughingCmBx_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles SawRoughingCmBx.SelectionChanged
      If m_DisableCalc Or IsNothing(SawRoughingCmBx.SelectedItem) Then Return
      ' La imposto come lavorazione corrente di sgrossatura con lama
      If SawRoughingCmBx.SelectedItem.ToString() <> NO_MACHINING Then
         m_CurrMachine.sCurrSawRoughing = SawRoughingCmBx.SelectedItem.ToString()
      Else
         m_CurrMachine.sCurrSawRoughing = String.Empty
      End If
      ' La inserisco
      AddFrameSawRoughing(m_dStartTrim, m_dEndTrim)
      ' Aggiorno visualizzazione
      EgtDraw()
   End Sub

   Private Sub SawFinishingCmBx_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles SawFinishingCmBx.SelectionChanged
      If m_DisableCalc Or IsNothing(SawFinishingCmBx.SelectedItem) Then Return
      ' La imposto come lavorazione corrente di finitura con lama
      If SawFinishingCmBx.SelectedItem.ToString() <> NO_MACHINING Then
         m_CurrMachine.sCurrSawFinishing = SawFinishingCmBx.SelectedItem.ToString()
      Else
         m_CurrMachine.sCurrSawFinishing = String.Empty
      End If
      ' La inserisco
      AddFrameSawFinishing(m_dStartTrim, m_dEndTrim)
      ' Aggiorno visualizzazione
      EgtDraw()
   End Sub

   Private Sub SawSideFinCmBx_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles SawSideFinCmBx.SelectionChanged
      If m_DisableCalc Or IsNothing(SawSideFinCmBx.SelectedItem) Then Return
      ' La imposto come lavorazione corrente di finitura con lama
      If SawSideFinCmBx.SelectedItem.ToString() <> NO_MACHINING Then
         m_CurrMachine.sCurrSawSideFinishing = SawSideFinCmBx.SelectedItem.ToString()
      Else
         m_CurrMachine.sCurrSawSideFinishing = String.Empty
      End If
      ' La inserisco
      AddFrameSawSideFinishing(m_dStartTrim, m_dEndTrim)
      ' Aggiorno visualizzazione
      EgtDraw()
   End Sub

   Private Sub SawSingleCmBx_SelectionChanged(sender As Object, e As SelectionChangedEventArgs) Handles SawSingleCmBx.SelectionChanged
      If m_DisableCalc Or IsNothing(SawSingleCmBx.SelectedItem) Then Return
      ' La imposto come lavorazione corrente di taglio singolo con lama
      If SawSingleCmBx.SelectedItem.ToString() <> NO_MACHINING Then
         m_CurrMachine.sCurrSawSingle = SawSingleCmBx.SelectedItem.ToString()
      Else
         m_CurrMachine.sCurrSawSingle = String.Empty
      End If
      ' La inserisco
      AddFrameSawSingle()
      ' Aggiorno visualizzazione
      EgtDraw()
   End Sub

   Private Sub XXTrimTxBx_EgtClosed(sender As Object, e As EventArgs) Handles StartTrimTxBx.EgtClosed, EndTrimTxBx.EgtClosed
      ' Trim iniziale
      Dim dStartTrim As Double = 0
      If StringToLen(StartTrimTxBx.Text, dStartTrim) Then
         m_dStartTrim = dStartTrim
         WritePrivateProfileString(S_FRAME, K_STARTTRIM, DoubleToString(dStartTrim, 3), m_MainWindow.GetIniFile())
      End If
      ' Trim finale
      Dim dEndTrim As Double = 0
      If StringToLen(EndTrimTxBx.Text, dEndTrim) Then
         m_dEndTrim = dEndTrim
         WritePrivateProfileString(S_FRAME, K_ENDTRIM, DoubleToString(dEndTrim, 3), m_MainWindow.GetIniFile())
      End If
      ' Ricalcolo lavorazioni
      AddFrameMachinings(m_dStartTrim, m_dEndTrim)
      ' Aggiorno visualizzazione
      EgtDraw()
   End Sub

   Private Sub OthSide_Click(sender As Object, e As EventArgs) Handles OthSideChBx.Click
      If OthSideChBx.IsChecked() Then
         m_bOtherSide = True
      else
         m_bOtherSide = False
      End If
      WritePrivateProfileString(S_FRAME, K_OTHERSIDE, If( m_bOtherSide, "1", "0"), m_MainWindow.GetIniFile())
      ' Recupero il pezzo
      Dim nPartId As Integer = EgtGetFirstPartInRawPart( EgtGetFirstRawPart())
      ' Verifico se cornice con linea guida
      Dim nCurrAx As Integer = 0
      EgtGetInfo( nPartId, INFO_FRAME_DIR, nCurrAx)
      If nCurrAx <> 3 Then Return
      ' Recupero layer e curva della sezione
      Dim nSectLayId As Integer = EgtGetFirstNameInGroup(nPartId, NAME_SECT)
      Dim nSectId As Integer = EgtGetFirstInGroup(nSectLayId)
      If nSectId = GDB_ID.NULL Then Return
      ' Recupero layer e curva della guida
      Dim nGuideLayId As Integer = EgtGetFirstNameInGroup(nPartId, NAME_GUIDE)
      Dim nGuideId As Integer = EgtGetFirstInGroup(nGuideLayId)
      If nGuideId = GDB_ID.NULL Then Return
      ' Verifico che la guida sia una linea
      Dim ptGdStart As Point3d : EgtStartPoint( nGuideId, GDB_ID.ROOT, ptGdStart)
      Dim ptGdMid As Point3d : EgtMidPoint( nGuideId, GDB_ID.ROOT, ptGdMid)
      Dim ptGdEnd As Point3d : EgtEndPoint( nGuideId, GDB_ID.ROOT, ptGdEnd)
      Dim vtGdDir As new Vector3d( ptGdEnd - ptGdStart)
      If Not vtGdDir.Normalize() then return
      Dim ptGdOn As new Point3d( ptGdStart + ( ptGdMid - ptGdStart) * vtGdDir * vtGdDir)
      If Point3d.Dist( ptGdMid, ptGdOn) > 10 * EPS_SMALL Then Return
      ' Sposto e inverto opportunamente
      Dim vtMove1 As New Vector3d(ptGdEnd - ptGdStart)
      EgtMove(nGuideLayId, vtMove1, GDB_RT.GLOB)
      EgtMirror(nGuideId, ptGdEnd, vtGdDir, GDB_RT.GLOB)
      EgtRotate(nSectLayId, ptGdStart, Vector3d.Z_AX, 180, GDB_RT.GLOB)
      EgtMove(nSectLayId, vtMove1, GDB_RT.GLOB)
      EgtMirror(nSectId, Point3d.ORIG, Vector3d.X_AX)
      ' Salvo il nuovo stato di inversione
      Dim bOthSide As Boolean = False
      EgtGetInfo( nPartId, INFO_FRAME_OTHSIDE, bOthSide)
      bOthSide = Not bOthSide
      If bOthSide Then
         EgtSetInfo( nPartId, INFO_FRAME_OTHSIDE, True)
      Else
         EgtRemoveInfo( nPartId, INFO_FRAME_OTHSIDE)
      End If
      ' Ricalcolo lavorazioni
      AddFrameMachinings(m_dStartTrim, m_dEndTrim)
      ' Aggiorno visualizzazione
      EgtDraw()
   End Sub

   Friend Sub ResetOthSide()
      m_bOtherSide = False
      OthSideChBx.IsChecked = False
      WritePrivateProfileString(S_FRAME, K_OTHERSIDE, "0", m_MainWindow.GetIniFile())
   End Sub

End Class
