Imports System.Collections.ObjectModel
Imports System.Collections.Specialized
Imports System.ComponentModel
Imports System.Windows.Threading
Imports EgtBEAMWALL.Core
Imports EgtUILib
Imports EgtWPFLib5

Public Class BTLStructureVM
   Inherits VMBase

#Region "FIELDS & PROPERTIES"

   Friend Enum SelectionTypes As Integer
      NULL = 0
      SELECT_ = 1
      HIGHLIGHT = 2
   End Enum

   Private m_Calc_PartEnd As New DispatcherTimer

   Private WithEvents m_BTLStructureM As BTLStructureM
   Public ReadOnly Property BTLStructureM As BTLStructureM
      Get
         Return m_BTLStructureM
      End Get
   End Property

   ' pezzi da BTL
   Private m_BTLPartVMList_View As CollectionView = Nothing
   Public ReadOnly Property BTLPartVMList_View As CollectionView
      Get
         Return m_BTLPartVMList_View
      End Get
   End Property

   Private m_BTLPartVMList As ObservableCollection(Of BTLPartVM)
   Public Property BTLPartVMList As ObservableCollection(Of BTLPartVM)
      Get
         Return m_BTLPartVMList
      End Get
      Set(value As ObservableCollection(Of BTLPartVM))
         m_BTLPartVMList = value
      End Set
   End Property

   Private m_bOnlySelectItem As Boolean = False
   Public Property bOnlySelectItem As Boolean
      Get
         Return m_bOnlySelectItem
      End Get
      Set(value As Boolean)
         m_bOnlySelectItem = value
      End Set
   End Property
   Private m_PrevSelectionType As SelectionTypes = SelectionTypes.NULL
   Friend ReadOnly Property PrevSelectionType As SelectionTypes
      Get
         Return m_PrevSelectionType
      End Get
   End Property
   Private m_SelectionType As SelectionTypes = SelectionTypes.NULL
   Friend ReadOnly Property SelectionType As SelectionTypes
      Get
         Return m_SelectionType
      End Get
   End Property
   Friend Sub SetSelectionType(value As SelectionTypes)
      m_PrevSelectionType = m_SelectionType
      If value = m_SelectionType Then Return
      m_SelectionType = value
      Select Case m_SelectionType
         Case SelectionTypes.SELECT_
            ' verifico reset mark su tutti i pezzi
            For Each BTLPart In m_BTLPartVMList
               EgtResetMark(BTLPart.nPartId)
            Next
            ' mostro barra di gestione pezzo
            Map.refProjectVM.NotifyPropertyChanged(NameOf(Map.refProjectVM.PartManager_Visibility))
         Case SelectionTypes.HIGHLIGHT
            If m_PrevSelectionType = SelectionTypes.SELECT_ Then
               EgtBeamShowFacesName( False)
               EgtBeamShowLoadingSide( False, False)
            End If
            If Not IsNothing(m_SelBTLPart) Then
               m_SelBTLPart = Nothing
               NotifyPropertyChanged(NameOf(SelBTLPart))
            End If
            ' mostro pezzi selezionati
            Map.refProjectVM.BTLStructureVM.ShowAll(False)
            ' se attivata opzione, li assemblo
            Map.refProjectVM.BTLStructureVM.ShowBuilding(If(Map.refMainMenuVM.SelPage = Pages.VIEW, Map.refShowBeamPanelVM.ShowBuilding_IsChecked, False), False)
            ' nascondo barra di gestione pezzo
            Map.refProjectVM.NotifyPropertyChanged(NameOf(Map.refProjectVM.PartManager_Visibility))
      End Select
      ' aggiornamento grafica
      Map.refLeftPanelVM.PartShowAllChanged()
      Map.refLeftPanelVM.FeatureSelectionChanged()
      Map.refCALCPanelVM.SetIsEnabledForSelPart()
      Map.refProjectVM.NotifyPropertyChanged(NameOf(Map.refProjectVM.PartManager_Visibility))
   End Sub

   Private m_SelBTLParts As New PartsObservableCollection(Of BTLPartVM)
   Public ReadOnly Property SelBTLParts As PartsObservableCollection(Of BTLPartVM)
      Get
         Return m_SelBTLParts
      End Get
   End Property

   Private m_SelBTLPartsCnt As Integer = Nothing
   Public ReadOnly Property SelBTLPartsCnt As Integer
      Get
         Return m_SelBTLPartsCnt
      End Get
   End Property
   Friend Sub UpdateSelBTLParts(Optional bFromSelPart As Boolean = False, Optional bByOptim As Boolean = False)
      Dim nOldSelCount As Integer = m_SelBTLPartsCnt
      Dim nSelCount As Integer = BTLPartVMList.LongCount(Function(x) x.IsSelected)
      m_SelBTLPartsCnt = nSelCount
      If Not bByOptim AndAlso (nOldSelCount <> nSelCount AndAlso (nOldSelCount = 1 OrElse nSelCount = 1)) OrElse bFromSelPart Then
         Map.refLeftPanelVM.PartShowAllChanged()
         Map.refLeftPanelVM.FeatureSelectionChanged()
         Map.refCALCPanelVM.SetIsEnabledForSelPart()
         Map.refProjectVM.NotifyPropertyChanged(NameOf(Map.refProjectVM.PartManager_Visibility))
      End If
      If nSelCount = 1 Then
         If bByOptim Then
            m_SelBTLPart = BTLPartVMList.FirstOrDefault(Function(x) x.IsSelected)
         Else
            SelBTLPart = BTLPartVMList.FirstOrDefault(Function(x) x.IsSelected)
         End If
      Else
         If bByOptim Then
            m_SelBTLPart = Nothing
         Else
            SelBTLPart = Nothing
            ' mostro in parte bassa dati BTL
            Map.refBottomPanelVM.SetSelPartFeatureTab(BottomPanelVM.PartFeatureTab.STRUCTURE_)
            ' mostro pezzi selezionati
            Map.refProjectVM.BTLStructureVM.ShowAll(False, True)
            Core.ViewPanelVM.BWSetView(VT.ISO_SW, False)
            EgtZoom(ZM.ALL)
         End If
         NotifyPropertyChanged(NameOf(SelBTLPart))
      End If
   End Sub

   Private Sub SelBTLParts_CollectionChanged(sender As Object, e As NotifyCollectionChangedEventArgs)
      If m_bOnlySelectItem Then Return
      Select Case e.Action
         Case NotifyCollectionChangedAction.Add
            If e.NewItems.Count > 0 AndAlso Not IsNothing(e.NewItems(0)) Then
               If (Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso m_SelectionType = SelectionTypes.SELECT_) OrElse Map.refMainMenuVM.SelPage = Pages.MACHINING Then
                  SelectBTLPart(e.NewItems(0))
               Else     ' SelectionTypes.HIGHLIGHT
                  HighlightBTLPart(e.NewItems(0))
               End If
            End If
         Case NotifyCollectionChangedAction.Remove
            If e.OldItems.Count > 0 AndAlso Not IsNothing(e.OldItems(0)) Then
               If (Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso m_PrevSelectionType = SelectionTypes.SELECT_) OrElse Map.refMainMenuVM.SelPage = Pages.MACHINING Then
                  DeselectBTLPart(e.OldItems(0))
               Else     ' SelectionTypes.HIGHLIGHT
                  DeHighlightBTLPart(e.OldItems(0))
               End If
            End If
         Case NotifyCollectionChangedAction.Reset
            If (Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso m_PrevSelectionType = SelectionTypes.SELECT_) OrElse Map.refMainMenuVM.SelPage = Pages.MACHINING Then
               If Not IsNothing(m_SelBTLPart) Then
                  DeselectBTLPart(m_SelBTLPart)
               End If
            Else     ' SelectionTypes.HIGHLIGHT
               For Each BTLPart In m_BTLPartVMList
                  DeHighlightBTLPart(BTLPart, False)
               Next
               EgtDraw()
            End If
            SelBTLPart = Nothing
      End Select
      ' aggiornamento grafica
      Map.refLeftPanelVM.PartShowAllChanged()
   End Sub

   Private Sub SelectBTLPart(BtlPart As BTLPartVM)
      EgtBeamShowFacesName( False)
      EgtBeamShowLoadingSide( False, False)
      m_SelBTLPart = BtlPart
      If Map.refMainMenuVM.SelPage = Pages.VIEW Then
         ' se modalità building, la tolgo
         If Map.refShowBeamPanelVM.ShowBuilding_IsChecked Then
            ShowBuilding(False, False)
         End If
         ' seleziono pezzo nella scena
         SceneSelPartSelection()
         ' seleziono pezzo in Db geometrico
         EgtBeamSetPart(BtlPart.nPartId)
         EgtBeamShowFacesName( True)
         Dim bLoadingSideShow As Boolean = (nPROJTYPE = BWType.BEAM)
         Dim bLeftToRight As Boolean = Not ( CurrentMachine.ViewDir = VT.ISO_NW OrElse CurrentMachine.ViewDir = VT.ISO_NE)
         EgtBeamShowLoadingSide( bLoadingSideShow, bLeftToRight)
         ' seleziono pagina BottomPanel
         Map.refBottomPanelVM.SetSelPartFeatureTab(BottomPanelVM.PartFeatureTab.PART)
         '' mostro barra di gestione pezzo
         'Map.refProjectVM.NotifyPropertyChanged(NameOf(Map.refProjectVM.PartManager_Visibility))
         ' deseleziono le feature
         If Not IsNothing(BtlPart.SelBTLFeatureVM) Then SelBTLPart.SelBTLFeatureVM = Nothing
         ' aggiorno stato selezionato tutto
         Map.refShowBeamPanelVM.bShowAll = False
         Core.ViewPanelVM.BWSetView(If(Core.ViewPanelVM.Type = BWType.BEAM, VT.ISO_SW, VT.TOP), False)
         EgtZoom(ZM.ALL)
      ElseIf Map.refMainMenuVM.SelPage = Pages.MACHINING Then
         ' resetto gruppo di lavorazione corrente
         EgtResetCurrMachGroup()
         ' trovo ed evidenzio MachGroup e Duplo di questo pezzo
         If Not IsNothing(Map.refProjectVM.MachGroupPanelVM) Then
            Dim MachGroupList As New List(Of MyMachGroupVM)
            For Each Machgroup As MyMachGroupVM In Map.refProjectVM.MachGroupPanelVM.MachGroupVMList
               Dim bFound As Boolean = False
               For Each Part As PartVM In Machgroup.PartVMList
                  If EgtDuploGetOriginal(Part.nPartId) = BtlPart.nPartId Then
                     Part.SetSearchFound()
                     bFound = True
                  Else
                     Part.ResetSearchFound()
                  End If
               Next
               If bFound Then
                  Machgroup.SetSearchFound()
               Else
                  Machgroup.ResetSearchFound()
               End If
            Next
         End If
         ' seleziono pezzo nella scena
         SceneSelPartSelection()
         Core.ViewPanelVM.BWSetView(If(Core.ViewPanelVM.Type = BWType.BEAM, VT.ISO_SW, VT.TOP), False)
         EgtZoom(ZM.ALL)
      End If
      NotifyPropertyChanged(NameOf(SelBTLPart))
   End Sub
   Private Sub DeselectBTLPart(BtlPart As BTLPartVM)
      ' se necessario tolgo solido dal precedentemente selezionato
      If Map.refShowBeamPanelVM.ShowSolid_IsChecked Then
         ' tolgo eventuale indicazione solido rimasta da pezzo precedente
         Map.refShowBeamPanelVM.SetShowSolid(False)
         Map.refProjectVM.BTLStructureVM.ShowSolid(BtlPart.nPartId, False, False)
      End If
      If m_SelBTLPart Is BtlPart Then
         EgtBeamShowFacesName( False)
         EgtBeamShowLoadingSide( False, False)
         m_SelBTLPart = Nothing
         NotifyPropertyChanged(NameOf(SelBTLPart))
      End If
      ' disabilito eventuale feature selezionata 
      If Not IsNothing(BtlPart.m_SelBTLFeatureVM) Then BtlPart.SelBTLFeatureVM = Nothing
      EgtDraw()
   End Sub
   Private Sub HighlightBTLPart(BtlPart As BTLPartVM)
      EgtSetMark(BtlPart.nPartId)
      ' se modalità building
      If Map.refShowBeamPanelVM.ShowBuilding_IsChecked Then
         ' evidenzio anche copie
         Dim nNextPartId As Integer = EgtGetNext(BtlPart.nPartId)
         While nNextPartId <> GDB_ID.NULL
            Dim nOrigId As Integer = GDB_ID.NULL
            If EgtGetInfo(nNextPartId, "!COP", nOrigId) AndAlso nOrigId <> GDB_ID.NULL AndAlso nOrigId = BtlPart.nPartId Then
               EgtSetMark(nNextPartId)
            Else
               Exit While
            End If
            nNextPartId = EgtGetNext(nNextPartId)
         End While
      End If
      ' seleziono pagina BottomPanel
      Map.refBottomPanelVM.SetSelPartFeatureTab(BottomPanelVM.PartFeatureTab.NULL)
      EgtDraw()
   End Sub
   Private Sub DeHighlightBTLPart(BtlPart As BTLPartVM, Optional bDraw As Boolean = True)
      EgtResetMark(BtlPart.nPartId)
      ' se modalità building
      If Map.refShowBeamPanelVM.ShowBuilding_IsChecked Then
         ' evidenzio anche copie
         Dim nNextPartId As Integer = EgtGetNext(BtlPart.nPartId)
         While nNextPartId <> GDB_ID.NULL
            Dim nOrigId As Integer = GDB_ID.NULL
            If EgtGetInfo(nNextPartId, "!COP", nOrigId) AndAlso nOrigId <> GDB_ID.NULL AndAlso nOrigId = BtlPart.nPartId Then
               EgtResetMark(nNextPartId)
            Else
               Exit While
            End If
            nNextPartId = EgtGetNext(nNextPartId)
         End While
      End If
      ' seleziono pagina BottomPanel
      'Map.refBottomPanelVM.SetSelPartFeatureTab(BottomPanelVM.PartFeatureTab.NULL)
      If bDraw Then EgtDraw()
   End Sub

   Friend ReadOnly Property SelBTLPartList As List(Of BTLPartVM)
      Get
         Return m_BTLPartVMList.Where(Function(x) x.IsSelected).ToList()
      End Get
   End Property

   Private m_SelBTLPart As BTLPartVM = Nothing
   Public Property SelBTLPart As BTLPartVM
      Get
         Return m_SelBTLPart
      End Get
      Set(value As BTLPartVM)
         If Not IsNothing(m_SelBTLPart) Then
            ' se necessario tolgo solido dal precedentemente selezionato
            If Map.refShowBeamPanelVM.ShowSolid_IsChecked Then
               Map.refShowBeamPanelVM.SetShowSolid(False)
            End If
            ' disabilito eventuale feature selezionata 
            If Not IsNothing(m_SelBTLPart.m_SelBTLFeatureVM) Then m_SelBTLPart.SelBTLFeatureVM = Nothing
         End If
         m_SelBTLPart = value
         ' se seleziono un pezzo
         If Not IsNothing(m_SelBTLPart) Then
            If Map.refMainMenuVM.SelPage = Pages.VIEW Then
               ' se modalità building, la tolgo
               If Map.refShowBeamPanelVM.ShowBuilding_IsChecked Then
                  ShowBuilding(False, False)
               End If
               ' seleziono pezzo nella scena
               SceneSelPartSelection()
               ' seleziono pezzo in Db geometrico
               EgtBeamSetPart(m_SelBTLPart.nPartId)
               ' seleziono pagina BottomPanel
               Map.refBottomPanelVM.SetSelPartFeatureTab(BottomPanelVM.PartFeatureTab.PART)
               ' mostro barra di gestione pezzo
               Map.refProjectVM.NotifyPropertyChanged(NameOf(Map.refProjectVM.PartManager_Visibility))
               ' deseleziono le feature
               If Not IsNothing(m_SelBTLPart.SelBTLFeatureVM) Then SelBTLPart.SelBTLFeatureVM = Nothing
               ' aggiorno stato selezionato tutto
               Map.refShowBeamPanelVM.bShowAll = False
               Core.ViewPanelVM.BWSetView(If(Core.ViewPanelVM.Type = BWType.BEAM, VT.ISO_SW, VT.TOP), False)
               EgtZoom(ZM.ALL)
            ElseIf Map.refMainMenuVM.SelPage = Pages.MACHINING Then
               ' resetto gruppo di lavorazione corrente
               EgtResetCurrMachGroup()
               ' trovo ed evidenzio MachGroup e Duplo di questo pezzo
               If Not IsNothing(Map.refProjectVM.MachGroupPanelVM) Then
                  Dim MachGroupList As New List(Of MyMachGroupVM)
                  For Each Machgroup As MyMachGroupVM In Map.refProjectVM.MachGroupPanelVM.MachGroupVMList
                     Dim bFound As Boolean = False
                     For Each Part As PartVM In Machgroup.PartVMList
                        If EgtDuploGetOriginal(Part.nPartId) = m_SelBTLPart.nPartId Then
                           Part.SetSearchFound()
                           bFound = True
                        Else
                           Part.ResetSearchFound()
                        End If
                     Next
                     If bFound Then
                        Machgroup.SetSearchFound()
                     Else
                        Machgroup.ResetSearchFound()
                     End If
                  Next
               End If
               ' seleziono pezzo nella scena
               SceneSelPartSelection()
               Core.ViewPanelVM.BWSetView(If(Core.ViewPanelVM.Type = BWType.BEAM, VT.ISO_SW, VT.TOP), False)
               EgtZoom(ZM.ALL)
            End If
         End If
         NotifyPropertyChanged(NameOf(SelBTLPart))
      End Set
   End Property


   Friend Sub SetSelBTLPart(SelBTLPart As BTLPartVM, Optional bByOptim As Boolean = False, Optional bSingleHighlight As Boolean = False)
      If bByOptim Then
         ' annullo evidenziazione MachGroup e Duplo
         If Not IsNothing(Map.refProjectVM.MachGroupPanelVM) Then
            For Each Machgroup As MyMachGroupVM In Map.refProjectVM.MachGroupPanelVM.MachGroupVMList
               For Each Part As PartVM In Machgroup.PartVMList
                  Part.ResetSearchFound()
               Next
               Machgroup.ResetSearchFound()
            Next
         End If
      End If
      SetSelectionType(SelectionTypes.HIGHLIGHT)
      If bByOptim Then
         m_bOnlySelectItem = True
      End If
      If bByOptim Or bSingleHighlight Then
         If SelBTLParts.Contains(SelBTLPart) Then
            For Each Part In SelBTLParts.ToList()
               If Part IsNot SelBTLPart Then SelBTLParts.Remove(Part)
            Next
         Else
            SelBTLParts.Clear()
         End If
      End If

      If Not IsNothing(SelBTLPart) Then SelBTLParts.AddToList(SelBTLPart)

      If bByOptim Then
         m_bOnlySelectItem = False
      End If
   End Sub

   ' lista parametri per ricerca testuale
   Private m_SearchParamList As New ObservableCollection(Of IdNameStruct)({New IdNameStruct(BTLPartParam.NULL, ""),
                                                                           New IdNameStruct(BTLPartParam.PDN, EgtMsg(61809)),
                                                                           New IdNameStruct(BTLPartParam.NAM, EgtMsg(61603))})
   Public ReadOnly Property SearchParamList As ObservableCollection(Of IdNameStruct)
      Get
         Return m_SearchParamList
      End Get
   End Property

   Private m_SelSearchParam As IdNameStruct = m_SearchParamList(0)
   Public Property SelSearchParam As IdNameStruct
      Get
         Return m_SelSearchParam
      End Get
      Set(value As IdNameStruct)
         ' resetto il contenuto della barra di ricerca testuale e refresho la lista dei Part (in modo da averli visibili tutti)
         SearchText = ""
         NotifyPropertyChanged(NameOf(SearchText))
         ' ora setto il valore scelto come Parameter Type
         m_SelSearchParam = value
      End Set
   End Property

   ' lista dei gruppi
   Private m_GroupList_View As CollectionView = Nothing
   Private m_GroupList As New ObservableCollection(Of String)({""})
   Public Property GroupList As ObservableCollection(Of String)
      Get
         Return m_GroupList
      End Get
      Set(value As ObservableCollection(Of String))
         m_GroupList = value
      End Set
   End Property

   Private m_SelGroup As String = ""
   Public Property SelGroup As String
      Get
         Return m_SelGroup
      End Get
      Set(value As String)
         m_SelGroup = value
         m_BTLPartVMList_View.Refresh()
         m_SectionList_View.Refresh()
         m_SubGroupList_View.Refresh()
      End Set
   End Property

   ' lista dei SubGroup
   Private m_SubGroupList_View As CollectionView = Nothing
   Private m_SubGroupList As New ObservableCollection(Of String)({""})
   Public Property SubGroupList As ObservableCollection(Of String)
      Get
         Return m_SubGroupList
      End Get
      Set(value As ObservableCollection(Of String))
         m_SubGroupList = value
      End Set
   End Property

   Private m_SelSubGroup As String = ""
   Public Property SelSubGroup As String
      Get
         Return m_SelSubGroup
      End Get
      Set(value As String)
         m_SelSubGroup = value
         m_BTLPartVMList_View.Refresh()
         m_SectionList_View.Refresh()
         m_GroupList_View.Refresh()
      End Set
   End Property

   ' lista delle sezioni utilizzate
   Private m_SectionList_View As CollectionView = Nothing
   Private m_SectionList As New ObservableCollection(Of SectionXMaterial)({SectionXMaterial.Empty})
   Public Property SectionList As ObservableCollection(Of SectionXMaterial)
      Get
         Return m_SectionList
      End Get
      Set(value As ObservableCollection(Of SectionXMaterial))
         m_SectionList = value
      End Set
   End Property

   Private m_SelSection As SectionXMaterial = SectionXMaterial.Empty
   Public Property SelSection As SectionXMaterial
      Get
         Return m_SelSection
      End Get
      Set(value As SectionXMaterial)
         If Not IsNothing(value) Then
            m_SelSection = value
            m_BTLPartVMList_View.Refresh()
            m_GroupList_View.Refresh()
            m_SubGroupList_View.Refresh()
         End If
      End Set
   End Property
   Friend Sub SetSelSection(value As SectionXMaterial)
      If Not IsNothing(value) Then
         m_SelSection = value
         m_BTLPartVMList_View.Refresh()
         m_GroupList_View.Refresh()
         m_SubGroupList_View.Refresh()
      End If
      NotifyPropertyChanged(NameOf(SelSection))
   End Sub

   Private m_SearchText As String = ""
   Public Property SearchText As String
      Get
         Return m_SearchText
      End Get
      Set(value As String)
         m_SearchText = value
         m_BTLPartVMList_View.Refresh()
         m_GroupList_View.Refresh()
         m_SectionList_View.Refresh()
      End Set
   End Property

   Public Property bDOALL As Boolean?
      Get
         If BTLPartVMList.Count = 0 Then Return False
         Dim bTemp As Boolean = BTLPartVMList(0).bDO
         For FeatureIndex = 1 To BTLPartVMList.Count - 1
            If BTLPartVMList(FeatureIndex).bDO <> bTemp Then Return Nothing
         Next
         Return bTemp
      End Get
      Set(value As Boolean?)
         If BTLPartVMList.Count = 0 Then
            NotifyPropertyChanged(NameOf(bDOALL))
            Return
         End If
         For PartIndex = 0 To BTLPartVMList.Count - 1
            Dim Part As BTLPartVM = BTLPartVMList(PartIndex)
            If (IsNothing(m_SelSection) OrElse m_SelSection.dH = -1 OrElse Part.Section = m_SelSection) AndAlso
               (SelGroup = "" OrElse Part.sGROUP = SelGroup) AndAlso
               (SelSubGroup = "" OrElse Part.sSTOREY = SelSubGroup) AndAlso
               (SelSearchParam.Id = BTLPartParam.NULL OrElse SearchText = String.Empty OrElse (
               (SelSearchParam.Id = BTLPartParam.PDN AndAlso Part.nPDN.ToString.IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0) OrElse
               (SelSearchParam.Id = BTLPartParam.NAM AndAlso Part.sNAM.IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0))) Then
               Part.bDO = value
               Part.NotifyPropertyChanged(NameOf(Part.bDO))
            End If
         Next
      End Set
   End Property

