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

Public Class BTLFeatureVM
   Inherits Core.BTLFeatureVM

   Public Property GRPList As ObservableCollection(Of Integer)
      Get
         Return m_BTLFeatureM.GRPList
      End Get
      Set(value As ObservableCollection(Of Integer))
         m_BTLFeatureM.GRPList = value
      End Set
   End Property

   Public Overrides Property nSelGRP As Integer
      Get
         Return m_BTLFeatureM.nSelGRP
      End Get
      Set(value As Integer)
         If value <> -1 Then
            ' verifico se solido attivo
            Dim bShowSolid As Boolean = Map.refShowBeamPanelVM.ShowSolid_IsChecked
            If bShowSolid Then Map.refProjectVM.BTLStructureVM.ShowSolid(GDB_ID.NULL, False, False)
            ' aggiorno la feature con nuovo valore
            Dim vPar() As Double = Nothing
            Dim sPar As String = String.Empty
            Dim vParQ() As String = Nothing
            m_BTLFeatureM.CalcParamArray(vPar, sPar, vParQ)
            Dim bOK As Boolean = m_BTLFeatureM.UpdateParams(value, m_BTLFeatureM.nPRC, nSelSIDE, m_BTLFeatureM.sDES, m_BTLFeatureM.nPRID,
                                                            m_BTLFeatureM.frFRAME, vPar, sPar, vParQ)
            If bOK Then
               m_BTLFeatureM.nSelGRP = value
               ' seleziono feature in disegno
               SelGeomFeature()
               ' rendo non calcolata questa feature
               ResetCalcFeature()
            End If
            NotifyPropertyChanged(NameOf(nSelGRP))
            If bShowSolid Then Map.refProjectVM.BTLStructureVM.ShowSolid(GDB_ID.NULL, True, False)
            EgtDraw()
         End If
      End Set
   End Property

   Public Property SIDEList As ObservableCollection(Of Integer)
      Get
         Return m_BTLFeatureM.SIDEList
      End Get
      Set(value As ObservableCollection(Of Integer))
         m_BTLFeatureM.SIDEList = value
      End Set
   End Property

   ' Lato
   Public Overrides Property nSelSIDE As Integer
      Get
         Return m_BTLFeatureM.nSelSIDE
      End Get
      Set(value As Integer)
         If value <> -1 Then
            ' verifico se solido attivo
            Dim bShowSolid As Boolean = Map.refShowBeamPanelVM.ShowSolid_IsChecked
            If bShowSolid Then Map.refProjectVM.BTLStructureVM.ShowSolid(GDB_ID.NULL, False, False)
            ' se freecontour
            If Me.m_BTLFeatureM.IsFreeContour() Then
               ' cambio faccia alla geometria
               Dim frOld As New Frame3d
               EgtBeamGetSideData(nSelSIDE, frOld)
               frOld.Invert()
               Dim frNew As New Frame3d
               EgtBeamGetSideData(value, frNew)
               Dim sAuxId As String = ""
               If EgtGetInfo(nFeatureId, "AUXID", sAuxId) Then
                  ' verifico se ha uno o due percorsi
                  Dim sAuxIdSplit() As String = sAuxId.Split(","c)
                  If Not IsNothing(sAuxIdSplit) AndAlso sAuxIdSplit.Length() >= 1 Then
                     Dim nAuxId As Integer = GDB_ID.NULL
                     If Integer.TryParse(sAuxIdSplit(0), nAuxId) Then
                        EgtTransform(nFeatureId + nAuxId, frOld, GDB_RT.GLOB)
                        EgtTransform(nFeatureId + nAuxId, frNew, GDB_RT.GLOB)
                     End If
                  End If
                  If Not IsNothing(sAuxIdSplit) AndAlso sAuxIdSplit.Length() >= 2 Then
                     Dim nAux2Id As Integer = GDB_ID.NULL
                     If Integer.TryParse(sAuxIdSplit(1), nAux2Id) Then
                        EgtTransform(nFeatureId + nAux2Id, frOld, GDB_RT.GLOB)
                        EgtTransform(nFeatureId + nAux2Id, frNew, GDB_RT.GLOB)
                     End If
                  End If
               End If
            End If
            ' aggiorno la feature con nuovo valore
            Dim vPar() As Double = Nothing
            Dim sPar As String = String.Empty
            Dim vParQ() As String = Nothing
            m_BTLFeatureM.CalcParamArray(vPar, sPar, vParQ)
            Dim bOK As Boolean = m_BTLFeatureM.UpdateParams(nSelGRP, m_BTLFeatureM.nPRC, value, m_BTLFeatureM.sDES, m_BTLFeatureM.nPRID,
                                                      m_BTLFeatureM.frFRAME, vPar, sPar, vParQ)
            If bOK Then
               m_BTLFeatureM.nSelSIDE = value
               SelGeomFeature()
               ' rendo non calcolata questa feature
               ResetCalcFeature()
            End If
            NotifyPropertyChanged("nSelSIDE")
            If bShowSolid Then Map.refProjectVM.BTLStructureVM.ShowSolid(GDB_ID.NULL, True, False)
            EgtDraw()
         End If
      End Set
   End Property

   Public Property sPriority As String
      Get
         Return m_BTLFeatureM.nPriority.ToString()
      End Get
      Set(value As String)
         Dim nTemp As Integer = 0
         If Integer.TryParse(value, nTemp) Then
            If EgtSetInfo(nFeatureId, BTL_FTR_PRIORITY, nTemp) Then
               m_BTLFeatureM.nPriority = nTemp
               ' setto feature da ricalcolare
               ResetCalcFeature()
               ' se in View
               If Map.refMainMenuVM.SelPage = Pages.VIEW Then
                  ' imposto modificato per copie
                  EgtDuploSetModified(m_BTLPartM.nPartId)
               End If
            End If
         End If
         NotifyPropertyChanged(NameOf(sPriority))
      End Set
   End Property
   ' proprieta' che indica se e' attivo l'update del parametro bDO su piu' feature (attiva/disattiva tutti su pezzo, o per tipo con tasto destro)
   ' necessario per evitare ricalcolo della grafica sulla modifica del parametro per ogni feature
   Private Shared m_bDO_MultipleUpdate As Boolean = False
   Public Shared Property bDO_MultipleUpdate As Boolean
      Get
         Return m_bDO_MultipleUpdate
      End Get
      Set(value As Boolean)
         m_bDO_MultipleUpdate = value
      End Set
   End Property

   Public Overrides Property bDO As Boolean
      Get
         Return m_BTLFeatureM.bDO
      End Get
      Set(value As Boolean)
         Dim bShowSolid As Boolean = Map.refShowBeamPanelVM.ShowSolid_IsChecked
         If value <> m_BTLFeatureM.bDO Then
            If Map.refMainMenuVM.SelPage = Pages.VIEW Then
               ' verifico se solido attivo
               If bShowSolid Then Map.refProjectVM.BTLStructureVM.ShowSolid(GDB_ID.NULL, False, False)
            End If
            If EgtBeamEnableProcess(nFeatureId, value, Not m_bDO_MultipleUpdate) Then
               m_BTLFeatureM.bDO = value
               ' setto feature da ricalcolare
               ResetCalcFeature()
               ' se in View
               If Map.refMainMenuVM.SelPage = Pages.VIEW Then
                  ' imposto modificato per copie
                  EgtDuploSetModified(m_BTLPartM.nPartId)
               End If
               NotifyPropertyChanged(NameOf(bDO))
               ' aggiorno messaggio su context menu
               For Each Item In MenuList
                  Item.NotifyPropertyChanged(NameOf(Item.sMsg))
               Next
            End If
            If Map.refMainMenuVM.SelPage = Pages.VIEW Then
               ' eventualmente ripristino solido
               If bShowSolid Then Map.refProjectVM.BTLStructureVM.ShowSolid(GDB_ID.NULL, True, False)
            End If
            If Not m_bDO_MultipleUpdate Then EgtDraw()
            ' aggiorno stato abilitazione del bottone modifica free contour
            Map.refFeatureManagerVM.SetEditIsEnabled()
         End If
      End Set
   End Property

   Public ReadOnly Property sDrawPath As String
      Get
         Return Map.refMainWindowVM.MainWindowM.sResourcesRoot & "\Features\" & sDescGRP & ".png"
      End Get
   End Property

   Private m_PBTLParamVMList As ObservableCollection(Of BTLParamVM)
   Public Property PBTLParamVMList As ObservableCollection(Of BTLParamVM)
      Get
         Return m_PBTLParamVMList
      End Get
      Set(value As ObservableCollection(Of BTLParamVM))
         m_PBTLParamVMList = value
      End Set
   End Property

   Protected m_SelPBTLParam As BTLParamVM
   Public Property SelPBTLParam As BTLParamVM
      Get
         Return m_SelPBTLParam
      End Get
      Set(value As BTLParamVM)
         m_SelPBTLParam = value
         If Not IsNothing(m_SelPBTLParam) Then
            ' imposto path disegno da mostrare in BottomPanel
            Map.refBottomPanelVM.SetCurrDraw(m_SelPBTLParam.sDrawPath)
         End If
         NotifyPropertyChanged(NameOf(SelPBTLParam))
      End Set
   End Property

   Private m_QBTLParamVMList As ObservableCollection(Of BTLParamVM)
   Public Property QBTLParamVMList As ObservableCollection(Of BTLParamVM)
      Get
         Return m_QBTLParamVMList
      End Get
      Set(value As ObservableCollection(Of BTLParamVM))
         m_QBTLParamVMList = value
      End Set
   End Property

   Protected m_SelQParam As BTLParamVM
   Public Property SelQBTLParam As BTLParamVM
      Get
         Return m_SelQParam
      End Get
      Set(value As BTLParamVM)
         m_SelQParam = value
         If Not IsNothing(m_SelQParam) Then
            ' imposto path disegno da mostrare in BottomPanel
            Map.refBottomPanelVM.SetCurrDraw(m_SelQParam.sDrawPath)
         End If
         NotifyPropertyChanged(NameOf(SelQBTLParam))
      End Set
   End Property

   Public ReadOnly Property Edit_Visibility As Visibility
      Get
         Return If(BTLFeatureM.IsFreeContour AndAlso Not Map.refFreeContourManagerVM.bIsActive, Visibility.Visible, Visibility.Collapsed)
      End Get
   End Property
   Public ReadOnly Property SaveCancel_Visibility As Visibility
      Get
         Return If(BTLFeatureM.IsFreeContour AndAlso Map.refFreeContourManagerVM.bIsActive, Visibility.Visible, Visibility.Collapsed)
      End Get
   End Property
   Friend Sub RefreshFCMBtnVisibility()
      NotifyPropertyChanged(NameOf(Edit_Visibility))
      NotifyPropertyChanged(NameOf(SaveCancel_Visibility))
   End Sub

   Private m_MenuList As New List(Of MenuItemVm)
   Public Property MenuList As List(Of MenuItemVm)
      Get
         Return m_MenuList
      End Get
      Set(value As List(Of MenuItemVm))
         m_MenuList = value
      End Set
   End Property

   ' Definizione comandi
   Private m_cmdEdit As ICommand
   Private m_cmdSave As ICommand
   Private m_cmdCancel As ICommand
   Private m_cmdDeleteFeature As ICommand

