Imports System.Globalization
Imports EgtUILib
Imports EgtWPFLib

Public Class AlzFrontUC
   Private Const NUM_VAR As Integer = 10
   Private Const LUA_CMP_VARS As String = "CMP"
   Private Const LUA_CMP_DRAW As String = "CMP_Draw"
   Private Const INFO_VAR As String = "Var"
   Private Const INFO_CMP As String = "CMP"
   Private Const INFO_ID As String = "ID"
   Friend Const LUA_CMP_INDEX As String = LUA_CMP_VARS & ".Ind"
   Friend Const LUA_CMP_INTERNAL As String = LUA_CMP_VARS & ".Int"
   Friend Const LUA_REMOVEHOLE As String = "RemoveHole"

   ' Costanti layer componenti
   Friend Const COMPO_LAYER_AUX As String = "LayAux"
   Friend Const COMPO_LAYER_QUOTATURE As String = "Quotature"
   Friend Const COMPO_LAYER_ETICHETTE As String = "Etichette"

   ' nome della info riferita alle alzatine e ai frontalini (1=Alz, 2=Front, 0=niente)
   Private Const INFO_ALZFRONT As String = "AF"
   Private Const INFO_ENABLE As String = "EnableAF"

   ' Properties 
   Private m_sCompoDir As String = String.Empty
   Private m_sCompoName As String = String.Empty
   Friend m_bDrawOk As Boolean = False
   Private m_bFirst As Boolean = True

   ' 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
   ' lista dei lati, in cui indico il tipo di entità da associare
   Private AlzFrontEntityList As New List(Of AlzFrontEntity)

   ' numero di lati presenti nella figura
   Private m_nCount As Integer = 0
   ' numero di righe rese disponibili nella pagina -> m_nShow = min(m_nCount, MAX_LINE)
   Private m_nShow As Integer = MAX_LINES

   Private bInternalSelection As Boolean = False

   ' raggio circoscritto al pezzo
   Private m_dBBoxRad As Double
   ' dimensione dei caratteri
   Private m_dH As Double

   Private Sub AlzFrontPage_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded

      m_MainWindow.m_DrawPageUC.m_ActiveComponentPage = DrawPageUC.Pages.AlzFront

      ' 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

      ' carico la lista dei lati della figura
      InitSides()
      ' aggiorno la visualizzazione delle TextBox e dei CheckBox
      TxBlChBxView()
      ' imposto lo stato delle checkbox
      SetCheck()

      ' nascondo il bottone Back della pagina Draw
      m_MainWindow.m_DrawPageUC.BackBtn.Visibility = Visibility.Hidden
      m_MainWindow.m_DrawPageUC.MessageGrid.Visibility = Visibility.Hidden
      ' Disabilito bottoni angoli di fianco e lavorazioni da sotto
      m_MainWindow.m_DrawPageUC.SideAngleBtn.IsEnabled = False
      m_MainWindow.m_DrawPageUC.FiloTopBtn.IsEnabled = False
      m_MainWindow.m_DrawPageUC.EngraveBtn.IsEnabled = False
      m_MainWindow.m_DrawPageUC.DripCutBtn.IsEnabled = False

      ' nome dei parametri condivisi
      Parameter1TxBl.Text = "Altezza"
      Parameter2TxBl.Text = "Delta angolo"
      Parameter5TxBl.Text = "Spessore"

      EgtZoom(ZM.ALL)
   End Sub

   ' carico la lista dei lati della figura corrente
   Private Sub InitSides()
      ' pulisco la lista dei lati 
      AlzFrontEntityList.Clear()

      ' Id del pezzo
      Dim PartId As Integer = GDB_ID.NULL
      ' Id del loop eseterno
      Dim LoopId As Integer = GDB_ID.NULL
      ' Id delle label
      Dim LabelId As Integer = GDB_ID.NULL

      ' definisco i valori delle altezza e degli angoli di spoglia per le alzatine e i frontalini (letti da file ini del programma)
      GetPrivateProfileString(S_ALZFRONT, K_ALZ_HEIGHT, "0", Parameter1ATxBx.Text, m_MainWindow.GetIniFile)
      GetPrivateProfileString(S_ALZFRONT, K_FRONT_HEIGHT, "0", Parameter1FTxBx.Text, m_MainWindow.GetIniFile)
      GetPrivateProfileString(S_ALZFRONT, K_ALZ_DELTA_ANG, "0", Parameter2ATxBx.Text, m_MainWindow.GetIniFile)
      GetPrivateProfileString(S_ALZFRONT, K_FRONT_DELTA_ANG, "0", Parameter2FTxBx.Text, m_MainWindow.GetIniFile)
      Parameter5TxBx.Text = Utility.LenToString(m_MainWindow.m_CurrentProjectPageUC.m_dRawHeight, 2)

      ' Imposto contesto corrente
      EgtSetCurrentContext(m_MainWindow.m_DrawPageUC.DrawScene.GetCtx())
      ' Ricavo nome primo pezzo
      PartId = EgtGetFirstPart()
      ' se non  esiste un pezzo corrente allora esco
      If PartId = GDB_ID.NULL Then Return

      ' Recupero nome layer con geometria di contorno (esterno o interno) del pezzo
      LoopId = EgtGetFirstNameInGroup(EgtGetFirstPart(), NAME_OUTLOOP)

      ' Recupero il layer "Etichette" per inserirvi il nome dei lati
      LabelId = EgtGetFirstNameInGroup(EgtGetFirstPart(), COMPO_LAYER_ETICHETTE)
      If LabelId = GDB_ID.NULL Then
         LabelId = EgtCreateGroup(PartId)
         EgtSetName(LabelId, COMPO_LAYER_ETICHETTE)
      Else
         ' se esistente allora lo svuoto
         EgtEmptyGroup(LabelId)
      End If
      EgtSetStatus(LabelId, GDB_ST.ON_)

      '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)
      ' utilizzato per definire la dimensione dei caratteri delle label per i lati
      m_dBBoxRad = 0.5 * Point3d.DistXY(ptMin, ptMax)

      ' 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

      ' inserisco il lato nella lista 
      While CurrLine <> GDB_ID.NULL
         Dim NextId As Integer = EgtGetNext(CurrLine)
         If NextId = GDB_ID.NULL Then NextId = EgtGetFirstInGroup(LoopId)
         If VerifySideAnglePossible(PrevLine, CurrLine, NextId, bOutLoop) Then

            If ApprovedSideToAlzFront(CurrLine) Then
               ' Aggiungo il lato alla lista di quelli su cui è possibile mettere una alzatina o un frontalino
               Dim sNameCurrLine As String = String.Empty
               Dim nInfo As Integer = 0
               Dim dSideAng As Integer = 0
               EgtSetName(CurrLine, "A" & nEntityIndex.ToString)
               EgtGetName(CurrLine, sNameCurrLine)
               ' inserisco la numerazione dei lati della figura
               AddTextToLine(sNameCurrLine, LabelId, CurrLine, 20, m_dBBoxRad, True)
               ' recupero l'informazione 
               EgtGetInfo(CurrLine, INFO_ALZFRONT, nInfo)
               If nInfo = 1 Then
                  AlzFrontEntityList.Add(New AlzFrontEntity(sNameCurrLine, CurrLine, AlzFrontEntity.AlzFront.ALZATINA))
               ElseIf nInfo = 2 Then
                  AlzFrontEntityList.Add(New AlzFrontEntity(sNameCurrLine, CurrLine, AlzFrontEntity.AlzFront.FRONTALINO))
               Else
                  AlzFrontEntityList.Add(New AlzFrontEntity(sNameCurrLine, CurrLine))
               End If
               ' inserisco riferimento univoco al lato (solo se non esiste)
               Dim sInfoRef As String = String.Empty
               EgtGetInfo(CurrLine, "RefAF", sInfoRef)
               If String.IsNullOrEmpty(sInfoRef) Then
                  Dim sRefGUID As String = System.Guid.NewGuid().ToString()
                  EgtSetInfo(CurrLine, "RefAF", sRefGUID)
               End If
               nEntityIndex += 1
            Else
               EgtSetName(CurrLine, "B" & nOtherIndex.ToString)
               nOtherIndex = nOtherIndex + 1
            End If
         End If
         PrevLine = CurrLine
         CurrLine = EgtGetNext(CurrLine)
      End While

      ' Aggiorno numero di lati carciati
      m_nCount = AlzFrontEntityList.Count()
      ' 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
      ' aggiungo l'Info che comunica se il lato è stato modificato
      InitList()

   End Sub

   ' Imposto la visibilità degli oggetti nella pagina: qui eseguo l'impaginazione
   Private Sub TxBlChBxView()

      If m_nCount = 0 Then
         ' nascondo il nome delle colonne
         SideAngleBl.Visibility = Windows.Visibility.Hidden
         HeelBl.Visibility = Windows.Visibility.Hidden
      Else
         ' definisco il posizionamento del nome (Alz.) delle colonne all'interno della grigia
         Grid.SetRow(SideAngleBl, MAX_LINES - m_nShow)
         SideAngleBl.Text = "Alz."
         SideAngleBl.Visibility = Windows.Visibility.Visible
         ' definisco il posizionamento del nome (Front.) delle colonne all'interno della grigia
         Grid.SetRow(HeelBl, MAX_LINES - m_nShow)
         HeelBl.Text = "Front."
         HeelBl.Visibility = Windows.Visibility.Visible
      End If

      ' Lati visibili
      For nI As Integer = 1 To m_nShow
         Dim Index As Integer = MAX_LINES - m_nShow + nI
         ' definisco la visibilità della label
         GetTxBlFromIndex(Index).Visibility = Windows.Visibility.Visible
         GetTxBlFromIndex(Index).Text = "A" & nI.ToString
         GetChBxAlzFromIndex(Index).Visibility = Windows.Visibility.Visible
         GetChBxFrontFromIndex(Index).Visibility = Windows.Visibility.Visible
         ' annulo le eventuali selezioni 
         bInternalSelection = True
         GetChBxAlzFromIndex(Index).IsChecked = False
         bInternalSelection = True
         GetChBxFrontFromIndex(Index).IsChecked = False

         ' aggiungo i campi per allungare e accorciare i lati (adesso sostituito con le CheckBox)
         'GetAngleTxBxFromIndex(Index).Visibility = Windows.Visibility.Visible
         'GetHeelTxBxFromIndex(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
         ' definisco la visibilità della label
         GetTxBlFromIndex(Index).Visibility = Windows.Visibility.Hidden
         GetChBxAlzFromIndex(Index).Visibility = Windows.Visibility.Hidden
         GetChBxFrontFromIndex(Index).Visibility = Windows.Visibility.Hidden
         bInternalSelection = True
         GetChBxAlzFromIndex(Index).IsChecked = False
         bInternalSelection = True
         GetChBxFrontFromIndex(Index).IsChecked = False
         'GetAngleTxBxFromIndex(Index).Visibility = Windows.Visibility.Hidden
         'GetHeelTxBxFromIndex(Index).Visibility = Windows.Visibility.Hidden

      Next
      bInternalSelection = False
   End Sub

   Private Sub SetCheck()
      For IndexSide As Integer = 0 To AlzFrontEntityList.Count() - 1
         Dim sNameSide As String = AlzFrontEntityList(IndexSide).SideName
         Dim IndexCh As Integer = IndexSide + MAX_LINES - m_nShow + 1
         If AlzFrontEntityList(IndexSide).Type = AlzFrontEntity.AlzFront.ALZATINA Then
            bInternalSelection = True
            GetChBxAlzFromIndex(IndexCh).IsChecked = True
         ElseIf AlzFrontEntityList(IndexSide).Type = AlzFrontEntity.AlzFront.FRONTALINO Then
            bInternalSelection = True
            GetChBxFrontFromIndex(IndexCh).IsChecked = True
         End If
      Next
      bInternalSelection = False
   End Sub

   ' restituisce vero se il lato possiede delle info legate al sideangle
   Private Function VerifyIsThereSideAngle(nCurrLine As Integer) As Boolean
      Dim dSideAngle As Double
      return EgtGetInfo(nCurrLine, INFO_SIDE_ANGLE, dSideAngle)
   End Function

   ' restituisce vero se il lato possiede delle info legate alle alette
   Private Function VerifyIsThereAlzFront(nCurrLine As Integer) As Boolean
      Dim nAlzFront As Integer
      return EgtGetInfo(nCurrLine, INFO_ALZFRONT, nAlzFront) AndAlso nAlzFront <> 0
   End Function

   ' approvo la costruzione dell'aletta sul lato indicato
   Private Function ApprovedSideToAlzFront(nCurrLine As Integer) As Boolean
      If VerifyIsThereSideAngle(nCurrLine) And Not VerifyIsThereAlzFront(nCurrLine) Then
         ' se esiste SideAngle e un'aletta allora NON approvo
         Return False
      End If
      Return True
   End Function

   ' Permette di aggiugere accanto alla linea passata
   Friend Function AddTextToLine(sText As String, TextLayer As Integer, CurrLine As Integer, dDistance As Double,
                                 dBBoxRad As Double, bTextExt As Boolean, Optional bRot As Boolean = False) As Integer
      ' Calcolo altezza testo
      m_dH = 0.05 * dBBoxRad
      ' Creo testo
      Dim nText As Integer = EgtCreateTextAdv(TextLayer, Point3d.ORIG(), 0, sText, "", 500, False, m_dH, 1, 0, INS_POS.MC)
      ' Calcolo posizionamento
      ' BBox del testo e suo centro
      Dim ptMinBBox As Point3d
      Dim ptMaxBBox As Point3d
      EgtGetBBox(nText, GDB_BB.STANDARD, ptMinBBox, ptMaxBBox)
      Dim ptMidBBox As Point3d
      ptMidBBox = Point3d.Media(ptMinBBox, ptMaxBBox)
      ' Punto medio della curva
      Dim ptMid As Point3d
      EgtMidPoint(CurrLine, nText, ptMid)
      ' Versore sul punto medio della curva
      Dim vtMid As Vector3d
      EgtMidVector(CurrLine, nText, vtMid)
      ' versore perpendicolare alla CurrLine che punta verso il testo
      Dim vtOrto As New Vector3d(vtMid)
      If bTextExt Then
         vtOrto.Rotate(Vector3d.Z_AX(), -90)
      Else
         vtOrto.Rotate(Vector3d.Z_AX(), 90)
      End If
      ' eventuale rotazione del testo
      Dim dRotAng As Double = 0
      If bRot Then
         dRotAng = Math.Atan2(vtMid.y, vtMid.x) * 180 / Math.PI
         Dim dSpecRotAng = dRotAng
         If dSpecRotAng > 91 Then
            dSpecRotAng -= 180
         ElseIf dSpecRotAng < -89 Then
            dSpecRotAng += 180
         End If
         EgtRotate(nText, Point3d.ORIG(), Vector3d.Z_AX(), dSpecRotAng)
      End If
      ' vettore dal centro del BBox all'estremo più vicino
      Dim vtptExtptMC As Vector3d
      If bRot Then
         vtptExtptMC = New Vector3d(0, ptMidBBox.y - ptMinBBox.y, 0)
         vtptExtptMC.Rotate(Vector3d.Z_AX(), dRotAng)
      Else
         If bTextExt Then
            If vtMid.x > 0 Then
               If vtMid.y > 0 Then
                  vtptExtptMC = ptMidBBox - New Point3d(ptMinBBox.x, ptMaxBBox.y, 0)
               Else
                  vtptExtptMC = ptMidBBox - ptMaxBBox
               End If
            Else
               If vtMid.y > 0 Then
                  vtptExtptMC = ptMidBBox - ptMinBBox
               Else
                  vtptExtptMC = ptMidBBox - New Point3d(ptMaxBBox.x, ptMinBBox.y, 0)
               End If
            End If
         Else
            If vtMid.x > 0 Then
               If vtMid.y > 0 Then
                  vtptExtptMC = ptMidBBox - New Point3d(ptMaxBBox.x, ptMinBBox.y, 0)
               Else
                  vtptExtptMC = ptMidBBox - ptMinBBox
               End If
            Else
               If vtMid.y > 0 Then
                  vtptExtptMC = ptMidBBox - ptMaxBBox
               Else
                  vtptExtptMC = ptMidBBox - New Point3d(ptMinBBox.x, ptMaxBBox.y, 0)
               End If
            End If
         End If
      End If
      ' Calcolo il centro del testo
      Dim ptTextMC As Point3d = ptMid + vtOrto * (dDistance + (vtOrto * vtptExtptMC))
      EgtMove(nText, (ptTextMC - Point3d.ORIG()))
      Return nText
   End Function