#Region "Parametri generici"

   Public Property sPROJNUM As String
      Get
         Return m_BTLStructureM.m_sPROJNUM
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_PROJNUM, value) Then
            m_BTLStructureM.m_sPROJNUM = value
         Else
            NotifyPropertyChanged("sPROJNUM")
         End If
      End Set
   End Property

   Public Property sPROJNAME As String
      Get
         Return m_BTLStructureM.m_sPROJNAME
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_PROJNAME, value) Then
            m_BTLStructureM.m_sPROJNAME = value
         Else
            NotifyPropertyChanged("sPROJNAME")
         End If
      End Set
   End Property

   Public Property sPROJPART As String
      Get
         Return m_BTLStructureM.m_sPROJPART
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_PROJPART, value) Then
            m_BTLStructureM.m_sPROJPART = value
         Else
            NotifyPropertyChanged("sPROJPART")
         End If
      End Set
   End Property

   Public Property sPROJGUID As String
      Get
         Return m_BTLStructureM.m_sPROJGUID
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_PROJGUID, value) Then
            m_BTLStructureM.m_sPROJGUID = value
         Else
            NotifyPropertyChanged("sPROJGUID")
         End If
      End Set
   End Property

   Public ReadOnly Property nPROJTYPE As BWType
      Get
         Select Case Map.refMainMenuVM.SelPage
            Case Pages.VIEW
               Return Map.refProjManagerVM.nProjType
            Case Pages.MACHINING
               Return Map.refProdManagerVM.nProdType
            Case Else
               Return BWType.NULL
         End Select
         'Return m_BTLStructureM.m_nPROJTYPE
      End Get
      'Set(value As BWType)
      '   If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_PROJTYPE, value) Then
      '      m_BTLStructureM.m_nPROJTYPE = value
      '   Else
      '      NotifyPropertyChanged(NameOf(nPROJTYPE))
      '   End If
      'End Set
   End Property

   Public Property sLISTNAME As String
      Get
         Return m_BTLStructureM.m_sLISTNAME
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_LISTNAME, value) Then
            DbControllers.m_ProjController.UpdateListName(Map.refProjManagerVM.CurrProj.nProjId, value)
            m_BTLStructureM.m_sLISTNAME = value
         Else
            NotifyPropertyChanged("sLISTNAME")
         End If
      End Set
   End Property

   Public Property sCUSTOMER As String
      Get
         Return m_BTLStructureM.m_sCUSTOMER
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_CUSTOMER, value) Then
            m_BTLStructureM.m_sCUSTOMER = value
         Else
            NotifyPropertyChanged("sCUSTOMER")
         End If
      End Set
   End Property

   Public Property sARCHITECT As String
      Get
         Return m_BTLStructureM.m_sARCHITECT
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_ARCHITECT, value) Then
            m_BTLStructureM.m_sARCHITECT = value
         Else
            NotifyPropertyChanged("sARCHITECT")
         End If
      End Set
   End Property

   Public Property sEDITOR As String
      Get
         Return m_BTLStructureM.m_sEDITOR
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_EDITOR, value) Then
            m_BTLStructureM.m_sEDITOR = value
         Else
            NotifyPropertyChanged("sEDITOR")
         End If
      End Set
   End Property

   Public Property sDELIVDATE As String
      Get
         Return m_BTLStructureM.m_sDELIVDATE
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_DELIVDATE, value) Then
            m_BTLStructureM.m_sDELIVDATE = value
         Else
            NotifyPropertyChanged("sDELIVDATE")
         End If
      End Set
   End Property

   Public Property sEXPDATE As String
      Get
         Return m_BTLStructureM.m_sEXPDATE
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_EXPDATE, value) Then
            m_BTLStructureM.m_sEXPDATE = value
         Else
            NotifyPropertyChanged("sEXPDATE")
         End If
      End Set
   End Property

   Public Property sEXPTIME As String
      Get
         Return m_BTLStructureM.m_sEXPTIME
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_EXPTIME, value) Then
            m_BTLStructureM.m_sEXPTIME = value
         Else
            NotifyPropertyChanged("sEXPTIME")
         End If
      End Set
   End Property

   Public Property sEXPRELEASE As String
      Get
         Return m_BTLStructureM.m_sEXPRELEASE
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_EXPRELEASE, value) Then
            m_BTLStructureM.m_sEXPRELEASE = value
         Else
            NotifyPropertyChanged("sEXPRELEASE")
         End If
      End Set
   End Property

   Public Property sLANGUAGE As String
      Get
         Return m_BTLStructureM.m_sLANGUAGE
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_LANGUAGE, value) Then
            m_BTLStructureM.m_sLANGUAGE = value
         Else
            NotifyPropertyChanged("sLANGUAGE")
         End If
      End Set
   End Property

   Public ReadOnly Property ocRANGE As List(Of Object)
      Get
         Return m_BTLStructureM.ocRANGE
      End Get
   End Property

   Public Property SelRANGE As Integer
      Get
         Return m_BTLStructureM.m_SelRANGE
      End Get
      Set(value As Integer)
         Dim nValue As Integer = IdNameStruct.IdFromInd(value, m_BTLStructureM.ocRANGE)
         Dim sValue As String = [Enum].GetName(GetType(Range), nValue)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_RANGE, sValue) Then
            m_BTLStructureM.m_SelRANGE = value
         Else
            NotifyPropertyChanged("SelRANGE")
         End If
      End Set
   End Property

   Public ReadOnly Property ocPROCESSINGQUALITY As List(Of Object)
      Get
         Return m_BTLStructureM.ocPROCESSINGQUALITY
      End Get
   End Property

   Public Property SelPROCESSINGQUALITY As Integer
      Get
         Return m_BTLStructureM.m_SelPROCESSINGQUALITY
      End Get
      Set(value As Integer)
         Dim nValue As Integer = IdNameStruct.IdFromInd(value, m_BTLStructureM.ocPROCESSINGQUALITY)
         Dim sValue As String = [Enum].GetName(GetType(ProcessingQuality), nValue)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_PRT_PROCESSINGQUALITY, sValue) Then
            m_BTLStructureM.m_SelPROCESSINGQUALITY = value
         Else
            NotifyPropertyChanged("SelPROCESSINGQUALITY")
         End If
      End Set
   End Property

   Public Property sCOMPUTERNAME As String
      Get
         Return m_BTLStructureM.m_sCOMPUTERNAME
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_COMPUTERNAME, value) Then
            m_BTLStructureM.m_sCOMPUTERNAME = value
         Else
            NotifyPropertyChanged("sCOMPUTERNAME")
         End If
      End Set
   End Property

   Public Property sUSER As String
      Get
         Return m_BTLStructureM.m_sUSER
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_USER, value) Then
            m_BTLStructureM.m_sUSER = value
         Else
            NotifyPropertyChanged("sUSER")
         End If
      End Set
   End Property

   Public Property sSRCFILE As String
      Get
         Return m_BTLStructureM.m_sSRCFILE
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_SRCFILE, value) Then
            m_BTLStructureM.m_sSRCFILE = value
         Else
            NotifyPropertyChanged("sSRCFILE")
         End If
      End Set
   End Property

   Public Property sEXPFILE As String
      Get
         Return m_BTLStructureM.m_sEXPFILE
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_EXPFILE, value) Then
            m_BTLStructureM.m_sEXPFILE = value
         Else
            NotifyPropertyChanged("sEXPFILE")
         End If
      End Set
   End Property

   Public ReadOnly Property ocRECESS As List(Of Object)
      Get
         Return m_BTLStructureM.ocRECESS
      End Get
   End Property

   Public Property SelRECESS As Integer
      Get
         Return m_BTLStructureM.m_SelRECESS
      End Get
      Set(value As Integer)
         Dim nValue As Integer = IdNameStruct.IdFromInd(value, m_BTLStructureM.ocRECESS)
         Dim sValue As String = [Enum].GetName(GetType(Recess), nValue)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_PRT_RECESS, sValue) Then
            m_BTLStructureM.m_SelRECESS = value
         Else
            NotifyPropertyChanged("SelRECESS")
         End If
      End Set
   End Property

   Public Property sUSERATTRIBUTE As String
      Get
         Return m_BTLStructureM.m_sUSERATTRIBUTE
      End Get
      Set(value As String)
         If EgtSetInfo(m_BTLStructureM.nBTLInfoId, BTL_GEN_USERATTRIBUTE, value) Then
            m_BTLStructureM.m_sUSERATTRIBUTE = value
         Else
            NotifyPropertyChanged("sUSERATTRIBUTE")
         End If
      End Set
   End Property

   Public ReadOnly Property sBTLTotParts As String
      Get
         Return m_BTLPartVMList.Sum(Function(x) x.nCNT + x.nADDED)
      End Get
   End Property

   Public ReadOnly Property sBTLTotVolume As String
      Get
         Dim dMMTotVolume As Double = m_BTLPartVMList.Sum(Function(x) x.dUnitVolume * (x.nCNT + x.nADDED))
         Return If(EgtUiUnitsAreMM(), DoubleToString(dMMTotVolume / 1000000000, 3), DoubleToString(dMMTotVolume * (12 / ONEINCH), 3))
      End Get
   End Property

   Public ReadOnly Property dBTLTotTime As Double
      Get
         Return m_BTLPartVMList.Sum(Function(x) x.nCALC_TIME * (x.nCNT + x.nADDED))
      End Get
   End Property

   Public ReadOnly Property sBTLTotTime As String
      Get
         Return TimeSpan.FromSeconds(dBTLTotTime).ToString()
      End Get
   End Property

   Public ReadOnly Property sBTLDoneTime As String
      Get
         Return TimeSpan.FromSeconds(m_BTLPartVMList.Sum(Function(x) x.nCALC_TIME * x.nDONE)).ToString()
      End Get
   End Property

   Public ReadOnly Property sBTLRemainingTime As String
      Get
         Return TimeSpan.FromSeconds(dBTLTotTime - m_BTLPartVMList.Sum(Function(x) x.nCALC_TIME * x.nDONE)).ToString()
      End Get
   End Property

   Public ReadOnly Property sTotCNTParts As String
      Get
         Return m_BTLPartVMList.Sum(Function(x) x.nCNT)
      End Get
   End Property

   Public ReadOnly Property sTotADDEDParts As String
      Get
         Return m_BTLPartVMList.Sum(Function(x) x.nADDED)
      End Get
   End Property

   Public ReadOnly Property sTotINPRODParts As String
      Get
         Return m_BTLPartVMList.Sum(Function(x) x.nINPROD)
      End Get
   End Property

   Public ReadOnly Property sTotDONEParts As String
      Get
         Return m_BTLPartVMList.Sum(Function(x) x.nDONE)
      End Get
   End Property