#Region "CONSTRUCTOR"

   Sub New(BTLFeatureM As BTLFeatureM, BTLPartM As BTLPartM)
      m_BTLFeatureM = BTLFeatureM
      AddHandler m_BTLFeatureM.PBTLParamAdded, AddressOf OnPBTLParamAdded
      AddHandler m_BTLFeatureM.QBTLParamAdded, AddressOf OnQBTLParamAdded
      m_BTLPartM = BTLPartM
      CreatePBTLParamVMList()
      CreateQBTLParamVMList()
      NotifyPropertyChanged(NameOf(Calc_Background))
      NotifyPropertyChanged(NameOf(CALC_ROT_Visibility))
      NotifyPropertyChanged(NameOf(CALC_ERR_Letter))
      NotifyPropertyChanged(NameOf(CALC_ERR_Foreground))
      m_MenuList.Add(New MenuItemVm(Me))
   End Sub

   Sub New(BTLFeatureM As BTLFeatureM)
      m_BTLFeatureM = BTLFeatureM
      AddHandler m_BTLFeatureM.QBTLParamAdded, AddressOf OnQBTLParamAdded
      m_BTLPartM = Nothing
      Dim Part As PartM = BTLFeatureM.ParentPart
      If Part.nType = BWType.WALL Then CreateQBTLParamVMList()
      NotifyPropertyChanged(NameOf(Calc_Background))
      NotifyPropertyChanged(NameOf(CALC_ROT_Visibility))
      NotifyPropertyChanged(NameOf(CALC_ERR_Letter))
      NotifyPropertyChanged(NameOf(CALC_ERR_Foreground))
   End Sub