#Region "CHIAMATA ALLE TEXT/CHECK/LABEL"
   Private Function GetChBxAlzFromIndex(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 GetChBxAalZFromName(sName As String) As CheckBox
      Select Case sName
         Case "A1"
            Return A1
         Case "A2"
            Return A2
         Case "A3"
            Return A3
         Case "A4"
            Return A4
         Case "A5"
            Return A5
         Case "A6"
            Return A6
         Case "A7"
            Return A7
         Case "A8"
            Return A8
         Case "A9"
            Return A9
         Case Else
            Return A10
      End Select
   End Function

   Private Function GetChBxFrontFromIndex(Index As Integer) As CheckBox
      Select Case Index
         Case 1
            Return F1
         Case 2
            Return F2
         Case 3
            Return F3
         Case 4
            Return F4
         Case 5
            Return F5
         Case 6
            Return F6
         Case 7
            Return F7
         Case 8
            Return F8
         Case 9
            Return F9
         Case Else
            Return F10
      End Select
   End Function

   Private Function GetChBxFrontFromName(sName As String) As CheckBox
      Select Case sName
         Case "F1"
            Return F1
         Case "F2"
            Return F2
         Case "F3"
            Return F3
         Case "F4"
            Return F4
         Case "F5"
            Return F5
         Case "F6"
            Return F6
         Case "F7"
            Return F7
         Case "F8"
            Return F8
         Case "F9"
            Return F9
         Case Else
            Return F10
      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

#End Region    ' Chiamata elle Text/Check/Label

#Region "SELEZIONE CHECKBOX"

   ' Per gestire la selezione/deselezione delle Alzatine
   Private Sub A_Checked(sender As Object, e As RoutedEventArgs) Handles A1.Checked, A2.Checked, A3.Checked, A4.Checked, A5.Checked, A6.Checked, A7.Checked, A8.Checked, A9.Checked, A10.Checked,
                                                                         A1.Unchecked, A2.Unchecked, A3.Unchecked, A4.Unchecked, A5.Unchecked, A6.Unchecked, A7.Unchecked, A8.Unchecked, A9.Unchecked, A10.Unchecked
      ' recupero il nome della Check selezionata
      Dim bIsAlzatina As Boolean = True
      Dim sChName As String = DirectCast(sender, CheckBox).Name
      Dim bIsChecked As Boolean = DirectCast(sender, CheckBox).IsChecked
      Dim sSideName As String = GetSideFromCheck(sChName, bIsAlzatina)
      Dim sOppositeCheckBox As String = GetOppositeCheck(sChName, bIsAlzatina)
      ' se la modifica della stato della checkbox avviene internamente al programma allora non devo eseguire nessun aggiornamento
      If bInternalSelection Then
         bInternalSelection = False
         Return
      End If
      RefreshList(sSideName, sOppositeCheckBox, bIsAlzatina, bIsChecked)

      EgtZoom(ZM.ALL)
   End Sub

   ' Per gestire la selezione/deselezione dei Frontalini
   Private Sub F_Checked(sender As Object, e As RoutedEventArgs) Handles F1.Checked, F2.Checked, F3.Checked, F4.Checked, F5.Checked, F6.Checked, F7.Checked, F8.Checked, F9.Checked, F10.Checked,
                                                                         F1.Unchecked, F2.Unchecked, F3.Unchecked, F4.Unchecked, F5.Unchecked, F6.Unchecked, F7.Unchecked, F8.Unchecked, F9.Unchecked, F10.Unchecked
      ' recupero il nome della Check selezionata
      Dim bIsAlzatina As Boolean = False
      Dim sChName As String = DirectCast(sender, CheckBox).Name
      Dim bIsChecked As Boolean = DirectCast(sender, CheckBox).IsChecked
      Dim sSideName As String = GetSideFromCheck(sChName, bIsAlzatina)
      Dim sOppositeCheckBox As String = GetOppositeCheck(sChName, bIsAlzatina)
      ' se la modifica della stato della checkbox avviene internamente al programma allora non devo eseguire nessun aggiornamento
      If bInternalSelection Then
         bInternalSelection = False
         Return
      End If
      RefreshList(sSideName, sOppositeCheckBox, bIsAlzatina, bIsChecked)

      EgtZoom(ZM.ALL)
   End Sub

#End Region    ' Selezione CheckBox

#Region "ALTEZZA, DELTA ANGOLO DI SPOGLIA"

   ' altezza ALZATINA
   Private Sub ParameterA1TxBx_EgtClosed(sender As Object, e As EventArgs) Handles Parameter1ATxBx.EgtClosed
      ' Nuovo angolo di inclinazione
      Dim dValue As Double
      StringToDouble(Parameter1ATxBx.Text, dValue)
      ' salvo il valore nel file ini e inserisco il valore nel file lua
      WritePrivateProfileString("Alz&Front", "A_Height", Parameter1ATxBx.Text, m_MainWindow.GetIniFile())
      ' aggiorno il disegno
      LoadCurrentCompo()
   End Sub

   ' altezza FRONTALINO
   Private Sub Parameter1FTxBx_EgtClosed(sender As Object, e As EventArgs) Handles Parameter1FTxBx.EgtClosed
      ' Nuovo angolo di inclinazione
      Dim dValue As Double
      StringToDouble(Parameter1FTxBx.Text, dValue)
      ' salvo il valore nel file ini e inserisco il valore nel file lua
      WritePrivateProfileString("Alz&Front", "F_Height", Parameter1FTxBx.Text, m_MainWindow.GetIniFile())
      ' aggiorno il disegno
      LoadCurrentCompo()
   End Sub

   ' angolo di spoglia ALZATINA
   Private Sub ParameterA2TxBx_EgtClosed(sender As Object, e As EventArgs) Handles Parameter2ATxBx.EgtClosed
      ' Nuovo angolo di inclinazione
      Dim dValue As Double
      StringToDouble(Parameter2ATxBx.Text, dValue)
      ' salvo il valore nel file ini e inserisco il valore nel file lua
      WritePrivateProfileString("Alz&Front", "A_DeltaAng", Parameter2ATxBx.Text, m_MainWindow.GetIniFile())
      ' aggiorno il disegno
      LoadCurrentCompo()
   End Sub

   ' angolo di spoglia FRONTALINO
   Private Sub Parameter2FTxBx_EgtClosed(sender As Object, e As EventArgs) Handles Parameter2FTxBx.EgtClosed
      ' Nuovo angolo di inclinazione
      Dim dValue As Double
      StringToDouble(Parameter2FTxBx.Text, dValue)
      ' salvo il valore nel file ini e inserisco il valore nel file lua
      WritePrivateProfileString("Alz&Front", "F_DeltaAng", Parameter2FTxBx.Text, m_MainWindow.GetIniFile())
      ' aggiorno il disegno
      LoadCurrentCompo()
   End Sub

   Private Sub Parameter5TxBx_EgtClosed(sender As Object, e As EventArgs) Handles Parameter5TxBx.EgtClosed
      Dim dValue As Double
      StringToDouble(Parameter5TxBx.Text, dValue)
      ' aggiorno il disegno
      LoadCurrentCompo()
   End Sub

#End Region    ' Altezza, delta angolo di spoglia

#Region "METHODS"

   ' noto il nome della checkbox (scritta nel codice xaml) selezionata restituisce il nome del lato (associato al disegno)
   Private Function GetSideFromCheck(sNameCheck As String, bIsAlz As Boolean) As String
      Dim sSideName As String = String.Empty
      Dim sTypeCheck As String = "A"
      If Not bIsAlz Then
         sTypeCheck = "F"
      End If
      ' separo il nome in due
      Dim sItems As String() = Split(sNameCheck, sTypeCheck)
      Dim nIndex As Integer
      ' costruisco il nome del lato
      If sItems.Count > 1 Then
         nIndex = CInt(sItems(1))
         nIndex = nIndex - (MAX_LINES - m_nShow)
         sSideName = "A" & nIndex.ToString
      End If

      Return sSideName
   End Function

   ' restituisce il nome del check opposto (Se passo una alzaztina restituisco il nome della checbox del frontalino)
   Private Function GetOppositeCheck(sNameCheck As String, bIsAlz As Boolean) As String
      Dim sSideName As String = String.Empty
      Dim sTypeCheck As String = "A"
      If Not bIsAlz Then
         sTypeCheck = "F"
      End If
      ' separo il nome in due
      Dim sItems As String() = Split(sNameCheck, sTypeCheck)

      ' estraggo l'indice del lato selezionato e costruisco il nome del CheckBox opposto
      If sItems.Count > 1 Then
         If bIsAlz Then
            sSideName = "F" & sItems(1).Trim
         Else
            sSideName = "A" & sItems(1).Trim
         End If

      End If

      Return sSideName
   End Function

   Private Sub InitList()
      ' quando avvio la pagina inizializzo tutti i lati comunicando che non sono stati modificati
      For j As Integer = 0 To AlzFrontEntityList.Count() - 1
         EgtSetInfo(AlzFrontEntityList(j).Id, "IsModify", 0)
      Next
   End Sub

   ' aggiorno lo stato della dell'oggetto
   Private Sub RefreshList(sSideName As String, sOppositeNameCheck As String, bIsAlz As Boolean, bIsChecked As Boolean)
      For j As Integer = 0 To AlzFrontEntityList.Count() - 1
         If AlzFrontEntityList(j).SideName = sSideName Then
            ' se deseleziono
            If Not bIsChecked Then
               AlzFrontEntityList(j).Type = AlzFrontEntity.AlzFront.NONE
               ' insrisco l'informazione nelle info del lato
               EgtSetInfo(AlzFrontEntityList(j).Id, INFO_ALZFRONT, 0)
               EgtSetInfo(AlzFrontEntityList(j).Id, "IsModify", 1)
               Exit For
            End If
            ' se selezione di Alz. o Front.
            If bIsAlz Then
               AlzFrontEntityList(j).Type = AlzFrontEntity.AlzFront.ALZATINA
               ' deseleziono il Check opposto
               If GetChBxFrontFromName(sOppositeNameCheck).IsChecked Then
                  bInternalSelection = True
                  GetChBxFrontFromName(sOppositeNameCheck).IsChecked = False
               End If
               ' insrisco l'informazione nelle info del lato
               EgtSetInfo(AlzFrontEntityList(j).Id, INFO_ALZFRONT, 1)
               EgtSetInfo(AlzFrontEntityList(j).Id, "IsModify", 1)
            Else
               AlzFrontEntityList(j).Type = AlzFrontEntity.AlzFront.FRONTALINO
               ' deseleziono il Check opposto
               If GetChBxAalZFromName(sOppositeNameCheck).IsChecked Then
                  bInternalSelection = True
                  GetChBxAalZFromName(sOppositeNameCheck).IsChecked = False
               End If
               ' inserisco l'informazione nelle info del lato
               EgtSetInfo(AlzFrontEntityList(j).Id, INFO_ALZFRONT, 2)
               EgtSetInfo(AlzFrontEntityList(j).Id, "IsModify", 1)
            End If
            ' termino il ciclo
            Exit For
         End If
      Next
      ' questa funzione deve essere lanciata al termine di ogno selezione o modifica dei parametri di dimensione
      LoadCurrentCompo()
   End Sub

#End Region   ' Methods

   ' eseguo il file per generare le Alzatine e i Frontalini (stesso file Lua)
   Private Sub LoadCurrentCompo()
      ' !! ATTENZIONE !! : per problemi di spazio è stata spenta la text per stampare i messaggi (ma potrebbe servire?)
      ' Pulisco l'ambiente lua
      EgtLuaResetGlobVar(LUA_CMP_VARS)
      EgtLuaResetGlobVar(LUA_CMP_DRAW)

      Dim nCompoName As Integer
      Dim sCompoFile As String = ""
      Dim sCompoImage As String = ""

      ' recupero il nome del direttorio
      Dim sCompoDir As String = String.Empty
      GetPrivateProfileString(S_ALZFRONT, K_COMPODIR, "", sCompoDir, m_MainWindow.GetIniFile())
      ' leggo le info inserite nel campo "Alz&Front"
      m_MainWindow.m_DrawPageUC.m_MainComponentPage.GetPrivateProfileCompo(S_ALZFRONT, K_ALZFRONT, nCompoName, sCompoFile, sCompoImage, m_MainWindow.GetIniFile())
      'Dim sCompoImageSource As ImageSource

      ' Costruisco path completa del componente
      Dim sPath = sCompoDir & "\" & sCompoFile
      ' Carico il file
      EgtLuaExecFile(sPath)

      ' carico la lista di variabili
      Dim dVal As Double
      If StringToLen(Parameter1ATxBx.Text, dVal) Then
         EgtLuaSetGlobNumVar("CMP.A_Height", dVal)
      End If
      If StringToLen(Parameter1FTxBx.Text, dVal) Then
         EgtLuaSetGlobNumVar("CMP.F_Height", dVal)
      End If
      If StringToLen(Parameter2ATxBx.Text, dVal) Then
         EgtLuaSetGlobNumVar("CMP.A_DeltaAng", dVal)
      End If
      If StringToLen(Parameter2FTxBx.Text, dVal) Then
         EgtLuaSetGlobNumVar("CMP.F_DeltaAng", dVal)
      End If
      If StringToLen(Parameter5TxBx.Text, dVal) Then
         EgtLuaSetGlobNumVar("CMP.ThicknessRaw", dVal)
      End If
      ' parametri per la scrittura dei caratteri
      EgtLuaSetGlobNumVar("CMP.BBoxRad", m_dBBoxRad)
      EgtLuaSetGlobNumVar("CMP.HeightText", m_dH)


      Dim sMsg As String = String.Empty
      ' eseguo la funzione per il disegno della componente (CMP_Draw)
      If Not EgtLuaExecLine(LUA_CMP_DRAW & "(true)") Then
         sMsg = "Error in component execution"
         m_bDrawOk = False
      Else
         EgtLuaGetGlobStringVar(LUA_CMP_VARS & ".MSG", sMsg)
         Dim nErr As Integer = 0
         EgtLuaGetGlobIntVar(LUA_CMP_VARS & ".ERR", nErr)
         m_bDrawOk = (nErr = 0)
      End If
      ' aggiorno la grafica
      EgtZoom(ZM.ALL)
   End Sub


   ' metodo utilizzato per tornare indietro alla pagina di selezione "CompoInterni/Alz&Front"
   Private Sub BackBtn_Click(sender As Object, e As RoutedEventArgs) Handles BackBtn.Click
      m_MainWindow.m_DrawPageUC.m_SceneButtons.MeasureBtn.IsChecked = False

      ' torno alla pagina iniziale di selezione del piano (Compo)
      'm_MainWindow.m_DrawPageUC.BackBtn_Click(sender, e)

      '--------- NUOVA GESTIONE ---------
      ' rimuovo l'elenco di bottoni per selezionare il tipo di componente interna
      m_MainWindow.m_DrawPageUC.LeftButtonGrd.Children.Remove(Me)
      ' inserisco nella Grid VaribalsesGrid lo UeserControl per definire le dimensioni della componente
      m_MainWindow.m_DrawPageUC.VariablesGrd.Children.Add(m_MainWindow.m_DrawPageUC.m_CompoDimension)
      ' nascondo la lista dei parametri
      m_MainWindow.m_DrawPageUC.m_CompoDimension.CollapsedAllParam()
      ' sto uscendo dalla componente interna (quindi comunico il cambio di componente)
      m_MainWindow.m_DrawPageUC.m_bInternalCompo = False
      ' comunico che sto arrivando da una componente interna
      m_MainWindow.m_DrawPageUC.m_bBackFromInternalCompo = True

      'm_MainWindow.m_DrawPageUC.SelectedComponent(m_MainWindow.m_DrawPageUC.m_sMainCompo)
      'm_MainWindow.m_DrawPageUC.m_ActiveComponentPage = DrawPageUC.Pages.CompoDimension
   End Sub



End Class

Public Class AlzFrontEntity
   Public Enum AlzFront
      ALZATINA
      FRONTALINO
      NONE
   End Enum

   Private m_SideName As String
   Private m_Id As Integer
   Private m_Type As AlzFront = AlzFront.NONE

   ' nome del lato scritto nel file nge (il nome deve avere la forma: A1, A2, .., An)
   Public Property SideName As String
      Get
         Return m_SideName
      End Get
      Set(value As String)
         m_SideName = value
      End Set
   End Property

   Public Property Type As AlzFront
      Get
         Return m_Type
      End Get
      Set(value As AlzFront)
         m_Type = value
      End Set
   End Property

   Public Property Id As Integer
      Get
         Return m_Id
      End Get
      Set(value As Integer)
         m_Id = value
      End Set
   End Property

   Sub New(Name As String, CurrId As Integer, Optional CurrType As AlzFront = AlzFront.NONE)
      m_SideName = Name
      m_Id = CurrId
      m_Type = CurrType
   End Sub

End Class