Imports EgtUILib

Public Class SideAngleUC
   ' NOTA: gli oggetti AngleTxBx e HeelTxBx ora sono usate come caselle di testo indipendentemente dal nome sia in SideAngle che in Drip/Engrave

   Public Enum ModeOpt As Integer
      SIDEANGLE = 0
      DRIP = 1
      ENGRAVE = 2
   End Enum
   ' Variabile che indica se sono in sideangle o drip
   Friend m_Mode As ModeOpt

   ' Riferimento alla MainWindow
   Private m_MainWindow As MainWindow = DirectCast(Application.Current.MainWindow, MainWindow)
   ' Riferimento alla pagina che ha aperto SideAngleUC
   Private m_CallingPage As MainWindow.Pages

   ' Gestione pagine
   Private Const MAX_LINES As Integer = 10
   Private m_nCurrPage As Integer = 1
   Private m_nCount As Integer = 0
   Private m_nShow As Integer = 0

   ' Massimo angolo di lato ammesso
   Private Const STD_MAXSIDEANG As Double = 50.0
   Private Const MAX_MAXSIDEANG As Double = 75.0
   Private m_dMaxSideAng As Double = STD_MAXSIDEANG

   ' Lista di tutte le entità inclinabili presenti nel progetto
   Friend m_SideAngleEntityList As New List(Of SideAngleEntity)
   Friend m_DripEntityList As New List(Of DripEntity)
   Friend m_dDripOffset As Double = 10
   Friend m_dDripOffset2 As Double = 0
   Friend m_nEngrNbr2 As Integer = 1
   Friend m_dDripDepth As Double = 10
   Friend m_dDripShort As Double = 0

   Private CurrEntityDrip As DripEntity

   ' carico la pagina
   Private Sub SideAngleUC_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
      ' Imposto riferimenti ad altre pagine: definisco la pagina attiva
      m_CallingPage = m_MainWindow.m_ActivePage

      ' Leggo da Ini il massimo angolo di fianco ammesso
      m_dMaxSideAng = GetPrivateProfileDouble(S_SIDES, K_MAXSIDEANGLE, STD_MAXSIDEANG, m_MainWindow.GetIniFile())
      If m_dMaxSideAng > MAX_MAXSIDEANG Then m_dMaxSideAng = MAX_MAXSIDEANG

      ' Imposto messaggi a fondo pagina
      If m_Mode <> ModeOpt.SIDEANGLE Then
         Parameter1TxBl.Text = EgtMsg(MSG_IMPORTPAGEUC + 10)         ' Offset
         Parameter2TxBl.Text = EgtMsg(MSG_IMPORTPAGEUC + 16)         ' Offset2
         Parameter3TxBl.Text = EgtMsg(MSG_IMPORTPAGEUC + 11)         ' Affondamento
         Parameter4TxBl.Text = EgtMsg(MSG_IMPORTPAGEUC + 12)         ' Accorciamento
      End If

      If m_CallingPage = MainWindow.Pages.Draw Then
         ' Imposto questa come pagina correntemente visualizzata nella drawpage
         m_MainWindow.m_DrawPageUC.m_ActiveComponentPage = DrawPageUC.Pages.SideAngle
         ' Imposto contesto corrente
         EgtSetCurrentContext(m_MainWindow.m_DrawPageUC.DrawScene.GetCtx())
      ElseIf m_CallingPage = MainWindow.Pages.Import Then
         ' Imposto contesto corrente
         EgtSetCurrentContext(m_MainWindow.m_ImportPageUC.ImportScene.GetCtx())
      End If

      ' Inizializzo: Spengo tutti i CheckBox attivi
      DeleteSideAngle()
      m_nCurrPage = 1
      ' numero di elemnti presenti nella lista SideAngle/DripEntity
      m_nCount = 0
      ' numero di righe rese disponibili nella pagina -> m_nShow = min(m_nCount, MAX_LINE)
      m_nShow = 0

      ' Inizializzo lati per angoli e per gocciolatoi (ne compilo la lista e aggiungo la scritta nel disegno)
      InitSides()
      '' Aggiorno testi nel disegno e creo i gocciolatoi
      'RefreshSideAngleText()
      ' Aggiorno check e valori
      RefreshCheckAndValue()
      ' Aggiorno testi nel disegno e creo i gocciolatoi
      RefreshSideAngleText()

      ' Gestisco visualizzazione di tutti i parametri
      If m_Mode = ModeOpt.SIDEANGLE Then
         ' nascondo tutti i CheckBox (ho bisogno solle delle caselle di campo)
         For Index As Integer = 1 To MAX_LINES
            GetChBxFromIndex(Index).Visibility = Windows.Visibility.Collapsed
            GetAngleTxBxFromIndex(Index).Visibility = Windows.Visibility.Visible
            GetHeelTxBxFromIndex(Index).Visibility = Windows.Visibility.Visible
         Next
         '------------> Nascondo tutti i parametri presenti a fine pagina
         ' Offset
         Parameter1TxBl.Visibility = Windows.Visibility.Hidden
         Parameter1TxBx.Visibility = Windows.Visibility.Hidden
         ' Offset2
         Parameter2TxBl.Visibility = Windows.Visibility.Hidden
         Parameter2TxBx.Visibility = Windows.Visibility.Hidden
         Parameter2aTxBx.Visibility = Windows.Visibility.Hidden
         Parameter2bTxBx.Visibility = Windows.Visibility.Hidden
         ' Affondamento
         Parameter3TxBl.Visibility = Windows.Visibility.Hidden
         Parameter3TxBx.Visibility = Windows.Visibility.Hidden
         ' Accorciamento
         Parameter4TxBl.Visibility = Windows.Visibility.Hidden
         Parameter4TxBx.Visibility = Windows.Visibility.Hidden
      Else
         ' se aggiungo gli ENGRAVE e i DRIP

         ' SideAngleBl.Visibility = Windows.Visibility.Collapsed
         ' HeelBl.Visibility = Windows.Visibility.Collapsed

         For Index As Integer = 1 To MAX_LINES
            GetChBxFromIndex(Index).Visibility = Windows.Visibility.Visible
            GetAngleTxBxFromIndex(Index).Visibility = Windows.Visibility.Visible
            GetHeelTxBxFromIndex(Index).Visibility = Windows.Visibility.Visible
         Next
         ' Offset
         Parameter1TxBl.Visibility = Windows.Visibility.Visible
         Parameter1TxBx.Visibility = Windows.Visibility.Visible
         Parameter2TxBl.Visibility = Windows.Visibility.Visible
         ' Offset2
         If m_Mode <> ModeOpt.ENGRAVE Then
            Parameter2TxBx.Visibility = Windows.Visibility.Visible
            Parameter2aTxBx.Visibility = Windows.Visibility.Hidden
            Parameter2bTxBx.Visibility = Windows.Visibility.Hidden
         Else
            Parameter2TxBx.Visibility = Windows.Visibility.Hidden
            Parameter2aTxBx.Visibility = Windows.Visibility.Visible
            Parameter2bTxBx.Visibility = Windows.Visibility.Visible
         End If
         ' Affondamento
         Parameter3TxBl.Visibility = Windows.Visibility.Visible
         Parameter3TxBx.Visibility = Windows.Visibility.Visible
         ' Accorciamento
         Parameter4TxBl.Visibility = Windows.Visibility.Hidden
         Parameter4TxBx.Visibility = Windows.Visibility.Hidden
      End If

      ' Gestisco Checkbox e nomi in base al numero di lati inclinabili
      TxBlChBxView()

      ' Aggiorno valori
      If m_Mode = ModeOpt.DRIP Then
         m_dDripOffset = GetPrivateProfileDouble( S_SIDES, K_DRIPOFFSET, 20, m_MainWindow.GetIniFile())
         m_dDripOffset2 = GetPrivateProfileDouble( S_SIDES, K_DRIPOFFSET2, 0, m_MainWindow.GetIniFile())
         m_dDripDepth = GetPrivateProfileDouble( S_SIDES, K_DRIPDEPTH, 10, m_MainWindow.GetIniFile())
         m_dDripShort = GetPrivateProfileDouble( S_SIDES, K_DRIPSHORT, 0, m_MainWindow.GetIniFile())
         Parameter1TxBx.Text = LenToString( m_dDripOffset, 3)
         Parameter2TxBx.Text = LenToString( m_dDripOffset2, 3)
         Parameter3TxBx.Text = LenToString( m_dDripDepth, 3)
         Parameter4TxBx.Text = LenToString( m_dDripShort, 3)
      ElseIf m_Mode = ModeOpt.ENGRAVE Then
         m_dDripOffset = GetPrivateProfileDouble( S_SIDES, K_ENGRAVEOFFSET, 20, m_MainWindow.GetIniFile())
         m_nEngrNbr2 = GetPrivateProfileInt( S_SIDES, K_ENGRAVENUMBER2, 1, m_MainWindow.GetIniFile())
         m_dDripOffset2 = GetPrivateProfileDouble( S_SIDES, K_ENGRAVEOFFSET2, 0, m_MainWindow.GetIniFile())
         m_dDripDepth = GetPrivateProfileDouble( S_SIDES, K_ENGRAVEDEPTH, 10, m_MainWindow.GetIniFile())
         m_dDripShort = GetPrivateProfileDouble( S_SIDES, K_ENGRAVESHORT, 0, m_MainWindow.GetIniFile())
         Parameter1TxBx.Text = LenToString( m_dDripOffset, 3)
         Parameter2aTxBx.Text = m_nEngrNbr2.ToString()
         Parameter2bTxBx.Text = LenToString( m_dDripOffset2, 3)
         Parameter3TxBx.Text = LenToString( m_dDripDepth, 3)
         Parameter4TxBx.Text = LenToString( m_dDripShort, 3)
      End If

      ' Aggiorno visualizzazione
      If m_CallingPage = MainWindow.Pages.Draw Then
         EgtZoom(ZM.ALL)
      Else
         EgtDraw()
      End If
   End Sub

   ' verfico di poter inserire i lati inclinati e le incisioni
   Private Sub InitSides()
      Dim PartId As Integer = GDB_ID.NULL
      ' Id del loop eseterno
      Dim LoopId As Integer = GDB_ID.NULL
      If m_CallingPage = MainWindow.Pages.Draw Then
         ' Imposto contesto corrente
         EgtSetCurrentContext(m_MainWindow.m_DrawPageUC.DrawScene.GetCtx())
         ' Ricavo nome primo pezzo e lo sistemo
         If m_Mode = ModeOpt.ENGRAVE And m_MainWindow.m_DrawPageUC.SelectedLayer = GDB_ID.NULL Then
            PartId = EgtGetFirstPart()
            m_MainWindow.m_DrawPageUC.SetCurrLayer(EgtGetFirstNameInGroup(PartId, NAME_OUTLOOP))
         End If
         PartId = If(m_MainWindow.m_DrawPageUC.SelectedLayer <> GDB_ID.NULL, EgtGetFirstPart(), GDB_ID.NULL)
         ' Recupero nome layer con geometria di contorno (esterno o interno) del pezzo
         LoopId = m_MainWindow.m_DrawPageUC.SelectedLayer
      Else
         ' Imposto contesto corrente
         EgtSetCurrentContext(m_MainWindow.m_ImportPageUC.ImportScene.GetCtx())
         ' Recupero nome pezzo selezionato
         PartId = m_MainWindow.m_ImportPageUC.SelectedPart
         ' Recupero nome layer con geometria di contorno (esterno o interno) del pezzo
         LoopId = m_MainWindow.m_ImportPageUC.SelectedLayer
      End If

      '-----------------> Determino se loop esterno o interno
      Dim sLoopName As String = ""
      Dim bOutLoop As Boolean = (EgtGetName(LoopId, sLoopName) AndAlso sLoopName = NAME_OUTLOOP)
      ' Calcolo dimensione ingombro Loop
      Dim ptMin, ptMax As Point3d
      EgtGetBBoxGlob(LoopId, GDB_BB.STANDARD, ptMin, ptMax)
      Dim dBBoxRad As Double = 0.5 * Point3d.DistXY(ptMin, ptMax)
      ' Creo layer per testi se non esiste già
      Dim TextLayer As Integer = EgtGetFirstNameInGroup(PartId, SIDE_ANGLE_LAYER)
      If TextLayer = GDB_ID.NULL And PartId <> GDB_ID.NULL Then
         TextLayer = EgtCreateGroup(PartId)
         EgtSetName(TextLayer, SIDE_ANGLE_LAYER)
         EgtSetColor(TextLayer, New Color3d(0, 0, 0))
      End If

      '-----------------> Recupero Id della curva del Loop Esterno
      Dim PrevLine As Integer = EgtGetLastInGroup(LoopId)
      Dim CurrLine As Integer = EgtGetFirstInGroup(LoopId)
      ' Creo indice per numerare le entità in ImportPage
      Dim nEntityIndex As Integer = 1
      Dim nOtherIndex As Integer = 1
      ' Ciclo che verifica se possibile inclinare la curva corrente o inserire un gocciolatoio
      While CurrLine <> GDB_ID.NULL
         Dim NextLine As Integer = EgtGetNext(CurrLine)
         If NextLine = GDB_ID.NULL Then NextLine = EgtGetFirstInGroup(LoopId)
         If m_Mode = ModeOpt.SIDEANGLE Then
            If SideAngle.VerifySideAnglePossible(PrevLine, CurrLine, NextLine, bOutLoop) Then
               ' Aggiungo il lato alla lista di quelli inclinabili e ne azzero l'inclinazione
               AddSideAngle(CurrLine, TextLayer, dBBoxRad, nEntityIndex)
               nEntityIndex += 1
            Else
               EgtSetName(CurrLine, "B" & nOtherIndex.ToString())
               nOtherIndex += 1
            End If
         Else
            If VerifyIsSideDripPossible(PrevLine, CurrLine, NextLine) Then
               ' Aggiungo il lato alla lista di quelli su cui è possibile mettere il gocciolatoio
               AddDripSide(CurrLine, TextLayer, dBBoxRad, nEntityIndex)
               nEntityIndex += 1
            Else
               EgtSetName(CurrLine, "B" & nOtherIndex.ToString())
               nOtherIndex += 1
            End If
         End If
         PrevLine = CurrLine
         CurrLine = EgtGetNext(CurrLine)
      End While

      '-----------------> Aggiorno numero di lati carciati
      If m_Mode = ModeOpt.SIDEANGLE Then
         m_nCount = m_SideAngleEntityList.Count()
      Else
         m_nCount = m_DripEntityList.Count()
      End If
      ' Aggiorno numero item visualizzati nella pagina iniziale
      m_nShow = Math.Min(m_nCount, MAX_LINES)

      ' Se non ci sono lati su cui operare, messaggio utente
      If LoopId <> GDB_ID.NULL Then
         If m_nCount = 0 Then
            If m_CallingPage = MainWindow.Pages.Draw Then
               m_MainWindow.m_DrawPageUC.MessageTxBx.Text = EgtMsg(MSG_DRAWPAGEUC + 7)   ' Non ci sono lati modificabili
               m_MainWindow.m_DrawPageUC.MessageBrd.Background = Application.Current.FindResource("OmagCut_Yellow")
            Else
               m_MainWindow.m_ImportPageUC.MessageTxBx.Text = EgtMsg(MSG_DRAWPAGEUC + 7)   ' Non ci sono lati modificabili
               m_MainWindow.m_ImportPageUC.MessageBrd.Background = Application.Current.FindResource("OmagCut_Yellow")
            End If
         Else
            If m_CallingPage = MainWindow.Pages.Draw Then
               m_MainWindow.m_DrawPageUC.MessageTxBx.Text = ""
               m_MainWindow.m_DrawPageUC.MessageBrd.Background = Brushes.Transparent
            Else
               m_MainWindow.m_ImportPageUC.MessageTxBx.Text = ""
               m_MainWindow.m_ImportPageUC.MessageBrd.Background = Brushes.Transparent
            End If
         End If
      End If
   End Sub

   ' Imposto la visibilità degli oggetti nella pagina: qui eseguo l'impaginazione
   Private Sub TxBlChBxView()
      ' Attualmente il vaore m_nCount è inizializzato ad "1"..
      ' Bottoni Prev Next
      If m_nCount <= MAX_LINES Then
         PrevBtn.Visibility= Windows.Visibility.Hidden
         NextBtn.Visibility= Windows.Visibility.Hidden
      Else
         Grid.SetRow(PrevBtn, MAX_LINES - m_nShow)
         PrevBtn.Visibility = Windows.Visibility.Visible
         PrevBtn.IsEnabled = (m_nCurrPage > 1)
         Grid.SetRow(NextBtn, MAX_LINES - m_nShow)
         NextBtn.Visibility = Windows.Visibility.Visible
         NextBtn.IsEnabled = (m_nCount > m_nCurrPage * MAX_LINES)
      End If

      ' Intestazione per angoli di lato
      If m_Mode = ModeOpt.SIDEANGLE Then
         If m_nCount = 0 Then
            SideAngleBl.Visibility = Windows.Visibility.Hidden
            HeelBl.Visibility = Windows.Visibility.Hidden
         Else
            ' definisco il posizionamento del nome (A;T/Start;End) delle colonne all'interno della grigia
            Grid.SetRow(SideAngleBl, MAX_LINES - m_nShow)
            SideAngleBl.Text = EgtMsg(91653)  ' A°
            SideAngleBl.Visibility = Windows.Visibility.Visible
            Grid.SetRow(HeelBl, MAX_LINES - m_nShow)
            HeelBl.Text = EgtMsg(91654)  ' T
            HeelBl.Visibility = Windows.Visibility.Visible
         End If
      Else
         If m_nCount = 0 Then
            SideAngleBl.Visibility = Windows.Visibility.Hidden
            HeelBl.Visibility = Windows.Visibility.Hidden
         Else
            ' definisco il posizionamento del nome (A;T/Start;End) delle colonne all'interno della grigia
            Grid.SetRow(SideAngleBl, MAX_LINES - m_nShow)
            SideAngleBl.Text = EgtMsg(91655)  ' Start
            SideAngleBl.Visibility = Windows.Visibility.Visible
            Grid.SetRow(HeelBl, MAX_LINES - m_nShow)
            HeelBl.Text = EgtMsg(91656)  ' End
            HeelBl.Visibility = Windows.Visibility.Visible
         End If
      End If

      ' Lati visibili
      For nI As Integer = 1 To m_nShow
         Dim Index As Integer = MAX_LINES - m_nShow + nI
         If m_Mode = ModeOpt.SIDEANGLE Then
            GetAngleTxBxFromIndex(Index).Visibility = Windows.Visibility.Visible
            GetHeelTxBxFromIndex(Index).Visibility = Windows.Visibility.Visible
         Else
            GetChBxFromIndex(Index).Visibility = Windows.Visibility.Visible
            ' aggiungo i campi per allungare e accorciare i lati
            GetAngleTxBxFromIndex(Index).Visibility = Windows.Visibility.Visible
            GetHeelTxBxFromIndex(Index).Visibility = Windows.Visibility.Visible
            GetPrivateProfileDouble(S_SIDES, K_ENGRAVESHORT, 0, m_MainWindow.GetIniFile())
            If m_Mode = ModeOpt.ENGRAVE Then
               GetAngleTxBxFromIndex(Index).Text = GetPrivateProfileDouble(S_SIDES, K_ENGRAVESHORT & "A" & nI.ToString & "_Start", 0, m_MainWindow.GetIniFile())
               GetHeelTxBxFromIndex(Index).Text = GetPrivateProfileDouble(S_SIDES, K_ENGRAVESHORT & "A" & nI.ToString & "_End", 0, m_MainWindow.GetIniFile())
            Else
               GetAngleTxBxFromIndex(Index).Text = GetPrivateProfileDouble(S_SIDES, K_DRIPSHORT & "A" & nI.ToString & "_Start", 0, m_MainWindow.GetIniFile())
               GetHeelTxBxFromIndex(Index).Text = GetPrivateProfileDouble(S_SIDES, K_DRIPSHORT & "A" & nI.ToString & "_End", 0, m_MainWindow.GetIniFile())
            End If
         End If
            Dim TxBlIndex As Integer = (m_nCurrPage - 1) * MAX_LINES + nI - 1
         GetTxBlFromIndex(Index).Text = If(m_Mode = ModeOpt.SIDEANGLE,
                                           m_SideAngleEntityList(TxBlIndex).sEntityName,
                                           m_DripEntityList(TxBlIndex).sEntityName)
         GetTxBlFromIndex(Index).Visibility = Windows.Visibility.Visible
      Next
      ' Lati nascosti: nascondo i lati partendo dall'alto (se ho 4 lati la prima TextBx disponibile è la settima -> 11-4 = 7 lati nascosti) 
      For Index As Integer = 1 To MAX_LINES - m_nShow
         If m_Mode = ModeOpt.SIDEANGLE Then
            GetAngleTxBxFromIndex(Index).Visibility = Windows.Visibility.Hidden
            GetHeelTxBxFromIndex(Index).Visibility = Windows.Visibility.Hidden
         Else
            GetChBxFromIndex(Index).Visibility = Windows.Visibility.Hidden
            GetAngleTxBxFromIndex(Index).Visibility = Windows.Visibility.Hidden
            GetHeelTxBxFromIndex(Index).Visibility = Windows.Visibility.Hidden
         End If
         GetTxBlFromIndex(Index).Visibility = Windows.Visibility.Hidden
      Next
   End Sub


   '-------------> Restituisce gli oggetto della grafica assegnato l'indice
   Private Function GetChBxFromIndex(Index As Integer) As CheckBox
      Select Case Index
         Case 1
            Return A1
         Case 2
            Return A2
         Case 3
            Return A3
         Case 4
            Return A4
         Case 5
            Return A5
         Case 6
            Return A6
         Case 7
            Return A7
         Case 8
            Return A8
         Case 9
            Return A9
         Case Else
            Return A10
      End Select
   End Function

   Private Function GetAngleTxBxFromIndex(Index As Integer) As EgtWPFLib.EgtTextBox
      Select Case Index
         Case 1
            Return A1TxBx
         Case 2
            Return A2TxBx
         Case 3
            Return A3TxBx
         Case 4
            Return A4TxBx
         Case 5
            Return A5TxBx
         Case 6
            Return A6TxBx
         Case 7
            Return A7TxBx
         Case 8
            Return A8TxBx
         Case 9
            Return A9TxBx
         Case Else
            Return A10TxBx
      End Select
   End Function

   Private Function GetHeelTxBxFromIndex(Index As Integer) As EgtWPFLib.EgtTextBox
      Select Case Index
         Case 1
            Return H1TxBx
         Case 2
            Return H2TxBx
         Case 3
            Return H3TxBx
         Case 4
            Return H4TxBx
         Case 5
            Return H5TxBx
         Case 6
            Return H6TxBx
         Case 7
            Return H7TxBx
         Case 8
            Return H8TxBx
         Case 9
            Return H9TxBx
         Case Else
            Return H10TxBx
      End Select
   End Function

   Private Function GetTxBlFromIndex(Index As Integer) As TextBlock
      Select Case Index
         Case 1
            Return Entity1
         Case 2
            Return Entity2
         Case 3
            Return Entity3
         Case 4
            Return Entity4
         Case 5
            Return Entity5
         Case 6
            Return Entity6
         Case 7
            Return Entity7
         Case 8
            Return Entity8
         Case 9
            Return Entity9
         Case Else
            Return Entity10
      End Select
   End Function
   '-------------> Restituisce gli oggetto della grafica assegnato l'indice

   ' quando esco salvo nel file l'ultima configurazione per le incisioni
   Private Sub SideAngleUC_Unloaded( sender As Object, e As RoutedEventArgs) Handles Me.Unloaded
      If m_CallingPage = MainWindow.Pages.Draw Then
         ' Ricavo nome pezzo
         Dim PartId As Integer = EgtGetFirstInGroup( GDB_ID.ROOT)
         ' Svuoto layer in cui sono presenti i testi con le inclinazioni dei lati
         If m_Mode = ModeOpt.SIDEANGLE Then
            EgtEmptyGroup( EgtGetFirstNameInGroup( PartId, SIDE_ANGLE_LAYER))
         Else
            EgtEmptyGroup( EgtGetFirstNameInGroup( PartId, SIDE_ANGLE_LAYER))
         End If
      ElseIf m_CallingPage = MainWindow.Pages.Import Then
         ' Nessuna azione necessaria
      End If

      If m_Mode = ModeOpt.DRIP Then
         WritePrivateProfileString(S_SIDES, K_DRIPOFFSET, LenToString(m_dDripOffset, 3), m_MainWindow.GetIniFile())
         WritePrivateProfileString(S_SIDES, K_DRIPOFFSET2, LenToString(m_dDripOffset2, 3), m_MainWindow.GetIniFile())
         WritePrivateProfileString(S_SIDES, K_DRIPDEPTH, LenToString(m_dDripDepth, 3), m_MainWindow.GetIniFile())
         'WritePrivateProfileString( S_SIDES, K_DRIPSHORT, DoubleToString( m_dDripShort, 3), m_MainWindow.GetIniFile())
      ElseIf m_Mode = ModeOpt.ENGRAVE Then
         WritePrivateProfileString(S_SIDES, K_ENGRAVEOFFSET, LenToString(m_dDripOffset, 3), m_MainWindow.GetIniFile())
         WritePrivateProfileString( S_SIDES, K_ENGRAVENUMBER2, m_nEngrNbr2.ToString(), m_MainWindow.GetIniFile())
         WritePrivateProfileString(S_SIDES, K_ENGRAVEOFFSET2, LenToString(m_dDripOffset2, 3), m_MainWindow.GetIniFile())
         WritePrivateProfileString(S_SIDES, K_ENGRAVEDEPTH, LenToString(m_dDripDepth, 3), m_MainWindow.GetIniFile())
         'WritePrivateProfileString( S_SIDES, K_ENGRAVESHORT, DoubleToString( m_dDripShort, 3), m_MainWindow.GetIniFile())
      End If

      EgtDraw()
   End Sub


   ' aggiunge il messaggio nel disegno, se DripGeom creo la geometria
   Private Sub RefreshSideAngleText()
      Dim PartId As Integer = GDB_ID.NULL
      Dim LoopId As Integer = GDB_ID.NULL
      If m_CallingPage = MainWindow.Pages.Draw Then
         ' Imposto contesto corrente
         EgtSetCurrentContext(m_MainWindow.m_DrawPageUC.DrawScene.GetCtx())
         PartId = If(m_MainWindow.m_DrawPageUC.SelectedLayer <> GDB_ID.NULL, EgtGetFirstPart(), GDB_ID.NULL)
         ' Recupero nome layer con geometria di contorno (esterno o interno) del pezzo
         LoopId = m_MainWindow.m_DrawPageUC.SelectedLayer
         ElseIf m_CallingPage = MainWindow.Pages.Import Then
         ' Imposto contesto corrente
         EgtSetCurrentContext(m_MainWindow.m_ImportPageUC.ImportScene.GetCtx())
         ' Recupero nome pezzo
         PartId = m_MainWindow.m_ImportPageUC.SelectedPart
         ' Recupero nome layer con geometria di contorno (esterno o interno) del pezzo
         LoopId = m_MainWindow.m_ImportPageUC.SelectedLayer
      End If

      ' Calcolo dimensione ingombro Loop
      Dim ptMin, ptMax As Point3d
      EgtGetBBoxGlob(LoopId, GDB_BB.STANDARD, ptMin, ptMax)
      Dim dBBoxRad As Double = 0.5 * Point3d.DistXY(ptMin, ptMax)

      ' Preparo layer con testi inclinazioni (svuotandolo o creandolo)
      Dim TextLayer As Integer = EgtGetFirstNameInGroup(PartId, SIDE_ANGLE_LAYER)
      If TextLayer <> GDB_ID.NULL Then
         EgtEmptyGroup(TextLayer)
      ElseIf PartId <> GDB_ID.NULL Then
         TextLayer = EgtCreateGroup(PartId)
         EgtSetName(TextLayer, SIDE_ANGLE_LAYER)
         EgtSetColor(TextLayer, New Color3d(0, 0, 0))
      End If

      ' Se modalità angoli di inclinazione...
      If m_Mode = ModeOpt.SIDEANGLE Then
         ' Per ogni entità (della lista inizializzata), creo testo con nome e angolo di inclinazione
         For Each Entity As SideAngleEntity In m_SideAngleEntityList
            Dim sText As String = Entity.sEntityName & " = " & DoubleToString(Entity.dSideAngle, 2) & "°"
            If Entity.dSideHeel > 10 * EPS_SMALL Then sText += "; " & LenToString(Entity.dSideHeel, 2)
            SideAngle.AddTextToLine(sText, Entity.nTextId, Entity.nGeomId, 20, dBBoxRad, True)
         Next
         ' Altrimenti modalità gocciolatoio
      Else
         ' Per ogni entità creo testo con nome
         For Each Entity As DripEntity In m_DripEntityList
            SideAngle.AddTextToLine(Entity.sEntityName, Entity.nTextId, Entity.nGeomId, 20, dBBoxRad, True)
         Next
         ' Creo le geometrie dei gocciolatoi
         CreateDripGeom(PartId)
      End If
      ' Aggiorno visualizzazione
      EgtDraw()
   End Sub

   ' refresh dei checkbox e della caselle di testo per tutte le entità presenti nelle liste SideAngle/DripEntity
   Private Sub RefreshCheckAndValue()
      If m_Mode = ModeOpt.SIDEANGLE Then
         For nIndex As Integer = 1 To m_nCount
            Dim Entity As SideAngleEntity = m_SideAngleEntityList(nIndex - 1)
            ' Creo testo con angolo di inclinazione e dimensione tallone
            If nIndex < (m_nCurrPage - 1) * MAX_LINES Or nIndex > m_nCurrPage * MAX_LINES Then Continue For
            ' recupero l'inidce degli oggetti della grafica
            Dim nTxBxIndex As Integer = nIndex - (m_nCurrPage - 1) * MAX_LINES + MAX_LINES - m_nShow
            ' aggiorno i valore delle caselle di testo per le entità caricate
            GetAngleTxBxFromIndex(nTxBxIndex).Text = DoubleToString(Entity.dSideAngle, 1)
            GetHeelTxBxFromIndex(nTxBxIndex).Text = LenToString(Entity.dSideHeel, 1)
         Next
      Else
         For nIndex As Integer = 1 To m_nCount
            Dim Entity As DripEntity = m_DripEntityList(nIndex - 1)
            ' Imposto check box (se sono stati definiti il numero corretto di CheckBox
            If nIndex < ( m_nCurrPage - 1) * MAX_LINES Or nIndex > m_nCurrPage * MAX_LINES Then Continue For
            Dim nChIndex As Integer = nIndex - (m_nCurrPage - 1) * MAX_LINES + MAX_LINES - m_nShow
            ' verifico se l'entità ha un gocciolatoio
            GetChBxFromIndex(nChIndex).IsChecked = Entity.bHaveDrip
            ' aggiorno i valore delle caselle di testo per le entità caricate (Start/End)
            If m_Mode = ModeOpt.ENGRAVE Then
               Dim dVal As Double = 0
               If StringToLen(GetPrivateProfileDouble(S_SIDES, K_ENGRAVESHORT & "A" & nIndex.ToString & "_Start", 0, m_MainWindow.GetIniFile()), dVal) Then
                  Entity.dShortStart = dVal
               End If
               If StringToLen(GetPrivateProfileDouble(S_SIDES, K_ENGRAVESHORT & "A" & nIndex.ToString & "_End", 0, m_MainWindow.GetIniFile()), dVal) Then
                  Entity.dShortEnd = dVal
               End If
            Else
               'GetAngleTxBxFromIndex(Index).Text = GetPrivateProfileDouble(S_SIDES, K_DRIPSHORT & "A" & nI.ToString & "_Start", 0, m_MainWindow.GetIniFile())
               'GetHeelTxBxFromIndex(Index).Text = GetPrivateProfileDouble(S_SIDES, K_DRIPSHORT & "A" & nI.ToString & "_End", 0, m_MainWindow.GetIniFile())
            End If
            GetAngleTxBxFromIndex(nChIndex).Text = LenToString(Entity.dShortStart, 1)
            GetHeelTxBxFromIndex(nChIndex).Text = LenToString(Entity.dShortEnd, 1)
         Next
      End If
   End Sub

   ' Funzione che verifica se alla linea corrente è associabile un canalino
   Private Function VerifyIsSideDripPossible(LastLine As Integer, CurrLine As Integer, NextLine As Integer) As Boolean
      ' Verifico se CurrLine è una linea
      If EgtGetType(CurrLine) <> GDB_TY.CRV_LINE Then
         Return False
      End If
      Return True
   End Function

   ' Funzione che gestisce le operazioni sull'entità da inclinare
   Private Sub AddSideAngle(CurrLine As Integer, TextLayer As Integer, dBBoxRad As Double, nEntityIndex As Integer)
      ' Imposto nome del lato
      EgtSetName(CurrLine, "A" & nEntityIndex.ToString())
      ' Ricavo angolo dell'entità
      Dim dSideAngleVal As Double
      If Not EgtGetInfo(CurrLine, INFO_SIDE_ANGLE, dSideAngleVal) Then dSideAngleVal = 0
      ' Ricavo tallone dell'entità
      Dim dSideHeelVal As Double
      If Not EgtGetInfo(CurrLine, INFO_HEEL, dSideHeelVal) Then dSideHeelVal = 0
      ' Aggiungo entità all'elenco di quelle inclinabili
      Dim sEntityName As String = String.Empty
      EgtGetName(CurrLine, sEntityName)
      m_SideAngleEntityList.Add(New SideAngleEntity(CurrLine, sEntityName, TextLayer, dSideAngleVal, dSideHeelVal))
      ' Creo testo con angolo di inclinazione ed eventuale tallone
      Dim sText As String = sEntityName & " = " & DoubleToString(dSideAngleVal, 2) & "°"
      If dSideHeelVal > 10 * EPS_SMALL Then sText += "; " & LenToString(dSideHeelVal, 2)
      SideAngle.AddTextToLine(sText, TextLayer, CurrLine, 20, dBBoxRad, True)
   End Sub

   ' Funzione che gestisce le operazioni sull'entità con gocciolatoio
   Private Sub AddDripSide(CurrLine As Integer, TextLayer As Integer, dBBoxRad As Double, nEntityIndex As Integer)
      ' Imposto nome del lato
      EgtSetName(CurrLine, "A" & nEntityIndex.ToString())
      ' Ricavo info dell'entità
      Dim bHaveDripVal As Boolean
      If Not EgtGetInfo(CurrLine, INFO_HAVE_DRIP, bHaveDripVal) Then bHaveDripVal = False
      ' Aggiungo entità all'elenco di quelle che possono avere il gocciolatoio
      Dim sEntityName As String = String.Empty
      EgtGetName(CurrLine, sEntityName)
      m_DripEntityList.Add(New DripEntity(CurrLine, sEntityName, TextLayer, bHaveDripVal))
      ' Creo testo con nome lato
      SideAngle.AddTextToLine(sEntityName, TextLayer, CurrLine, 20, dBBoxRad, True)
   End Sub

   ' Funzione che crea le geometrie dei gocciolatoi
   Friend Sub CreateDripGeomOLD(nPartId As Integer)
      ' Recupero Id layer di contorno esterno
      Dim nOutLoopId = EgtGetFirstNameInGroup(nPartId, NAME_OUTLOOP)
      ' Preparo layer con geometria gocciolatoi (svuotandolo o creandolo)
      Dim DripName As String = If(m_Mode = ModeOpt.DRIP, NAME_DRIPCUT, NAME_ONPATH)
      Dim DripLayer As Integer = EgtGetFirstNameInGroup(nPartId, DripName)
      If DripLayer <> GDB_ID.NULL Then
         EgtEmptyGroup(DripLayer)
      Else
         DripLayer = EgtCreateGroup(nPartId)
         EgtSetName(DripLayer, DripName)
      End If
      ' Per ogni entità con gocciolatoio, ne inserisco una copia nel layer
      Dim vSelId As New List(Of Integer)
      For Each Entity As DripEntity In m_DripEntityList
         If Entity.bHaveDrip Then
            Dim nSouId As Integer = EgtGetFirstNameInGroup(nOutLoopId, Entity.sEntityName)
            Dim nNewId As Integer = EgtCopyGlob(nSouId, DripLayer)
            EgtSetName(nNewId, Entity.sEntityName)
            vSelId.Add(nNewId)
         End If
      Next
      ' Eseguo eventuali allungamenti iniziali e finali
      Dim nCrvId As Integer = EgtGetFirstInGroup(DripLayer)
      While nCrvId <> GDB_ID.NULL
         If m_dDripShort < -EPS_SMALL Then
            EgtExtendCurveEndByLen(nCrvId, -m_dDripShort)
            EgtExtendCurveStartByLen(nCrvId, -m_dDripShort)
         End If
         nCrvId = EgtGetNext(nCrvId)
      End While
      ' Concateno le curve
      EgtCreateCurveCompoByReorder(DripLayer, vSelId.Count(), vSelId.ToArray(), New Point3d(), True)
      ' Eseguo eventuali accorciamenti iniziali e finali
      nCrvId = EgtGetFirstInGroup(DripLayer)
      While nCrvId <> GDB_ID.NULL
         If m_dDripShort > EPS_SMALL AndAlso Not EgtCurveIsClosed(nCrvId) Then
            Dim dLen As Double
            EgtCurveLength(nCrvId, dLen)
            EgtTrimCurveEndAtLen(nCrvId, dLen - m_dDripShort)
            EgtTrimCurveStartAtLen(nCrvId, m_dDripShort)
         End If
         nCrvId = EgtGetNext(nCrvId)
      End While
      ' Eseguo offset dei risultati
      nCrvId = EgtGetFirstInGroup(DripLayer)
      While nCrvId <> GDB_ID.NULL
         EgtOffsetCurve(nCrvId, -m_dDripOffset, OFF_TYPE.EXTEND)
         nCrvId = EgtGetNext(nCrvId)
      End While
      ' Eventuali curve aggiuntive con offset2
      If m_nEngrNbr2 > 0 And m_dDripOffset2 > EPS_SMALL Then
         nCrvId = EgtGetFirstInGroup(DripLayer)
         While nCrvId <> GDB_ID.NULL
            Dim nNextCrvId As Integer = EgtGetNext(nCrvId)
            For i As Integer = 1 To m_nEngrNbr2
               Dim nNewId As Integer = EgtCopy(nCrvId, nCrvId, GDB_POS.AFTER)
               EgtOffsetCurve(nNewId, -i * m_dDripOffset2, OFF_TYPE.EXTEND)
            Next
            nCrvId = nNextCrvId
         End While
      End If
      If m_Mode = ModeOpt.DRIP Then
         ' Esplodo nelle curve componenti
         nCrvId = EgtGetFirstInGroup(DripLayer)
         While nCrvId <> GDB_ID.NULL
            Dim nNextCrvId = EgtGetNext(nCrvId)
            Dim nCount As Integer
            EgtExplodeCurveCompo(nCrvId, nCount)
            nCrvId = nNextCrvId
         End While
         ' Assegno colore e attributi
         nCrvId = EgtGetFirstInGroup(DripLayer)
         While nCrvId <> GDB_ID.NULL
            EgtSetColor(nCrvId, COL_MCH_DRIPCUT())
            EgtSetInfo(nCrvId, INFO_DEPTH, m_dDripDepth)
            If m_dDripShort > EPS_SMALL Then EgtSetInfo(nCrvId, INFO_STRICT, "1")
            nCrvId = EgtGetNext(nCrvId)
         End While
      Else
         ' Assegno colore e attributi
         nCrvId = EgtGetFirstInGroup(DripLayer)
         While nCrvId <> GDB_ID.NULL
            EgtSetColor(nCrvId, COL_MCH_DRIPCUT())
            EgtSetInfo(nCrvId, INFO_DEPTH, m_dDripDepth)
            EgtSetInfo(nCrvId, INFO_STRICT, If(m_dDripShort > EPS_SMALL, "3", "0"))
            nCrvId = EgtGetNext(nCrvId)
         End While
      End If
   End Sub

   ' nuova funzione per gestire l'accorcaimento dei segmenti
   Friend Sub CreateDripGeom(nPartId As Integer)
      ' Recupero Id layer di contorno esterno
      Dim nOutLoopId = EgtGetFirstNameInGroup(nPartId, NAME_OUTLOOP)
      ' Preparo layer con geometria gocciolatoi (svuotandolo o creandolo)
      Dim DripName As String = If(m_Mode = ModeOpt.DRIP, NAME_DRIPCUT, NAME_ONPATH)
      Dim DripLayer As Integer = EgtGetFirstNameInGroup(nPartId, DripName)
      If DripLayer <> GDB_ID.NULL Then
         EgtEmptyGroup(DripLayer)
      Else
         DripLayer = EgtCreateGroup(nPartId)
         EgtSetName(DripLayer, DripName)
      End If
      ' Per ogni entità con gocciolatoio, ne inserisco una copia nel layer
      Dim vSelId As New List(Of Integer)
      Dim vTempSelId As New List(Of Integer)

      Dim nIndex As Integer = 0
      Dim vJoint As New List(Of Boolean)
      Dim bJointStart As Boolean = False

      For Each Entity As DripEntity In m_DripEntityList
         If Entity.bHaveDrip Then
            vJoint.Add(True)
         Else
            vJoint.Add(False)
         End If
      Next

      ' se non riesco a generare un elenco allora esco
      If vJoint.Count < 1 Then Return

      If vJoint(0) And vJoint(vJoint.Count - 1) Then
         bJointStart = True
      End If

      For Each Entity As DripEntity In m_DripEntityList

         If Entity.bHaveDrip Then
            Dim nSouId As Integer = EgtGetFirstNameInGroup(nOutLoopId, Entity.sEntityName)
            Dim nNewId As Integer = EgtCopyGlob(nSouId, DripLayer)
            EgtSetName(nNewId, Entity.sEntityName)
            vSelId.Add(nNewId)
            vTempSelId.Add(nNewId)
         End If

         ' devo distingure i casi in cui inserisco un valore positivo ed uno negativo!
         For Each IdCurve As Integer In vTempSelId

            ' accorcio entrmabi i lati
            Dim dLen As Double
            EgtCurveLength(IdCurve, dLen)

            If nIndex = vJoint.Count - 1 And (Not bJointStart Or Entity.dShortEnd <> 0) Then
               ' se l'ultimo segmento non è collegato al primo
               If Entity.dShortEnd > -EPS_SMALL Then
                  EgtTrimCurveEndAtLen(IdCurve, dLen - Entity.dShortEnd)
               Else
                  EgtExtendCurveEndByLen(IdCurve, -Entity.dShortEnd)
               End If

            ElseIf nIndex < vJoint.Count - 1 Then
               ' se l'elemento corrente non è collegato al precedente allora accorcio la coda
               If Not vJoint(nIndex + 1) Or Entity.dShortEnd <> 0 Then
                  If Entity.dShortEnd > -EPS_SMALL Then
                     EgtTrimCurveEndAtLen(IdCurve, dLen - Entity.dShortEnd)
                  Else
                     EgtExtendCurveEndByLen(IdCurve, -Entity.dShortEnd)
                  End If
               End If
            End If

            If nIndex = 0 And (Not bJointStart Or Entity.dShortStart <> 0) Then
               ' se il primo elemento non è collegato all'ultimo
               If Entity.dShortStart > -EPS_SMALL Then
                  EgtTrimCurveStartAtLen(IdCurve, Entity.dShortStart)
               Else
                  EgtExtendCurveStartByLen(IdCurve, -Entity.dShortStart)
               End If

            ElseIf nIndex > 0 Then
               ' se l'elemento precedente non è collegato al corrente allora accorcio la testa
               If Not vJoint(nIndex - 1) Or Entity.dShortStart <> 0 Then
                  If Entity.dShortStart > -EPS_SMALL Then
                     EgtTrimCurveStartAtLen(IdCurve, Entity.dShortStart)
                  Else
                     EgtExtendCurveStartByLen(IdCurve, -Entity.dShortStart)
                  End If
               End If
            End If

         Next
         vTempSelId.Clear()
         nIndex = nIndex + 1
      Next

      ' se tutti i lati sono accorciati allora eseguo il collegamento
      EgtCreateCurveCompoByReorder(DripLayer, vSelId.Count(), vSelId.ToArray(), New Point3d(), True)

      ' Eseguo offset dei risultati
      Dim nCrvId = EgtGetFirstInGroup(DripLayer)
      While nCrvId <> GDB_ID.NULL
         EgtOffsetCurve(nCrvId, -m_dDripOffset, OFF_TYPE.EXTEND)
         nCrvId = EgtGetNext(nCrvId)
      End While
      ' Eventuali curve aggiuntive con offset2
      If m_nEngrNbr2 > 0 And m_dDripOffset2 > EPS_SMALL Then
         nCrvId = EgtGetFirstInGroup(DripLayer)
         While nCrvId <> GDB_ID.NULL
            Dim nNextCrvId As Integer = EgtGetNext(nCrvId)
            For i As Integer = 1 To m_nEngrNbr2
               Dim nNewId As Integer = EgtCopy(nCrvId, nCrvId, GDB_POS.AFTER)
               EgtOffsetCurve(nNewId, -i * m_dDripOffset2, OFF_TYPE.EXTEND)
            Next
            nCrvId = nNextCrvId
         End While
      End If
      If m_Mode = ModeOpt.DRIP Then
         ' Esplodo nelle curve componenti
         nCrvId = EgtGetFirstInGroup(DripLayer)
         While nCrvId <> GDB_ID.NULL
            Dim nNextCrvId = EgtGetNext(nCrvId)
            Dim nCount As Integer
            EgtExplodeCurveCompo(nCrvId, nCount)
            nCrvId = nNextCrvId
         End While
         ' Assegno colore e attributi
         nCrvId = EgtGetFirstInGroup(DripLayer)
         While nCrvId <> GDB_ID.NULL
            EgtSetColor(nCrvId, COL_MCH_DRIPCUT())
            EgtSetInfo(nCrvId, INFO_DEPTH, m_dDripDepth)
            If m_dDripShort > EPS_SMALL Then EgtSetInfo(nCrvId, INFO_STRICT, "1")
            nCrvId = EgtGetNext(nCrvId)
         End While
      Else
         ' Assegno colore e attributi
         nCrvId = EgtGetFirstInGroup(DripLayer)
         While nCrvId <> GDB_ID.NULL
            EgtSetColor(nCrvId, COL_MCH_DRIPCUT())
            EgtSetInfo(nCrvId, INFO_DEPTH, m_dDripDepth)
            EgtSetInfo(nCrvId, INFO_STRICT, If(m_dDripShort > EPS_SMALL, "3", "0"))
            nCrvId = EgtGetNext(nCrvId)
         End While
      End If
   End Sub

   Private Sub PrevBtn_Click(sender As Object, e As RoutedEventArgs) Handles PrevBtn.Click
      If m_nCurrPage = 1 Then Return
      m_nCurrPage -= 1
      m_nShow = Math.Min( m_nCount - ( m_nCurrPage - 1) * MAX_LINES, MAX_LINES)
      TxBlChBxView()
      RefreshCheckAndValue()
   End Sub

   Private Sub NextBtn_Click(sender As Object, e As RoutedEventArgs) Handles NextBtn.Click
      If m_nCount <= ( m_nCurrPage - 1) * MAX_LINES Then Return
      m_nCurrPage += 1
      m_nShow = Math.Min( m_nCount - ( m_nCurrPage - 1) * MAX_LINES, MAX_LINES)
      TxBlChBxView()
      RefreshCheckAndValue()
   End Sub

   Private Sub SideCheck_Click(sender As Object, e As RoutedEventArgs) Handles A1.Click, A2.Click, A3.Click, A4.Click, A5.Click, A6.Click, A7.Click, A8.Click, A9.Click, A10.Click
      Dim CurrCheckBox As CheckBox = e.Source
      If m_Mode = ModeOpt.DRIP Or m_Mode = ModeOpt.ENGRAVE Then
         ' Recupero stato entità
         Dim bVal As Boolean = CurrCheckBox.IsChecked()
         Dim SideIndex As Integer = CInt(CurrCheckBox.Name.Substring(1))
         ' Converto nome checkbox in nome elemento tenendo conto della pagina e dello slittamento verso il basso
         Dim nCurrSide As Integer = ( m_nCurrPage - 1) * MAX_LINES + SideIndex - ( MAX_LINES - m_nShow)
         Dim sCurrSide As String = m_DripEntityList(nCurrSide - 1).sEntityName
         ' aggiorno l'entità con i valori scritti nel campo di testo
         Dim CurrEntity As DripEntity = DripEntity.FindEntity(sCurrSide)
         Dim dVal As Double = 0
         StringToLen(GetAngleTxBxFromIndex(SideIndex).Text, dVal)
         CurrEntity.dShortStart = dVal
         StringToLen(GetHeelTxBxFromIndex(SideIndex).Text, dVal)
         CurrEntity.dShortEnd = dVal
         ' Modifico info gocciolatoi
         ModifyDrip(sCurrSide, bVal)
         ' Aggiorno tutti i testi e le geometrie
         RefreshSideAngleText()
      End If
   End Sub

   '------->   riga 1
   Private Sub A1TxBx_EgtClosed(sender As Object, e As EventArgs) Handles A1TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideAngleFromTxBx(1, A1TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortStartFromTxBx(1, A1TxBx)
      End If
   End Sub

   Private Sub H1TxBx_EgtClosed(sender As Object, e As EventArgs) Handles H1TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideHeelFromTxBx(1, H1TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortEndFromTxBx(1, H2TxBx)
      End If
   End Sub

   '------->   riga 2
   Private Sub A2TxBx_EgtClosed(sender As Object, e As EventArgs) Handles A2TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideAngleFromTxBx(2, A2TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortStartFromTxBx(2, A2TxBx)
      End If
   End Sub

   Private Sub H2TxBx_EgtClosed(sender As Object, e As EventArgs) Handles H2TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideHeelFromTxBx(2, H2TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortEndFromTxBx(2, H2TxBx)
      End If
   End Sub

   '------->   riga 3
   Private Sub A3TxBx_EgtClosed(sender As Object, e As EventArgs) Handles A3TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideAngleFromTxBx(3, A3TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortStartFromTxBx(3, A3TxBx)
      End If
   End Sub

   Private Sub H3TxBx_EgtClosed(sender As Object, e As EventArgs) Handles H3TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideHeelFromTxBx(3, H3TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortEndFromTxBx(3, H3TxBx)
      End If
   End Sub

   '------->   riga 4
   Private Sub A4TxBx_EgtClosed(sender As Object, e As EventArgs) Handles A4TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideAngleFromTxBx(4, A4TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortStartFromTxBx(4, A4TxBx)
      End If
   End Sub

   Private Sub H4TxBx_EgtClosed(sender As Object, e As EventArgs) Handles H4TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideHeelFromTxBx(4, H4TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortEndFromTxBx(4, H4TxBx)
      End If
   End Sub

   '------->   riga 5
   Private Sub A5TxBx_EgtClosed(sender As Object, e As EventArgs) Handles A5TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideAngleFromTxBx(5, A5TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortStartFromTxBx(5, A5TxBx)
      End If
   End Sub

   Private Sub H5TxBx_EgtClosed(sender As Object, e As EventArgs) Handles H5TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideHeelFromTxBx(5, H5TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortEndFromTxBx(5, H5TxBx)
      End If
   End Sub

   '------->   riga 6
   Private Sub A6TxBx_EgtClosed(sender As Object, e As EventArgs) Handles A6TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideAngleFromTxBx(6, A6TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortStartFromTxBx(6, A6TxBx)
      End If
   End Sub

   Private Sub H6TxBx_EgtClosed(sender As Object, e As EventArgs) Handles H6TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideHeelFromTxBx(6, H6TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortEndFromTxBx(6, H6TxBx)
      End If
   End Sub

   '------->   riga 7
   Private Sub A7TxBx_EgtClosed(sender As Object, e As EventArgs) Handles A7TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideAngleFromTxBx(7, A7TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortStartFromTxBx(7, A7TxBx)
      End If
   End Sub

   Private Sub H7TxBx_EgtClosed(sender As Object, e As EventArgs) Handles H7TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideHeelFromTxBx(7, H7TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortEndFromTxBx(7, H7TxBx)
      End If
   End Sub

   ' ------->   riga 8
   Private Sub A8TxBx_EgtClosed(sender As Object, e As EventArgs) Handles A8TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideAngleFromTxBx(8, A8TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortStartFromTxBx(8, A8TxBx)
      End If
   End Sub

   Private Sub H8TxBx_EgtClosed(sender As Object, e As EventArgs) Handles H8TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideHeelFromTxBx(8, H8TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortEndFromTxBx(8, H8TxBx)
      End If
   End Sub

   ' ------->   riga 9
   Private Sub A9TxBx_EgtClosed(sender As Object, e As EventArgs) Handles A9TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideAngleFromTxBx(9, A9TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortStartFromTxBx(9, A9TxBx)
      End If
   End Sub

   Private Sub H9TxBx_EgtClosed(sender As Object, e As EventArgs) Handles H9TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideHeelFromTxBx(9, H9TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortEndFromTxBx(9, H9TxBx)
      End If
   End Sub

   ' ------->   riga 10
   Private Sub A10TxBx_EgtClosed(sender As Object, e As EventArgs) Handles A10TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideAngleFromTxBx(10, A10TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortStartFromTxBx(10, A10TxBx)
      End If
   End Sub

   Private Sub H10TxBx_EgtClosed(sender As Object, e As EventArgs) Handles H10TxBx.EgtClosed
      If m_Mode = ModeOpt.SIDEANGLE Then
         SetSideHeelFromTxBx(10, H10TxBx)
      Else 'If m_Mode = ModeOpt.DRIP Then
         SetDripShortEndFromTxBx(10, H10TxBx)
      End If
   End Sub

   Private Sub SetSideAngleFromTxBx(SideIndex As Integer, AngleTxBx As EgtWPFLib.EgtTextBox)
      ' Nuovo angolo di inclinazione
      Dim dSideAngle As Double
      StringToDouble(AngleTxBx.Text, dSideAngle)
      ' Verifico stia nei limiti
      If dSideAngle < -m_dMaxSideAng Then
         dSideAngle = -m_dMaxSideAng
         AngleTxBx.Text = DoubleToString(dSideAngle, 2)
      ElseIf dSideAngle > m_dMaxSideAng Then
         dSideAngle = m_dMaxSideAng
         AngleTxBx.Text = DoubleToString(dSideAngle, 2)
      End If
      ' Converto nome checkbox in nome elemento tenendo conto della pagina e dello slittamento verso il basso
      Dim nCurrSide As Integer = ( m_nCurrPage - 1) * MAX_LINES + SideIndex - ( MAX_LINES - m_nShow)
      Dim sCurrSide As String = m_SideAngleEntityList(nCurrSide - 1).sEntityName
      ' Lo modifico nella geometria e nella lista inclinazioni
      ModifySideAngle(sCurrSide, dSideAngle)
      ' Aggiorno tutti i testi
      RefreshSideAngleText()
   End Sub

   ' definsce l'accorciamento del lato rispetto al punto iniziale
   Private Sub SetDripShortStartFromTxBx(SideIndex As Integer, AngleTxBx As EgtWPFLib.EgtTextBox)
      ' Nuovo angolo di inclinazione
      Dim dSideAngle As Double
      StringToDouble(AngleTxBx.Text, dSideAngle)
      ' Verifico stia nei limiti

      ' Converto nome checkbox in nome elemento tenendo conto della pagina e dello slittamento verso il basso
      Dim nCurrSide As Integer = (m_nCurrPage - 1) * MAX_LINES + SideIndex - (MAX_LINES - m_nShow)
      Dim sCurrSide As String = m_DripEntityList(nCurrSide - 1).sEntityName

      ' Ricavo CurrEntity dal nome
      Dim CurrEntity As DripEntity = DripEntity.FindEntity(sCurrSide)
      CurrEntity.dShortStart = dSideAngle
      ' Creo le geometrie dei gocciolatoi
      RefreshSideAngleText()

      If m_Mode = ModeOpt.DRIP Then
         WritePrivateProfileString(S_SIDES, K_DRIPSHORT & CurrEntity.sEntityName & "_End", LenToString(CurrEntity.dShortStart, 3), m_MainWindow.GetIniFile())
      Else
         WritePrivateProfileString(S_SIDES, K_ENGRAVESHORT & CurrEntity.sEntityName & "_Start", LenToString(CurrEntity.dShortStart, 3), m_MainWindow.GetIniFile())
      End If


   End Sub

   ' definisce l'accorciamento del alto rispetto al punto finale
   Private Sub SetDripShortEndFromTxBx(SideIndex As Integer, AngleTxBx As EgtWPFLib.EgtTextBox)
      ' Nuovo angolo di inclinazione
      Dim dSideAngle As Double
      StringToDouble(AngleTxBx.Text, dSideAngle)
      ' Verifico stia nei limiti

      ' Converto nome checkbox in nome elemento tenendo conto della pagina e dello slittamento verso il basso
      Dim nCurrSide As Integer = (m_nCurrPage - 1) * MAX_LINES + SideIndex - (MAX_LINES - m_nShow)
      Dim sCurrSide As String = m_DripEntityList(nCurrSide - 1).sEntityName

      ' Ricavo CurrEntity dal nome
      Dim CurrEntity As DripEntity = DripEntity.FindEntity(sCurrSide)
      CurrEntity.dShortEnd = dSideAngle

      ' Creo le geometrie dei gocciolatoi
      RefreshSideAngleText()

      If m_Mode = ModeOpt.DRIP Then
         WritePrivateProfileString(S_SIDES, K_DRIPSHORT & CurrEntity.sEntityName & "_End", LenToString(CurrEntity.dShortEnd, 3), m_MainWindow.GetIniFile())
      Else
         WritePrivateProfileString(S_SIDES, K_ENGRAVESHORT & CurrEntity.sEntityName & "_End", LenToString(CurrEntity.dShortEnd, 3), m_MainWindow.GetIniFile())
      End If

   End Sub

   Private Sub SetSideHeelFromTxBx(SideIndex As Integer, HeelTxBx As EgtWPFLib.EgtTextBox)
      ' Nuovo tallone
      Dim dSideHeel As Double
      StringToLen(HeelTxBx.Text, dSideHeel)
      ' Verifico stia nei limiti
      If dSideHeel < 0 Then
         dSideHeel = 0
         HeelTxBx.Text = "0"
      End If
      ' Converto nome checkbox in nome elemento tenendo conto della pagina e dello slittamento verso il basso
      Dim nCurrSide As Integer = ( m_nCurrPage - 1) * MAX_LINES + SideIndex - ( MAX_LINES - m_nShow)
      Dim sCurrSide As String = m_SideAngleEntityList(nCurrSide - 1).sEntityName
      ' Lo modifico nella geometria e nella lista inclinazioni
      ModifySideHeel(sCurrSide, dSideHeel)
      ' Aggiorno tutti i testi
      RefreshSideAngleText()
   End Sub

   ' Funzione che modifica l'eventuale canalino di un lato
   Friend Function ModifyDrip(sEntityName As String, bVal As Boolean) As Boolean
      ' Ricavo CurrEntity dal nome
      Dim CurrEntity As DripEntity = DripEntity.FindEntity(sEntityName)
      If IsNothing(CurrEntity) Then
         EgtOutLog("Error in drip definition: selected line not found in DripEntity")
         Return False
      End If
      ' Scrivo nuovo angolo nelle info
      If bVal Then
         EgtSetInfo(CurrEntity.nGeomId, INFO_HAVE_DRIP, "1")
         ' Cancello inclinazione nell'apposito campo info
      Else
         EgtRemoveInfo(CurrEntity.nGeomId, INFO_HAVE_DRIP)
      End If
      ' Aggiorno lista entità con nuova inclinazione
      CurrEntity.bHaveDrip = bVal

      Return True
   End Function

   ' Funzione che modifica l'inclinazione di un lato
   Friend Function ModifySideAngle(sEntityName As String, dSideAngle As Double) As Boolean
      ' Ricavo CurrEntity dal nome
      Dim CurrEntity As SideAngleEntity = SideAngleEntity.FindEntity(sEntityName)
      If IsNothing(CurrEntity) Then
         EgtOutLog("Error in side angle definition: selected line not found in SideAngleList")
         Return False
      End If
      ' Scrivo nuovo angolo nelle info
      If dSideAngle <> 0 Then
         EgtSetInfo(CurrEntity.nGeomId, INFO_SIDE_ANGLE, dSideAngle)
         EgtSetInfo(CurrEntity.nGeomId, INFO_ORIG_SIDE_ANGLE, dSideAngle)
      ' Cancello inclinazione nell'apposito campo info
      Else
         EgtRemoveInfo(CurrEntity.nGeomId, INFO_SIDE_ANGLE)
         EgtRemoveInfo(CurrEntity.nGeomId, INFO_ORIG_SIDE_ANGLE)
      End If
      ' Aggiorno lista entità con nuova inclinazione
      CurrEntity.dSideAngle = dSideAngle
      Return True
   End Function

   ' Funzione che modifica il tallone di un lato
   Friend Function ModifySideHeel(sEntityName As String, dSideHeel As Double) As Boolean
      ' Ricavo CurrEntity dal nome
      Dim CurrEntity As SideAngleEntity = SideAngleEntity.FindEntity(sEntityName)
      If IsNothing(CurrEntity) Then
         EgtOutLog("Error in side angle definition: selected line not found in SideAngleList")
         Return False
      End If
      ' Scrivo nuovo tallone nelle info
      If dSideHeel > 10 * EPS_SMALL Then
         EgtSetInfo(CurrEntity.nGeomId, INFO_HEEL, dSideHeel)
      ' Cancello inclinazione nell'apposito campo info
      Else
         EgtRemoveInfo(CurrEntity.nGeomId, INFO_HEEL)
      End If
      ' Aggiorno lista entità con nuova inclinazione
      CurrEntity.dSideHeel = dSideHeel
      Return True
   End Function

   ' Pulisco la finestra e svuoto le liste SideAngle/DripEntity
   Friend Sub DeleteSideAngle()
      ' Cancello lista lati inclinati
      If m_Mode = ModeOpt.SIDEANGLE Then
         m_SideAngleEntityList.Clear()
         ' Annullo tutti i testi
         For Index As Integer = 1 To MAX_LINES
            GetAngleTxBxFromIndex(Index).Text = String.Empty
            GetHeelTxBxFromIndex(Index).Text = String.Empty
         Next
      Else
         m_DripEntityList.Clear()
         ' Annullo tutti i CheckBox e svuoto tutte le caselle di testo
         For Index As Integer = 1 To MAX_LINES
            GetChBxFromIndex(Index).IsChecked = False
            GetAngleTxBxFromIndex(Index).Text = String.Empty
            GetHeelTxBxFromIndex(Index).Text = String.Empty
         Next
      End If
   End Sub

   '---------------> Elenco parametri presenti a fine pagina
   Private Sub Parameter1TxBx_EgtClosed(sender As Object, e As EventArgs) Handles Parameter1TxBx.EgtClosed
      If m_Mode = ModeOpt.DRIP Or m_Mode = ModeOpt.ENGRAVE Then
         ' Recupero il valore
         StringToLen(Parameter1TxBx.Text, m_dDripOffset)
         ' Creo le geometrie dei gocciolatoi
         RefreshSideAngleText()
      End If
   End Sub

   Private Sub Parameter2TxBx_EgtClosed(sender As Object, e As EventArgs) Handles Parameter2TxBx.EgtClosed
      If m_Mode = ModeOpt.DRIP Then
         ' Recupero il valore
         StringToLen(Parameter2TxBx.Text, m_dDripOffset2)
         ' Creo le geometrie dei gocciolatoi
         RefreshSideAngleText()
      End If
   End Sub

   Private Sub Parameter2aTxBx_EgtClosed(sender As Object, e As EventArgs) Handles Parameter2aTxBx.EgtClosed
      If m_Mode = ModeOpt.ENGRAVE Then
         ' Recupero il valore
         StringToInt(Parameter2aTxBx.Text, m_nEngrNbr2)
         ' Creo le geometrie dei gocciolatoi
         RefreshSideAngleText()
      End If
   End Sub

   Private Sub Parameter2bTxBx_EgtClosed(sender As Object, e As EventArgs) Handles Parameter2bTxBx.EgtClosed
      If m_Mode = ModeOpt.ENGRAVE Then
         ' Recupero il valore
         StringToLen(Parameter2bTxBx.Text, m_dDripOffset2)
         ' Creo le geometrie dei gocciolatoi
         RefreshSideAngleText()
      End If
   End Sub

   Private Sub Parameter3TxBx_EgtClosed(sender As Object, e As EventArgs) Handles Parameter3TxBx.EgtClosed
      If m_Mode = ModeOpt.DRIP Or m_Mode = ModeOpt.ENGRAVE Then
         ' Recupero il valore
         StringToLen(Parameter3TxBx.Text, m_dDripDepth)
         ' Creo le geometrie dei gocciolatoi
         RefreshSideAngleText()
      End If
   End Sub

   Private Sub Parameter4TxBx_EgtClosed(sender As Object, e As EventArgs) Handles Parameter4TxBx.EgtClosed
      If m_Mode = ModeOpt.DRIP Or m_Mode = ModeOpt.ENGRAVE Then
         ' Recupero il valore
         StringToLen(Parameter4TxBx.Text, m_dDripShort)
         ' Creo le geometrie dei gocciolatoi
         RefreshSideAngleText()
      End If
   End Sub

   Friend Sub ReLoadSideAnglePage()
      SideAngleUC_Loaded(Me, New RoutedEventArgs)
   End Sub

End Class

Friend Class SideAngleEntity

   Private Shared m_MainWindow As MainWindow = DirectCast(Application.Current.MainWindow, MainWindow)

   Private m_nGeomId As Integer
   Private m_sEntityName As String
   Private m_nTextId As Integer
   Private m_dSideAngle As Double
   Private m_dSideHeel As Double

   Public Property nGeomId As Integer
      Get
         Return m_nGeomId
      End Get
      Set(value As Integer)
         m_nGeomId = value
      End Set
   End Property

   Public ReadOnly Property sEntityName As String
      Get
         Return m_sEntityName
      End Get
   End Property

   Public ReadOnly Property nTextId As Integer
      Get
         Return m_nTextId
      End Get
   End Property

   Public Property dSideAngle As Double
      Get
         Return m_dSideAngle
      End Get
      Set(value As Double)
         m_dSideAngle = value
      End Set
   End Property

   Public Property dSideHeel As Double
      Get
         Return m_dSideHeel
      End Get
      Set(value As Double)
         m_dSideHeel = value
      End Set
   End Property

   Sub New(nId As Integer, sEntityName As String, nTextId As Integer, dSideAngle As Double, dSideHeel As Double)
      m_nGeomId = nId
      m_sEntityName = sEntityName
      m_nTextId = nTextId
      m_dSideAngle = dSideAngle
      m_dSideHeel = dSideHeel
   End Sub

   Friend Shared Function FindEntity(sEntityName As String) As SideAngleEntity
      Dim EntityList As List(Of SideAngleEntity) = Nothing
      If m_MainWindow.m_ActivePage = MainWindow.Pages.Draw Then
         EntityList = m_MainWindow.m_DrawPageUC.m_SideAngleUC.m_SideAngleEntityList
      ElseIf m_MainWindow.m_ActivePage = MainWindow.Pages.Import Then
         EntityList = m_MainWindow.m_ImportPageUC.m_SideAngleUC.m_SideAngleEntityList
      End If

      If IsNothing(EntityList) Then
         Return Nothing
      End If

      For Each Entity As SideAngleEntity In EntityList
         If Entity.m_sEntityName = sEntityName Then
            Return Entity
         End If
      Next
      Return Nothing
   End Function

End Class

Friend Class DripEntity

   Private Shared m_MainWindow As MainWindow = DirectCast(Application.Current.MainWindow, MainWindow)

   Private m_nGeomId As Integer
   Private m_sEntityName As String
   Private m_nTextId As Integer
   Private m_bHaveDrip As Boolean


   Private m_dShortStart As Double
   Private m_dShortEnd As Double

   Public Property nGeomId As Integer
      Get
         Return m_nGeomId
      End Get
      Set(value As Integer)
         m_nGeomId = value
      End Set
   End Property

   Public ReadOnly Property sEntityName As String
      Get
         Return m_sEntityName
      End Get
   End Property

   Public ReadOnly Property nTextId As Integer
      Get
         Return m_nTextId
      End Get
   End Property

   Public Property bHaveDrip As Boolean
      Get
         Return m_bHaveDrip
      End Get
      Set(value As Boolean)
         m_bHaveDrip = value
      End Set
   End Property

   Public Property dShortEnd As Double
      Get
         Return m_dShortEnd
      End Get
      Set(value As Double)
         m_dShortEnd = value
      End Set
   End Property
   Public Property dShortStart As Double
      Get
         Return m_dShortStart
      End Get
      Set(value As Double)
         m_dShortStart = value
      End Set
   End Property

   Sub New(nId As Integer, sEntityName As String, nTextId As Integer, bHaveDrip As Boolean)
      m_nGeomId = nId
      m_sEntityName = sEntityName
      m_nTextId = nTextId
      m_bHaveDrip = bHaveDrip
   End Sub

   Friend Shared Function FindEntity(sEntityName As String) As DripEntity
      Dim EntityList As List(Of DripEntity) = Nothing
      If m_MainWindow.m_ActivePage = MainWindow.Pages.Draw Then
         EntityList = m_MainWindow.m_DrawPageUC.m_SideAngleUC.m_DripEntityList
      ElseIf m_MainWindow.m_ActivePage = MainWindow.Pages.Import Then
         EntityList = m_MainWindow.m_ImportPageUC.m_SideAngleUC.m_DripEntityList
      End If

      If IsNothing(EntityList) Then
         Return Nothing
      End If

      For Each Entity As DripEntity In EntityList
         If Entity.m_sEntityName = sEntityName Then
            Return Entity
         End If
      Next
      Return Nothing
   End Function

End Class