#End Region ' Parametri generici

   ' Definizione comandi
   Private m_cmdDeletePart As ICommand

   Public ReadOnly Property PDN_Msg As String
      Get
         Return EgtMsg(61809)
      End Get
   End Property

#End Region

#Region "CONSTRUCTOR"

   Sub New(BTLStructureM As BTLStructureM)
      m_BTLStructureM = BTLStructureM
      AddHandler m_BTLStructureM.BTLPartAdded, AddressOf OnBTLPartAdded
      AddHandler m_SelBTLParts.CollectionChanged, AddressOf SelBTLParts_CollectionChanged
      ' creo lista di BTLPartVM
      CreateBTLPartVMList()
      m_BTLPartVMList_View = CollectionViewSource.GetDefaultView(m_BTLPartVMList)
      m_GroupList_View = CollectionViewSource.GetDefaultView(m_GroupList)
      m_SubGroupList_View = CollectionViewSource.GetDefaultView(m_SubGroupList)
      m_SectionList_View = CollectionViewSource.GetDefaultView(m_SectionList)
      m_BTLPartVMList_View.Filter = AddressOf PartFilter
      m_GroupList_View.Filter = AddressOf GroupFilter
      m_SectionList_View.Filter = AddressOf SectionFilter
      m_Calc_PartEnd.Interval = TimeSpan.FromMilliseconds(500)
      AddHandler m_Calc_PartEnd.Tick, AddressOf Calc_PartEnd_Tick
      m_Calc_PartEnd.Start()
      ' Aggiorno check DOALL
      NotifyPropertyChanged(NameOf(bDOALL))
      If BTLStructureM.nAsseBaseId = GDB_ID.NULL Then
         Map.refShowBeamPanelVM.SetShowBuilding(False)
      End If
   End Sub