#End Region    ' CONSTRUCTOR

#Region "METHODS"

   Private Sub CreatePBTLParamVMList()
      Dim all As List(Of BTLParamVM) = (From BTLParamM In m_BTLFeatureM.GetPBTLParams()
                                        Select New BTLParamVM(BTLParamM, m_BTLFeatureM)).ToList()

      For Each BTLParamVM As BTLParamVM In all
         AddHandler BTLParamVM.PropertyChanged, AddressOf OnPBTLParamVMPropertyChanged
      Next

      m_PBTLParamVMList = New ObservableCollection(Of BTLParamVM)(all)
      AddHandler m_PBTLParamVMList.CollectionChanged, AddressOf OnPBTLParamVMListChanged

   End Sub

   Private Sub CreateQBTLParamVMList()
      Dim all As List(Of BTLParamVM) = (From BTLParamM In m_BTLFeatureM.GetQBTLParams()
                                        Select New BTLParamVM(BTLParamM, m_BTLFeatureM)).ToList()
      For Each BTLParamVM As BTLParamVM In all
         AddHandler BTLParamVM.PropertyChanged, AddressOf OnQBTLParamVMPropertyChanged
      Next

      m_QBTLParamVMList = New ObservableCollection(Of BTLParamVM)(all)
      AddHandler m_QBTLParamVMList.CollectionChanged, AddressOf OnQBTLParamVMListChanged
   End Sub

   ' funzione che aggiorna lo stato, la rotazione e gli errori dopo calcolo
   Friend Sub CalcFeatureUpdate(ERR As Integer, ROT As Integer, MSG As String)
      EgtSetInfo(nFeatureId, If(Map.refMainMenuVM.SelPage = Pages.VIEW, ITG_PROJ_ERR, ITG_PROD_ERR), ERR, True)
      EgtSetInfo(nFeatureId, If(Map.refMainMenuVM.SelPage = Pages.VIEW, ITG_PROJ_MSG, ITG_PROD_MSG), MSG, True)
      EgtSetInfo(nFeatureId, If(Map.refMainMenuVM.SelPage = Pages.VIEW, ITG_PROJ_ROT, ITG_PROD_ROT), ROT, True)
      m_BTLFeatureM.nCALC_ERR = ERR
      m_BTLFeatureM.nCALC_ROT = ROT
      m_BTLFeatureM.sCALC_MSG = MSG
      Select Case ERR
         Case 0
            m_BTLFeatureM.nState = CalcStates.OK
         Case 22
            m_BTLFeatureM.nState = CalcStates.COLLISION
         Case 17, 19
            m_BTLFeatureM.nState = CalcStates.WARNING
         Case < 0
            m_BTLFeatureM.nState = CalcStates.INFO
         Case > 0
            m_BTLFeatureM.nState = CalcStates.ERROR_
      End Select
      NotifyPropertyChanged(NameOf(Calc_Background))
      NotifyPropertyChanged(NameOf(CALC_ROT_Visibility))
      NotifyPropertyChanged(NameOf(sCALC_MSG))
      NotifyPropertyChanged(NameOf(CALC_ERR_Letter))
      NotifyPropertyChanged(NameOf(CALC_ERR_Foreground))
   End Sub

   ' funzione che resetta gli errori del calcolo
   Friend Sub ResetFeatureError()
      Dim ERR As Integer = 0
      Dim MSG As String = ""
      EgtSetInfo(nFeatureId, If(Map.refMainMenuVM.SelPage = Pages.VIEW, ITG_PROJ_ERR, ITG_PROD_ERR), ERR, True)
      EgtSetInfo(nFeatureId, If(Map.refMainMenuVM.SelPage = Pages.VIEW, ITG_PROJ_MSG, ITG_PROD_MSG), MSG, True)
      m_BTLFeatureM.nCALC_ERR = ERR
      m_BTLFeatureM.sCALC_MSG = MSG
      Select Case ERR
         Case 0
            m_BTLFeatureM.nState = CalcStates.OK
         Case 22
            m_BTLFeatureM.nState = CalcStates.COLLISION
         Case 17, 19
            m_BTLFeatureM.nState = CalcStates.WARNING
         Case < 0
            m_BTLFeatureM.nState = CalcStates.INFO
         Case > 0
            m_BTLFeatureM.nState = CalcStates.ERROR_
      End Select
      NotifyPropertyChanged(NameOf(Calc_Background))
      NotifyPropertyChanged(NameOf(sCALC_MSG))
      NotifyPropertyChanged(NameOf(CALC_ERR_Letter))
      NotifyPropertyChanged(NameOf(CALC_ERR_Foreground))
   End Sub

   Friend Sub ResetCalcFeature()
      EgtRemoveInfo(nFeatureId, If(IsNothing(m_BTLPartM), ITG_PROD_ERR, ITG_PROJ_ERR))
      EgtRemoveInfo(nFeatureId, If(IsNothing(m_BTLPartM), ITG_PROD_MSG, ITG_PROJ_MSG))
      EgtRemoveInfo(nFeatureId, If(IsNothing(m_BTLPartM), ITG_PROD_ROT, ITG_PROJ_ROT))
      m_BTLFeatureM.nState = CalcStates.NOTCALCULATED
      m_BTLFeatureM.nCALC_ERR = 0
      m_BTLFeatureM.nCALC_ROT = 0
      m_BTLFeatureM.sCALC_MSG = ""
      NotifyPropertyChanged(NameOf(Calc_Background))
      NotifyPropertyChanged(NameOf(CALC_ROT_Visibility))
      NotifyPropertyChanged(NameOf(sCALC_MSG))
      NotifyPropertyChanged(NameOf(CALC_ERR_Letter))
      NotifyPropertyChanged(NameOf(CALC_ERR_Foreground))
   End Sub

   Public Function Copy() As BTLFeatureM
      Return Copy(m_BTLPartM)
   End Function

   Public Function Copy(DestBTLPart As BTLPartM) As BTLFeatureM
      ' creo nuova feature
      Dim vPar() As Double = Nothing
      Dim sPar As String = String.Empty
      Dim vParQ() As String = Nothing
      m_BTLFeatureM.CalcParamArray(vPar, sPar, vParQ)
      ' imposto eventuali percorsi
      Dim nCrvId As Integer = GDB_ID.NULL
      Dim nCrv2Id As Integer = GDB_ID.NULL
      m_BTLFeatureM.GetFreeContourPaths(nCrvId, nCrv2Id)
      ' creo la feature con nuovi valori
      EgtBeamSetPart(DestBTLPart.nPartId)
      Dim nNewFeatureId As Integer = EgtBeamAddProcess(m_BTLFeatureM.nSelGRP, m_BTLFeatureM.nPRC, m_BTLFeatureM.nSelSIDE, m_BTLFeatureM.sDES,
                                                       DestBTLPart.NewProcId(), m_BTLFeatureM.frFRAME, vPar, sPar, vParQ, nCrvId, nCrv2Id)
      ' se è stata creata
      If nNewFeatureId <> GDB_ID.NULL Then
         ' Riporto eventuali indicazioni di parametri Q custom
         For Each QPar In QBTLParamVMList
            If QPar.bCustom Then EgtSetInfo(nNewFeatureId, QPar.sName & "A", 1)
         Next
         ' Riporto priority
         EgtSetInfo(nNewFeatureId, BTL_FTR_PRIORITY, m_BTLFeatureM.nPriority)
         Dim NewFeat As BTLFeatureM = BTLFeatureM.CreateBTLFeature(m_BTLPartM, nNewFeatureId)
         ' la aggiungo a struttura BTL pezzo di destinazione
         DestBTLPart.AddBTLFeature(NewFeat)
         Return NewFeat
      End If
      Return Nothing
   End Function