#End Region    ' CONSTRUCTOR

#Region "METHODS"

   Private Sub CreateBTLPartVMList()
      Dim all As List(Of BTLPartVM) = (From BTLPartM In m_BTLStructureM.GetBTLParts()
                                       Select New BTLPartVM(BTLPartM, m_BTLStructureM)).ToList()

      For Each BTLPartVM As BTLPartVM In all
         AddHandler BTLPartVM.PropertyChanged, AddressOf OnBTLPartVMPropertyChanged
      Next

      m_BTLPartVMList = New ObservableCollection(Of BTLPartVM)(all)
      AddHandler m_BTLPartVMList.CollectionChanged, AddressOf OnBTLPartVMListChanged
   End Sub


   Friend Sub LoadFilters()
      For Each BTLPartVM As BTLPartVM In m_BTLPartVMList
         ' verifico sezione, gruppo e sottogruppo per inserirli nei filtri
         If Not SectionList.Contains(BTLPartVM.Section) Then
            SectionList.Add(BTLPartVM.Section)
         End If
         If Not GroupList.Contains(BTLPartVM.sGROUP) Then
            GroupList.Add(BTLPartVM.sGROUP)
         End If
         If Not SubGroupList.Contains(BTLPartVM.sSTOREY) Then
            SubGroupList.Add(BTLPartVM.sSTOREY)
         End If
      Next
   End Sub

   Private Sub Calc_PartEnd_Tick()
      ' se calcolo non in corso (mainmenu e' attivo), esco
      If Map.refMainMenuVM.MainMenu_IsEnabled Then Return
      ' aggiorno iconcina delle feature dei part che hanno finito calcolo
      For Each BTLPart In BTLPartVMList
         If BTLPart.Calc_PartEnd Then
            BTLPart.BTLFeatureVMList_View.Refresh()
            BTLPart.ResetCalcPartEnd()
         End If
      Next
   End Sub

   Private Sub SceneSelPartSelection()
      ' deseleziono tutto
      EgtDeselectAll()
      ' disabilito impostazione modificato
      Dim DisableMgr As New DisableModifiedMgr
      ' ciclo sui pezzi
      For Each Part As BTLPartVM In m_BTLPartVMList
         ' se non è quello selezionato, lo nasondo
         If Part IsNot m_SelBTLPart Then
            EgtSetMode(Part.nPartId, GDB_MD.HIDDEN)
         Else
            EgtSetMode(Part.nPartId, GDB_MD.STD)
         End If
      Next
      ' ripristino precedente impostazione modificato
      DisableMgr.ReEnable()
   End Sub

   Friend Sub ShowAll(Optional bRedraw As Boolean = True, Optional bOnlySelected As Boolean = False)
      ' disabilito impostazione modificato
      Dim DisableMgr As New DisableModifiedMgr
      If Not IsNothing(SelBTLPart) Then
         ' se pezzo solido, lo riporto normale
         If Map.refShowBeamPanelVM.ShowSolid_IsChecked Then
            Map.refShowBeamPanelVM.SetShowSolid(False)
         End If
         ' tolgo pezzo selezionato
         SelBTLPart.SelBTLFeatureVM = Nothing
      End If
      'If Not bOnlySelected Then SetSelBTLPart(Nothing)
      ' mostro tutti i pezzi
      ' creo lista id presenti
      Dim BTLPartIdList As List(Of Integer) = (From Part In BTLPartVMList
                                               Select Part.nPartId).ToList()
      BTLPartIdList.Sort()
      Dim nGeomPartId As Integer = EgtGetFirstPart()
      While nGeomPartId <> GDB_ID.NULL
         Dim CurrPart As BTLPartVM = BTLPartVMList.FirstOrDefault(Function(x) x.nPartId = nGeomPartId)
         If Not IsNothing(CurrPart) AndAlso (Not bOnlySelected OrElse (bOnlySelected AndAlso CurrPart.IsSelected)) Then
            Dim nMode As Integer
            EgtGetMode(CurrPart.nPartId, nMode)
            If nMode <> GDB_MD.STD Then
               EgtSetMode(CurrPart.nPartId, GDB_MD.STD)
            End If
         Else
            EgtSetMode(nGeomPartId, GDB_MD.HIDDEN)
         End If
         nGeomPartId = EgtGetNextPart(nGeomPartId)
      End While
      ' ripristino precedente impostazione modificato
      DisableMgr.ReEnable()
      Core.ViewPanelVM.BWSetView(VT.ISO_SW, False)
      EgtZoom(ZM.ALL, bRedraw)
      ' imposto stato per ShowBeamPanel
      If Not bOnlySelected Then Map.refShowBeamPanelVM.bShowAll = True
   End Sub

   Friend Sub HideAll(Optional bRedraw As Boolean = True)
      ' disabilito impostazione modificato
      Dim DisableMgr As New DisableModifiedMgr
      If Not IsNothing(SelBTLPart) Then
         ' se pezzo solido, lo riporto normale
         If Map.refShowBeamPanelVM.ShowSolid_IsChecked Then
            ShowSolid(GDB_ID.NULL, False, False)
            Map.refShowBeamPanelVM.SetShowSolid(False)
         End If
         ' tolgo pezzo selezionato
         SelBTLPart.SelBTLFeatureVM = Nothing
      End If
      SetSelBTLPart(Nothing)
      ' nascondo tutti i pezzi
      Dim nPartId As Integer = EgtGetFirstPart()
      While nPartId <> GDB_ID.NULL
         Dim nMode As Integer
         EgtGetMode(nPartId, nMode)
         If nMode <> GDB_MD.HIDDEN Then
            EgtSetMode(nPartId, GDB_MD.HIDDEN)
         End If
         nPartId = EgtGetNextPart(nPartId)
      End While
      'For Each Part As BTLPartVM In BTLPartVMList
      '   Dim nMode As Integer
      '   EgtGetMode(Part.nPartId, nMode)
      '   If nMode <> GDB_MD.HIDDEN Then
      '      EgtSetMode(Part.nPartId, GDB_MD.HIDDEN)
      '   End If
      'Next
      ' ripristino precedente impostazione modificato
      DisableMgr.ReEnable()
      Core.ViewPanelVM.BWSetView(VT.ISO_SW, False)
      EgtZoom(ZM.ALL, bRedraw)
      ' imposto stato per ShowBeamPanel
      Map.refShowBeamPanelVM.bShowAll = True
   End Sub

   Friend Sub ShowBuilding(bShow As Boolean, Optional bRedraw As Boolean = True)
      ' disabilito impostazione modificato
      Dim DisableMgr As New DisableModifiedMgr

      Dim bOn As Boolean = EgtBeamGetBuildingIsOn()
      If bShow <> bOn Then
         EgtBeamShowBuilding(bShow)
      End If

      ' ripristino precedente impostazione modificato
      DisableMgr.ReEnable()

      ' aggiorno visualizzazione
      Core.ViewPanelVM.BWSetView(VT.ISO_SW, False)
      EgtZoom(ZM.ALL, bRedraw)
   End Sub

   Friend Sub ShowSolid(nPartId As Integer, bShow As Boolean, Optional bRedraw As Boolean = True)
      ' se non viene passato, recupero il pezzo del primo oggetto selezionato
      If nPartId = GDB_ID.NULL And Not IsNothing(SelBTLPart) Then
         nPartId = SelBTLPart.nPartId
      End If
      If Not EgtIsPart(nPartId) Then
         Dim nLayerId As Integer = EgtGetParent(nPartId)
         Dim sLayerName As String = ""
         EgtGetName(nLayerId, sLayerName)
         If sLayerName <> ASSEBASE Then
            Map.refMyStatusBarVM.SetOutputMessage("ERROR: Nessuna trave selezionata ", 5, MSG_TYPE.ERROR_)
            Return
         End If
      End If
      EgtDeselectAll()

      ' disabilito impostazione modificato
      Dim DisableMgr As New DisableModifiedMgr

      If bShow Then EgtBeamCalcSolid(nPartId)

      EgtBeamShowSolid(nPartId, bShow)
      If bRedraw Then EgtDraw()

      ' ripristino precedente impostazione modificato
      DisableMgr.ReEnable()
   End Sub

   ' Funzione per regolarizzare, se necessario, la superficie della feature
   Private Function RegularizeTriMesh(SurfId As Integer, DestGrpId As Integer, dStep As Double) As Integer
      ' solo per superfici trimesh con poche facce (max4)
      Dim nFacetCnt As Integer = EgtSurfTmFacetCount(SurfId)
      If nFacetCnt > 4 Then
         Return SurfId
      End If
      ' box della superficie
      Dim b3Surf As New BBox3d
      EgtGetBBox(SurfId, GDB_BB.STANDARD, b3Surf)
      If b3Surf.IsEmpty() Or b3Surf.DimX() < 2 * dStep Then
         Return SurfId
      End If
      ' recupero le facce e le divido in X
      Dim dXmin As Double = b3Surf.Min().x - 1
      Dim dXmax As Double = b3Surf.Max().x + 1
      Dim nStep As Integer = CInt(Math.Floor((dXmax - dXmin) / dStep + 0.9))
      dStep = (dXmax - dXmin) / nStep
      Dim NewSurfId As Integer = GDB_ID.NULL
      For nF = 0 To nFacetCnt - 1
         Dim FacId As Integer = EgtCopySurfTmFacet(SurfId, nF, DestGrpId)
         Dim b3Fac As New BBox3d
         EgtGetBBox(FacId, GDB_BB.STANDARD, b3Fac)
         Dim dX2 As Double = dXmin
         For nI = 1 To nStep
            Dim dX1 As Double = dX2
            dX2 = dX2 + dStep
            If b3Fac.Min().x < dX2 And b3Fac.Max().x > dX1 Then
               EgtCutSurfTmPlane(FacId, New Point3d(dX1, 0, 0), -Vector3d.X_AX, True)
               EgtCutSurfTmPlane(FacId, New Point3d(dX2, 0, 0), Vector3d.X_AX, False)
               Dim nCount As Integer = 0
               Dim LoopId As Integer = EgtExtractSurfTmFacetLoops(FacId, 0, DestGrpId, nCount)
               EgtMergeCurvesInCurveCompo(LoopId, 0.001)
               Dim TmpSurfId As Integer = EgtCreateSurfTmByFlatContour(DestGrpId, LoopId, 0.01)
               EgtErase(LoopId)
               If NewSurfId <> GDB_ID.NULL Then
                  NewSurfId = EgtCreateSurfTmBySewing(DestGrpId, 2, {NewSurfId, TmpSurfId}, True)
               Else
                  NewSurfId = TmpSurfId
               End If
               EgtErase(FacId)
               FacId = EgtCopySurfTmFacet(SurfId, nF, DestGrpId)
            End If
         Next
         EgtErase(FacId)
      Next
      Return NewSurfId
   End Function

   Private Function PartFilter(Part As Object) As Boolean
      Dim CurrBTLPart As BTLPartVM = DirectCast(Part, BTLPartVM)
      Dim bGroupOk As Boolean = True
      Dim bSubGroupOk As Boolean = True
      Dim bSectionOk As Boolean = True
      Dim bSearchTextOk As Boolean = True
      If SelSection <> SectionXMaterial.Empty AndAlso CurrBTLPart.Section <> SelSection Then bSectionOk = False
      If SelGroup <> "" AndAlso CurrBTLPart.sGROUP <> SelGroup Then bGroupOk = False
      If SelSubGroup <> "" AndAlso CurrBTLPart.sSTOREY <> SelSubGroup Then bSubGroupOk = False
      If m_SelSearchParam.Id <> BTLPartParam.NULL AndAlso m_SearchText <> String.Empty AndAlso (
         (m_SelSearchParam.Id = BTLPartParam.PDN AndAlso CurrBTLPart.nPDN.ToString.IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) < 0) OrElse
         (m_SelSearchParam.Id = BTLPartParam.NAM AndAlso CurrBTLPart.sNAM.IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) < 0)) Then
         bSearchTextOk = False
      End If
      Dim bResult As Boolean = bSectionOk AndAlso bGroupOk AndAlso bSubGroupOk AndAlso bSearchTextOk
      If Not bResult And CurrBTLPart.IsSelected Then CurrBTLPart.IsSelected = False
      Return bResult
   End Function

   Private Function GroupFilter(Group As Object) As Boolean
      Dim CurrGroup As String = DirectCast(Group, String)
      Dim bOk As Boolean = True
      If CurrGroup <> "" AndAlso (SelSection <> SectionXMaterial.Empty OrElse SelSubGroup <> "" OrElse SearchText <> "") Then
         bOk = m_BTLPartVMList.Any(Function(x) x.sGROUP = CurrGroup AndAlso
                                               (SelSection = SectionXMaterial.Empty OrElse x.Section = SelSection) AndAlso
                                               (SelSubGroup = "" OrElse x.sSTOREY = SelSubGroup) AndAlso
                                               (SearchText = "" OrElse Not x.sNAM.IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0))
      End If
      Return bOk
   End Function

   Private Function SubGroupFilter(SubGroup As Object) As Boolean
      Dim CurrSubGroup As String = DirectCast(SubGroup, String)
      Dim bOk As Boolean = True
      If CurrSubGroup <> "" AndAlso (SelSection <> SectionXMaterial.Empty OrElse SearchText <> "" OrElse SelGroup <> "") Then
         bOk = m_BTLPartVMList.Any(Function(x) x.sGROUP = CurrSubGroup AndAlso
                                               (SelSection = SectionXMaterial.Empty OrElse x.Section = SelSection) AndAlso
                                               (SelGroup = "" OrElse x.sGROUP = SelGroup) AndAlso
                                               (SearchText = "" OrElse Not x.sNAM.IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0))
      End If
      Return bOk
   End Function

   Private Function SectionFilter(Section As Object) As Boolean
      Dim CurrSection As SectionXMaterial = DirectCast(Section, SectionXMaterial)
      Dim bOk As Boolean = True
      If CurrSection <> Section.Empty AndAlso (SelGroup <> "" OrElse SelSubGroup <> "" OrElse SearchText <> "") Then
         bOk = m_BTLPartVMList.Any(Function(x) x.Section = CurrSection AndAlso
                                               (SelGroup = "" OrElse x.sGROUP = SelGroup) AndAlso
                                               (SelSubGroup = "" OrElse x.sSTOREY = SelSubGroup) AndAlso
                                               (SearchText = "" OrElse Not x.sNAM.IndexOf(SearchText, StringComparison.InvariantCultureIgnoreCase) >= 0))
      End If
      Return bOk
   End Function

   Friend Sub UpdateSection(NewPartSection As SectionXMaterial, OldPartSection As SectionXMaterial)
      If IsNothing(BTLPartVMList) Then Return
      'If Map.refProjectVM.BTLStructureVM.nPROJTYPE = MachineType.BEAM Then
      ' verifico se era unico con vecchia sezione
      If Not m_BTLPartVMList.Any(Function(x) x.Section = OldPartSection) Then
         ' nel caso seleziono filtro generico 
         SelSection = m_SectionList(0)
         ' e poi lo cerco ed elimino
         m_SectionList.FirstOrDefault(Function(x) x = OldPartSection)
         m_SectionList.Remove(m_SectionList.FirstOrDefault(Function(x) x = OldPartSection))
      End If
      ' verifico se esiste già nuova sezione
      If Not m_SectionList.Any(Function(x) x = NewPartSection) Then
         m_SectionList.Add(NewPartSection)
      End If
      'ElseIf Map.refProjectVM.BTLStructureVM.nPROJTYPE = MachineType.WALL Then
      '   ' se ruoto o inverto parete, la sezione non cambia
      'End If
   End Sub

   ' funzione che aggiorna totale tempi a fine calcolo
   Friend Sub CalcGlobalTime()
      NotifyPropertyChanged(NameOf(sBTLTotTime))
      NotifyPropertyChanged(NameOf(sBTLDoneTime))
      NotifyPropertyChanged(NameOf(sBTLRemainingTime))
   End Sub

   ' funzione che aggiorna numero pezzi, volume e tempo totali
   Friend Sub CalcGlobalUpdate()
      NotifyPropertyChanged(NameOf(sBTLTotParts))
      NotifyPropertyChanged(NameOf(sBTLTotVolume))
      NotifyPropertyChanged(NameOf(sBTLTotTime))
      NotifyPropertyChanged(NameOf(sBTLDoneTime))
      NotifyPropertyChanged(NameOf(sBTLRemainingTime))
   End Sub

   ' funzione utilizata per aggiornare rot e flip dopo calcolo
   Public Sub RefreshRotFlip()
      For Each BTLPart In BTLPartVMList
         If Not EgtGetInfo(BTLPart.nPartId, BTL_PRT_ROTATED, BTLPart.BTLPartM.nROTATED) Then
            BTLPart.BTLPartM.nROTATED = 0
         End If
         If Not EgtGetInfo(BTLPart.nPartId, BTL_PRT_INVERTED, BTLPart.BTLPartM.nINVERTED) Then
            BTLPart.BTLPartM.nINVERTED = 0
         End If
         BTLPart.NotifyPropertyChanged(NameOf(BTLPart.sROTATED))
         BTLPart.NotifyPropertyChanged(NameOf(BTLPart.sINVERTED))
      Next
   End Sub