#End Region    ' METHODS

#Region "COMMANDS"

#Region "DeleteFeature"

   Public ReadOnly Property DeleteFeature_Command As ICommand
      Get
         If m_cmdDeleteFeature Is Nothing Then
            m_cmdDeleteFeature = New Command(AddressOf DeleteFeature)
         End If
         Return m_cmdDeleteFeature
      End Get
   End Property

   Public Sub DeleteFeature()
      If Map.refMainMenuVM.SelPage = Pages.VIEW Then Map.refLeftPanelVM.RemoveFeature()
   End Sub

#End Region ' DeleteFeature

#Region "Edit"

   Public ReadOnly Property Edit_Command As ICommand
      Get
         If m_cmdEdit Is Nothing Then
            m_cmdEdit = New Command(AddressOf Edit)
         End If
         Return m_cmdEdit
      End Get
   End Property

   Public Sub Edit()
      ' attivo modalita' contorno libero
      Map.refFreeContourManagerVM.Open()
   End Sub

#End Region ' Edit

#Region "Save"

   Public ReadOnly Property Save_Command As ICommand
      Get
         If m_cmdSave Is Nothing Then
            m_cmdSave = New Command(AddressOf Save)
         End If
         Return m_cmdSave
      End Get
   End Property

   Public Sub Save()
      Select Case Map.refFreeContourManagerVM.SelType
         Case FreeContourManagerVM.FreeContourTypes.ONE
         Case FreeContourManagerVM.FreeContourTypes.ONEWITHANGLES
         Case FreeContourManagerVM.FreeContourTypes.TWO
      End Select
      'm_PBTLParamVMList(0).sName
      'm_PBTLParamVMList(0).dValue
      'm_QBTLParamVMList(0).sName
      'm_QBTLParamVMList(0).dValue
      'Map.refFreeContourManagerVM.nNewPathId
      'Map.refFreeContourManagerVM.nNewSecondPathId
      ' disattivo modalita' contorno libero
      Map.refFreeContourManagerVM.Close(True)
   End Sub

#End Region ' Save

#Region "Cancel"

   Public ReadOnly Property Cancel_Command As ICommand
      Get
         If m_cmdCancel Is Nothing Then
            m_cmdCancel = New Command(AddressOf Cancel)
         End If
         Return m_cmdCancel
      End Get
   End Property

   Public Sub Cancel()
      ' disattivo modalita' contorno libero
      Map.refFreeContourManagerVM.Close(False)
   End Sub

#End Region ' Cancel

#End Region    ' COMMANDS

#Region "EVENTS"

   Private Sub OnPBTLParamAdded(sender As Object, e As BTLParamAddedEventArgs) Handles m_BTLFeatureM.PBTLParamAdded
      Dim BTLParamVM As BTLParamVM = New BTLParamVM(e.NewBTLParam, m_BTLFeatureM)
      PBTLParamVMList.Add(BTLParamVM)
   End Sub
   Private Sub OnQBTLParamAdded(sender As Object, e As BTLParamAddedEventArgs) Handles m_BTLFeatureM.QBTLParamAdded
      Dim BTLParamVM As BTLParamVM = New BTLParamVM(e.NewBTLParam, m_BTLFeatureM)
      QBTLParamVMList.Add(BTLParamVM)
   End Sub

   Private Sub OnPBTLParamVMListChanged(sender As Object, e As NotifyCollectionChangedEventArgs)
      If Not IsNothing(e.NewItems) AndAlso e.NewItems.Count > 0 Then
         For Each BTLParamVM As BTLParamVM In e.NewItems
            AddHandler BTLParamVM.PropertyChanged, AddressOf OnPBTLParamVMPropertyChanged
         Next
      End If
      If Not IsNothing(e.OldItems) AndAlso e.OldItems.Count > 0 Then
         For Each BTLParamVM As BTLParamVM In e.OldItems
            RemoveHandler BTLParamVM.PropertyChanged, AddressOf OnPBTLParamVMPropertyChanged
         Next
      End If
   End Sub
   Private Sub OnQBTLParamVMListChanged(sender As Object, e As NotifyCollectionChangedEventArgs)
      If Not IsNothing(e.NewItems) AndAlso e.NewItems.Count > 0 Then
         For Each BTLParamVM As BTLParamVM In e.NewItems
            AddHandler BTLParamVM.PropertyChanged, AddressOf OnQBTLParamVMPropertyChanged
         Next
      End If
      If Not IsNothing(e.OldItems) AndAlso e.OldItems.Count > 0 Then
         For Each BTLParamVM As BTLParamVM In e.OldItems
            RemoveHandler BTLParamVM.PropertyChanged, AddressOf OnQBTLParamVMPropertyChanged
         Next
      End If
   End Sub

   Private Sub OnPBTLParamVMPropertyChanged(sender As Object, e As PropertyChangedEventArgs)
      Select Case e.PropertyName
         Case NameOf(sender.dValue), NameOf(sender.sValue)
            ' riseleziono questa feature
            SelGeomFeature()
            ' rendo non calcolata questa feature
            ResetCalcFeature()
      End Select
   End Sub
   Private Sub OnQBTLParamVMPropertyChanged(sender As Object, e As PropertyChangedEventArgs)
      Select Case e.PropertyName
         Case NameOf(sender.dValue), NameOf(sender.sValue)
            ' riseleziono questa feature
            SelGeomFeature()
            ' rendo non calcolata questa feature
            ResetCalcFeature()
      End Select
   End Sub