#End Region    ' METHODS

#Region "DeletePart"

   Public ReadOnly Property DeletePart_Command As ICommand
      Get
         If m_cmdDeletePart Is Nothing Then
            m_cmdDeletePart = New Command(AddressOf DeletePart)
         End If
         Return m_cmdDeletePart
      End Get
   End Property

   Public Sub DeletePart()
      If Map.refMainMenuVM.SelPage = Pages.VIEW Then Map.refLeftPanelVM.RemovePartCmd()
   End Sub

#End Region ' DeletePart

#Region "EVENTS"

   Private Sub OnBTLPartAdded(sender As Object, e As BTLPartAddedEventArgs)
      Dim BTLPartVM As BTLPartVM = New BTLPartVM(e.NewBTLPart, m_BTLStructureM)
      m_BTLPartVMList.Add(BTLPartVM)
      NotifyPropertyChanged(NameOf(BTLPartVMList))
   End Sub

   Private Sub OnBTLPartVMListChanged(sender As Object, e As NotifyCollectionChangedEventArgs)
      If Not IsNothing(e.NewItems) AndAlso e.NewItems.Count > 0 Then
         For Each BTLPartVM As BTLPartVM In e.NewItems
            AddHandler BTLPartVM.PropertyChanged, AddressOf OnBTLPartVMPropertyChanged
         Next
      End If
      If Not IsNothing(e.OldItems) AndAlso e.OldItems.Count > 0 Then
         For Each BTLPartVM As BTLPartVM In e.OldItems
            RemoveHandler BTLPartVM.PropertyChanged, AddressOf OnBTLPartVMPropertyChanged
            m_BTLStructureM.BTLPartMList.Remove(BTLPartVM.BTLPartM)
         Next
      End If
   End Sub

   Private Sub OnBTLPartVMPropertyChanged(sender As Object, e As PropertyChangedEventArgs)
      Select Case e.PropertyName
         Case NameOf(sender.sMATERIAL)
            If Not GroupList.Contains(sender.sMATERIAL) Then
               GroupList.Add(sender.sMATERIAL)
            End If
         Case NameOf(sender.sW), NameOf(sender.sH), NameOf(sender.sL)
            'If Not SectionList.Contains(sender.Section) Then
            '   SectionList.Add(sender.Section)
            'End If
            'Case NameOf(sender.sROTATED)
            '   UpdateSection(CType(sender, BTLPartVM).BTLPartM)
         Case NameOf(sender.nDONE)
            NotifyPropertyChanged(NameOf(sBTLDoneTime))
            NotifyPropertyChanged(NameOf(sBTLRemainingTime))
         Case NameOf(sender.bDOALL)
            NotifyPropertyChanged(NameOf(bDOALL))
      End Select
   End Sub

#End Region    ' EVENTS

End Class