#End Region    ' EVENTS

End Class

Public Class MenuItemVm
   Inherits VMBase

   Private m_ParentFeature As BTLFeatureVM
   Public ReadOnly Property ParentFeature As BTLFeatureVM
      Get
         Return m_ParentFeature
      End Get
   End Property

   Public ReadOnly Property sMsg As String
      Get
         Return If(ParentFeature.bDO, "Disable all ", "Enable all ") & ParentFeature.sDescGRP
      End Get
   End Property

   ' Definizione comando
   Private m_cmdCommand As ICommand

   Sub New(Parent As BTLFeatureVM)
      m_ParentFeature = Parent
   End Sub

#Region "Cancel"

   Public ReadOnly Property MenuItem_Command As ICommand
      Get
         If m_cmdCommand Is Nothing Then
            m_cmdCommand = New Command(AddressOf Command)
         End If
         Return m_cmdCommand
      End Get
   End Property

   Public Sub Command()
      Dim bNewDo As Boolean = Not ParentFeature.bDO
      ' imposto modalita' update multiplo
      BTLFeatureVM.bDO_MultipleUpdate = True
      ' aggiorno tutte le feature del pezzo
      'For FeatureVMIndex = 0 To Map.refProjectVM.BTLStructureVM.SelBTLPart.BTLFeatureVMList.Count - 1
      Dim SameProcFeatureList As List(Of BTLFeatureVM) = Map.refProjectVM.BTLStructureVM.SelBTLPart.BTLFeatureVMList.Where(Function(x) x.nPRC = ParentFeature.nPRC AndAlso x.GRPList.Contains(ParentFeature.nSelGRP)).ToList()
      For FeatureVMIndex = 0 To SameProcFeatureList.Count - 1
         If FeatureVMIndex = SameProcFeatureList.Count - 1 Then
            ' reset modalita' update multiplo
            BTLFeatureVM.bDO_MultipleUpdate = False
         End If
         Dim FeatureVM As BTLFeatureVM = SameProcFeatureList(FeatureVMIndex)
         If FeatureVM.nPRC = ParentFeature.nPRC AndAlso FeatureVM.GRPList.Contains(ParentFeature.nSelGRP) Then
            FeatureVM.bDO = bNewDo
         End If
      Next
   End Sub

#End Region ' Cancel

End Class