Imports System.IO
Imports EgtUILib
Imports EgtWPFLib5
Imports EgtBEAMWALL.Core
Imports System.Collections.ObjectModel
Imports System.Windows.Threading

Public Class CALCPanelVM
   Inherits VMBase

   Public Enum ProduceType As Integer
      NULL = 0
      PRODUCE = 1
      PRODUCEALL = 2
   End Enum

   ' timer e variabile per ricaricare progetto dopo edit
   Private m_Waiting_Timer As New DispatcherTimer
   Private m_ReloadEditedFile As Boolean = False

   Private m_OrigSelectedMachine As Machine = Nothing
   ' imposta se il calcolo e' stato lanciato dal tasto produci(1), produci tutti(2) o nessuno(0)
   Private m_FromProduce As ProduceType = ProduceType.NULL
   Friend Sub SetFromProduce(value As ProduceType)
      m_FromProduce = value
   End Sub

   Private m_IsMachineApplied As Boolean = False
   Public Property IsMachineApplied As Boolean
      Get
         Return m_IsMachineApplied
      End Get
      Set(value As Boolean)
         m_IsMachineApplied = value
      End Set
   End Property

   Private m_CALCPanel_IsEnabled As Boolean = True
   Public Property CALCPanel_IsEnabled As Boolean
      Get
         Return m_CALCPanel_IsEnabled
      End Get
      Set(value As Boolean)
         m_CALCPanel_IsEnabled = value
      End Set
   End Property

   Private m_ChooseMachineBtn_Visibility As Boolean = True
   Public Property ChooseMachineBtn_Visibility As Visibility
      Get
         Return If(m_ChooseMachineBtn_Visibility, Visibility.Visible, Visibility.Collapsed)
      End Get
      Set(value As Visibility)
         m_ChooseMachineBtn_Visibility = (value = Visibility.Visible)
         NotifyPropertyChanged(NameOf(ChooseMachineBtn_Visibility))
      End Set
   End Property
   Friend Sub SetChooseMachineBtn_Visibility(IsVisible As Boolean)
      m_ChooseMachineBtn_Visibility = IsVisible
      NotifyPropertyChanged(NameOf(ChooseMachineBtn_Visibility))
   End Sub

   Private m_ChooseMachine_Visibility As Boolean = False
   Public Property ChooseMachine_Visibility As Visibility
      Get
         Return If(m_ChooseMachine_Visibility, Visibility.Visible, Visibility.Collapsed)
      End Get
      Set(value As Visibility)
         m_ChooseMachine_Visibility = (value = Visibility.Visible)
         NotifyPropertyChanged(NameOf(ChooseMachine_Visibility))
      End Set
   End Property
   Friend Sub SetChooseMachine_Visibility(IsVisible As Boolean)
      m_ChooseMachine_Visibility = IsVisible
      NotifyPropertyChanged(NameOf(ChooseMachine_Visibility))
   End Sub

   ' Lista delle macchine disponibili per il tipo di progetto corrente
   Private m_MachineList As New ObservableCollection(Of Machine)
   Public Property MachineList As ObservableCollection(Of Machine)
      Get
         Return m_MachineList
      End Get
      Set(value As ObservableCollection(Of Machine))
         m_MachineList = value
      End Set
   End Property

   ' Macchina correntemente selezionata e quindi attiva
   Private m_SelectedMachine As Machine = Nothing
   Public Property SelectedMachine As Machine
      Get
         Return m_SelectedMachine
      End Get
      Set(value As Machine)
         If value IsNot m_SelectedMachine Then
            m_SelectedMachine = value
            NotifyPropertyChanged(NameOf(SelectedMachine))
         End If
      End Set
   End Property

   Public ReadOnly Property ViewPage_Visibility As Visibility
      Get
         Return If(Map.refMainMenuVM.SelPage = Pages.VIEW, Visibility.Visible, Visibility.Collapsed)
      End Get
   End Property

   Public ReadOnly Property Edit_Visibility As Visibility
      Get
         Return If(Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso GetMainPrivateProfileInt(S_GENERAL, K_ENABLEEDIT, 0) = 1, Visibility.Visible, Visibility.Collapsed)
      End Get
   End Property

   Public ReadOnly Property Verify_IsEnabled As Boolean
      Get
         Return If(Map.refMainMenuVM.SelPage = Pages.VIEW,
                   m_CALCPanel_IsEnabled AndAlso Not Map.refShowBeamPanelVM.bShowAll AndAlso
                   Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Not Map.refProjectVM.BTLStructureVM.SelBTLPartsCnt > 1,
                   m_CALCPanel_IsEnabled)
      End Get
   End Property

   Public ReadOnly Property Simulate_IsEnabled As Boolean
      Get
         Return If(Map.refMainMenuVM.SelPage = Pages.VIEW,
                   m_CALCPanel_IsEnabled And Not Map.refShowBeamPanelVM.bShowAll AndAlso
                   Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Not Map.refProjectVM.BTLStructureVM.SelBTLPartsCnt > 1,
                   m_CALCPanel_IsEnabled)
      End Get
   End Property

   Public ReadOnly Property Edit_IsEnabled As Boolean
      Get
         Return If(Map.refMainMenuVM.SelPage = Pages.VIEW,
                   m_CALCPanel_IsEnabled And Not Map.refShowBeamPanelVM.bShowAll AndAlso
                   Not IsNothing(Map.refProjectVM.BTLStructureVM) AndAlso Not Map.refProjectVM.BTLStructureVM.SelBTLPartsCnt > 1,
                   True)
      End Get
   End Property

   ' Definizione comandi
   Private m_cmdVerify As ICommand
   Private m_cmdVerifyAll As ICommand
   Private m_cmdResetCalc As ICommand
   Private m_cmdSimulate As ICommand
   Private m_cmdEdit As ICommand
   Private m_cmdChooseMachine As ICommand
   Private m_cmdOk As ICommand

#Region "Messages"

   Public ReadOnly Property Verify_ToolTip As String
      Get
         Return EgtMsg(61901)
      End Get
   End Property

   Public ReadOnly Property VerifyAll_ToolTip As String
      Get
         Return EgtMsg(61928)
      End Get
   End Property

   Public ReadOnly Property Simulate_ToolTip As String
      Get
         Return EgtMsg(61902)
      End Get
   End Property

   Public ReadOnly Property Edit_ToolTip As String
      Get
         Return EgtMsg(61939)
      End Get
   End Property

   Public ReadOnly Property ResetCalc_ToolTip As String
      Get
         Return EgtMsg(61940)
      End Get
   End Property

   Public ReadOnly Property ChooseMachine_ToolTip As String
      Get
         Return EgtMsg(61941)
      End Get
   End Property

#End Region    ' Messages

#Region "CONSTRUCTORS"

   Sub New()
      ' imposto riferimento in Map
      Map.SetRefCALCPanelVM(Me)
      Core.CalcIntegration.SetMaxCamInstances(Map.refMainWindowVM.MainWindowM.GetMaxCamInstances())
      AddHandler Core.CalcIntegration.Calc_ProcessResult, AddressOf Calc_ProcessResult
      AddHandler Core.CalcIntegration.Calc_Ended, AddressOf Calc_Ended
      m_Waiting_Timer.Interval = TimeSpan.FromMilliseconds(500)
      AddHandler m_Waiting_Timer.Tick, AddressOf Waiting_Timer_Tick
      m_Waiting_Timer.Start()
   End Sub

#End Region    ' CONSTRUCTORS

#Region "METHODS"

   Friend Sub SetCalcPanelIsEnabled(bIsEnabled As Boolean)
      m_CALCPanel_IsEnabled = bIsEnabled
      NotifyPropertyChanged(NameOf(CALCPanel_IsEnabled))
      NotifyPropertyChanged(NameOf(Verify_IsEnabled))
      NotifyPropertyChanged(NameOf(Simulate_IsEnabled))
      NotifyPropertyChanged(NameOf(Edit_IsEnabled))
   End Sub
   Friend Sub SetIsEnabledForSelPart()
      NotifyPropertyChanged(NameOf(Verify_IsEnabled))
      NotifyPropertyChanged(NameOf(Simulate_IsEnabled))
      NotifyPropertyChanged(NameOf(Edit_IsEnabled))
   End Sub

   Private Sub Calc_ProcessResult(sender As Object, e As CalcResultEventArgs)
      ProcessResults(e.m_Result)
   End Sub

   Private Sub Calc_Ended(sender As Object, e As CalcEndEventArgs)
      If e.End_ = CalcEndEventArgs.Results.ERROR_ OrElse e.End_ = CalcEndEventArgs.Results.NULL Then
         MessageBox.Show("Execution error (all processes are disabled)")
      End If
      If e.End_ = CalcEndEventArgs.Results.EDIT Then
         Map.refMyStatusBarVM.SetOutputMessage("Editor closed")
         m_ReloadEditedFile = True
      End If
      ' se verify o verifyall, salvo il progetto per conservarne gli stati calcolati
      If e.CmdType = CmdTypes.CHECKGEN Then
         If Map.refMainMenuVM.SelPage = Pages.VIEW Then
            Map.refProjManagerVM.Save()
         ElseIf Map.refMainMenuVM.SelPage = Pages.MACHINING Then
            Map.refProdManagerVM.Save()
         End If
      End If
      ' se modalita' assemblato attiva
      If Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso Map.refShowBeamPanelVM.ShowBuilding_IsChecked AndAlso Map.refShowBeamPanelVM.bShowAll Then
         ' lo rimonto
         Map.refProjectVM.BTLStructureVM.ShowBuilding(True, False)
      End If
      Map.refProjectVM.SetCalcRunning(False)
      Map.refMyStatusBarVM.ResetStopProgress()
      ' se lanciato dal produci, eseguo produci
      If m_FromProduce <> ProduceType.NULL Then
         Select Case m_FromProduce
            Case ProduceType.PRODUCE
               Map.refTopPanelVM.ProduceRawPart()
            Case ProduceType.PRODUCEALL
               Map.refTopPanelVM.ProduceAllRawPart()
         End Select
         m_FromProduce = ProduceType.NULL
      End If
   End Sub

   Private Sub Waiting_Timer_Tick()
      If m_ReloadEditedFile Then
         m_ReloadEditedFile = False
         Map.refMyStatusBarVM.SetOutputMessage("Reloading modified file")
         ' ricarico il progetto
         Dim sCurrFilePath As String = ""
         EgtGetCurrFilePath(sCurrFilePath)
         EgtOpenFile(sCurrFilePath)
         ' imposto duplo modificato
         EgtDuploSetModified(Map.refProjectVM.BTLStructureVM.SelBTLPart.nPartId)
         ' riseleziono il pezzo precedentemente selezionato
         Map.refProjectVM.BTLStructureVM.SetSelBTLPart(Map.refProjectVM.BTLStructureVM.SelBTLPart)
         Map.refMyStatusBarVM.SetOutputMessage("Modified file reloaded", 1)
         Map.refProjectVM.SetCalcRunning(False)
         Map.refMyStatusBarVM.ResetStopProgress()
      End If
   End Sub

   Friend Shared Sub ProcessResults(MachGroupId As MyMachGroupVM)
      ProcessResults(Map.refProdManagerVM.CurrProd.sProdDirPath & "/" & MachGroupId.nName & ".txt", ProjectType.PROD, MachGroupId.Id)
   End Sub

   Private Shared Sub ProcessResults(Bar As Bar)
      If IsNothing(Bar) Then Return
      ProcessResults(Bar.sBarPath, Bar.nProgramPage, Bar.nBarId)
   End Sub

   Private Shared Sub ProcessResults(BtlPath As String, nProgramPage As ProjectType, nBarId As Integer)

      Dim ResPath As String = Path.ChangeExtension(BtlPath, ".txt")
      Dim bErrors As Boolean = False
      Dim nLastErr As Integer = 0
      Dim sLastMsg As String = ""
      Dim nCurrCutId As Integer = 0
      Dim nTotTime As Integer = 0

      If File.Exists(ResPath) Then

         Dim ProcessResultList As New List(Of ProcessResult)
         Dim nErr As Integer = 0
         Dim sMsg As String = ""
         Dim dRot As Double = 0
         Dim nFall As Integer = 0
         Dim dPartRot As Double = 0
         Dim dTotRot As Double = 0
         Dim cutId As Integer = 0
         Dim taskId As Integer = 0
         Dim prevCutId As Integer = GDB_ID.NULL
         Dim currBTLPart As BTLPartVM = Nothing

         Dim lines As String() = System.IO.File.ReadAllLines(ResPath)
         For Each line As String In lines

            If line.StartsWith("ERR=") Then
               Dim nVal As Integer? = GetVal(line, "ERR")
               nErr = (If(Not IsNothing(nVal), nVal.Value, 0))
               sMsg = ""
               dRot = 0
               nFall = 0
               cutId = 0
               taskId = 0
            ElseIf line.StartsWith("ROT=") Then
               Dim nVal As Integer? = GetVal(line, "ROT")
               Dim nRot As Integer = (If(Not IsNothing(nVal), nVal.Value, 0))
               dRot = Math.Abs(((4 - nRot) Mod 4) * 90)
               dPartRot = Math.Max(dPartRot, dRot)
               dTotRot = Math.Max(dTotRot, dRot)
            ElseIf line.StartsWith("CUTID=") Then
               Dim nVal As Integer? = GetVal(line, "CUTID")
               cutId = If(Not IsNothing(nVal), nVal.Value, 0)
            ElseIf line.StartsWith("TASKID=") Then
               Dim nVal As Integer? = GetVal(line, "TASKID")
               taskId = (If(Not IsNothing(nVal), nVal.Value, 0))
               ProcessResultAdd(ProcessResultList, ProcessResult.CreateTaskResult(cutId, taskId, nErr, sMsg, dRot), nProgramPage)
            ElseIf line.StartsWith("FALL=") Then
               Dim nVal As Integer? = GetVal(line, "FALL")
               nFall = (If(Not IsNothing(nVal), nVal.Value, 0))
               ProcessResultList.Add(ProcessResult.CreateFallResult(cutId, nErr, sMsg, nFall))
            ElseIf line.StartsWith("TIME=") Then
               Dim nVal As Integer? = GetVal(line, "TIME")
               nTotTime = (If(Not IsNothing(nVal), nVal.Value, 0))
               ProcessResultList.Add(ProcessResult.CreateTimeResult(cutId, nTotTime))
               'If Bar.nBarType = ProjectType.PROJ AndAlso Not IsNothing(currBTLPart) Then
               '   EgtSetInfo(currBTLPart.nPartId, If(Bar.nBarType = ProjectType.PROJ, ITG_PROJ_TIME, ITG_PROD_TIME), nTotTime, True)
               'End If
            ElseIf Not String.IsNullOrWhiteSpace(line) AndAlso line <> "---" Then
               sMsg = line
            End If
         Next

         If ProcessResultList.Count > 0 Then
            If nProgramPage = ProjectType.PROJ Then
               ' Inizializzo il pezzo in verifica
               Dim BTLPart As BTLPartVM = GetBTLPartVMFromBTLPartId(nBarId)
               BTLPart.CalcPartUpdate(0, 0, "")
               ' Resetto feature in collisione
               For Each Feature In BTLPart.m_BTLFeatureVMList
                  If Feature.nState = CalcStates.COLLISION Then
                     Feature.ResetFeatureError()
                  End If
               Next
            Else
               ' Inizializzo i pezzi del gruppo di lavoro in verifica
               Dim Machgroup As MyMachGroupVM = GetMachgroupVMFromMachgroupId(nBarId)
               For Each Part As PartVM In Machgroup.PartVMList
                  Part.CalcPartUpdate(0, 0, "")
                  ' Resetto feature in collisione
                  For Each Feature As BTLFeatureVM In Part.FeatureVMList
                     If Feature.nState = CalcStates.COLLISION Then
                        Feature.ResetFeatureError()
                     End If
                  Next
               Next
               Machgroup.CalcMachGroupUpdate(0, 0, "")
            End If
            ' Ciclo ...
            Dim nCUTID As Integer = -1
            Dim CurrBTLPartVM As BTLPartVM = Nothing
            Dim CurrPartVM As PartVM = Nothing
            Dim CurrMachgroupVM As MyMachGroupVM = Nothing
            Dim CurrBTLFeatureVM As BTLFeatureVM = Nothing
            For Each Line In ProcessResultList
               ' se necessario recupero part
               If Line.nCUTID <> 0 Then
                  If Line.nCUTID <> nCUTID Then
                     nCUTID = Line.nCUTID
                     If nProgramPage = ProjectType.PROJ Then
                        ' aggiorno nuovo pezzo
                        CurrBTLPartVM = GetBTLPartVMFromBTLPartId(Line.nCUTID)
                        If IsNothing(CurrBTLPartVM) Then
                           Line.ResetTypePart()
                           EgtOutLog("Error in CALC ProcessResult. CUTID " & Line.nCUTID & "not found in project(BTLPartVM).")
                        End If
                     Else
                        ' aggiorno nuovo pezzo
                        CurrPartVM = GetPartVMFromPartId(Line.nCUTID)
                        If IsNothing(CurrPartVM) Then
                           Line.ResetTypePart()
                           EgtOutLog("Error in CALC ProcessResult. CUTID " & Line.nCUTID & "not found in project(PartVM).")
                        End If
                     End If
                  End If
               Else
                  ' se CutId = 0 
                  If nProgramPage = ProjectType.PROJ Then
                     ' imposto unico pezzo presente
                     CurrBTLPartVM = GetBTLPartVMFromBTLPartId(nBarId)
                     If IsNothing(CurrBTLPartVM) Then
                        EgtOutLog("Error in CALC ProcessResult. CUTID " & nBarId & "not found in project(BTLPartVM).")
                        Continue For
                     End If
                  Else
                     ' riporto errore barra
                     CurrMachgroupVM = GetMachgroupVMFromMachgroupId(nBarId)
                     If IsNothing(CurrMachgroupVM) Then
                        EgtOutLog("Error in CALC ProcessResult. CUTID " & nBarId & "not found in project(MachGroup).")
                        Continue For
                     End If
                  End If
               End If
               ' se necessario recupero feature
               If Line.nTASKID <> 0 Then
                  If nProgramPage = ProjectType.PROJ Then
                     CurrBTLFeatureVM = GetBTLFeatureVMFromBTLPartId(CurrBTLPartVM, Line.nTASKID)
                     If IsNothing(CurrBTLFeatureVM) Then
                        Line.ResetTypeFeature()
                        EgtOutLog("Error in CALC ProcessResult. TASKID " & Line.nTASKID & "not found in BTLPartVM " & CurrBTLPartVM.nPartId)
                     End If
                  Else
                     CurrBTLFeatureVM = GetFeatureVMFromPartId(CurrPartVM, Line.nTASKID)
                     If IsNothing(CurrBTLFeatureVM) Then
                        Line.ResetTypeFeature()
                        EgtOutLog("Error in CALC ProcessResult. TASKID " & Line.nTASKID & "not found in PartVM " & CurrPartVM.nPartId)
                     End If
                  End If
               Else
                  CurrBTLFeatureVM = Nothing
               End If
               Select Case Line.Type
                  Case ProcessResult.ProcessResultTypes.BAR
                     If nProgramPage = ProjectType.PROJ Then
                        CurrBTLPartVM.CalcPartUpdate(Line.nERR, Line.dROT, Line.sMSG)
                     Else
                        CurrMachgroupVM.CalcMachGroupUpdate(Line.nERR, Line.dROT, Line.sMSG)
                     End If
                  Case ProcessResult.ProcessResultTypes.PART
                     If nProgramPage = ProjectType.PROJ Then
                        CurrBTLPartVM.CalcPartUpdate(Line.nERR, Line.dROT, Line.sMSG)
                     Else
                        CurrPartVM.CalcPartUpdate(Line.nERR, Line.dROT, Line.sMSG)
                     End If
                  Case ProcessResult.ProcessResultTypes.TASKID
                     CurrBTLFeatureVM.CalcFeatureUpdate(Line.nERR, Line.dROT, Line.sMSG)
                  Case ProcessResult.ProcessResultTypes.FALL
                     If nProgramPage = ProjectType.PROJ Then
                        CurrBTLPartVM.CalcFallUpdate(Line.nFALL)
                     Else
                        CurrPartVM.CalcFallUpdate(Line.nFALL)
                     End If
                  Case ProcessResult.ProcessResultTypes.TIME
                     If nProgramPage = ProjectType.PROJ Then
                        CurrBTLPartVM.CalcTimeUpdate(Line.nTIME)
                     Else
                        If IsNothing(CurrMachgroupVM) Then CurrMachgroupVM = GetMachgroupVMFromMachgroupId(nBarId)
                        CurrMachgroupVM.CalcTimeUpdate(Line.nTIME)
                     End If
               End Select
            Next
            If nProgramPage = ProjectType.PROJ Then
               ' aggiorno il pezzo
               Dim BTLPart As BTLPartVM = GetBTLPartVMFromBTLPartId(nBarId)
               BTLPart.CalcGlobalUpdate()
               ' lancio aggiornamento tempo su BTL
               Map.refProjectVM.BTLStructureVM.CalcGlobalTime()
            Else
               Dim Machgroup As MyMachGroupVM = GetMachgroupVMFromMachgroupId(nBarId)
               For Each Part In Machgroup.PartVMList
                  Part.CalcGlobalUpdate()
               Next
               Machgroup.CalcGlobalUpdate()
               ' lancio aggiornamento tempo su MachgroupPanel
               Map.refProjectVM.MachGroupPanelVM.CalcGlobalTime()
            End If

         End If

      Else
         bErrors = True
         nLastErr = 25
         sLastMsg = "Execution Error"
      End If

   End Sub

   Private Shared Function GetVal(sText As String, sKey As String) As Integer?
      Dim sParts As String() = sText.Split("="c)
      If String.Compare(sParts(0), sKey) <> 0 Then Return Nothing
      Dim nVal As Integer = Nothing

      If Not Integer.TryParse(sParts(1), nVal) Then
         Return Nothing
      Else
         Return nVal
      End If
   End Function

   Private Shared Sub ProcessResultAdd(PRList As List(Of ProcessResult), NewPR As ProcessResult, nProgramPage As ProjectType)
      Dim Prev As ProcessResult = Nothing
      Select Case NewPR.Type
         Case ProcessResult.ProcessResultTypes.BAR
            If nProgramPage = ProjectType.PROJ Then
               Prev = PRList.FirstOrDefault(Function(x) x.Type = ProcessResult.ProcessResultTypes.PART)
            Else
               Prev = PRList.FirstOrDefault(Function(x) x.Type = ProcessResult.ProcessResultTypes.BAR)
            End If
         Case ProcessResult.ProcessResultTypes.PART
            Prev = PRList.FirstOrDefault(Function(x) x.Type = ProcessResult.ProcessResultTypes.PART AndAlso x.nCUTID = NewPR.nCUTID)
         Case ProcessResult.ProcessResultTypes.TASKID
            Prev = PRList.FirstOrDefault(Function(x) x.Type = ProcessResult.ProcessResultTypes.TASKID AndAlso x.nCUTID = NewPR.nCUTID AndAlso x.nTASKID = NewPR.nTASKID)
      End Select
      If IsNothing(Prev) Then
         PRList.Add(NewPR)
      ElseIf NewPR.nERR = 22 Or (NewPR.nERR > 0 And Prev.nERR <= 0) Or (NewPR.nERR < 0 And Prev.nERR = 0) Then
         If NewPR.dROT = 0 And Prev.dROT <> NewPR.dROT Then
            NewPR.SetROT(Prev.dROT)
         End If
         PRList.Remove(Prev)
         PRList.Add(NewPR)
      ElseIf Prev.dROT = 0 And Prev.dROT <> NewPR.dROT Then
         Prev.SetROT(NewPR.dROT)
      End If
   End Sub

   Friend Shared Function GetBTLPartVMFromBTLPartId(nBTLPartId As Integer) As BTLPartVM
      Return Map.refProjectVM.BTLStructureVM.BTLPartVMList.FirstOrDefault(Function(x) x.nPartId = nBTLPartId)
   End Function

   Friend Shared Function GetBTLPartVMFromPartId(nPartId As Integer) As BTLPartVM
      Dim nBTLPartId As Integer = MyMachGroupPanelM.DuploGetOriginal(nPartId)
      Return Map.refProjectVM.BTLStructureVM.BTLPartVMList.FirstOrDefault(Function(x) x.nPartId = nBTLPartId)
   End Function

   Friend Shared Function GetPartVMFromPartId(nPartId As Integer) As PartVM
      For Each MachGroupVM As MyMachGroupVM In Map.refProjectVM.MachGroupPanelVM.MachGroupVMList
         Dim PartVM As PartVM = MachGroupVM.PartVMList.FirstOrDefault(Function(x) x.nPartId = nPartId)
         If Not IsNothing(PartVM) Then Return PartVM
      Next
      Return Nothing
   End Function

   Friend Shared Function GetMachgroupVMFromMachgroupId(nMachGroupId As Integer) As MyMachGroupVM
      Return Map.refProjectVM.MachGroupPanelVM.MachGroupVMList.FirstOrDefault(Function(x) x.Id = nMachGroupId)
   End Function

   Private Shared Function GetBTLFeatureVMFromBTLPartId(BTLPartVM As BTLPartVM, nFeatureId As Integer) As Core.BTLFeatureVM
      Return BTLPartVM.BTLFeatureVMList.FirstOrDefault(Function(x) x.nFeatureId = nFeatureId)
   End Function

   Private Shared Function GetFeatureVMFromPartId(PartVM As PartVM, nFeatureId As Integer) As Core.BTLFeatureVM
      Return PartVM.FeatureVMList.FirstOrDefault(Function(x) x.nFeatureId = nFeatureId)
   End Function

   Friend Sub LoadMachineList()
      MachineList.Clear()
      ' ciclo per aggiungere macchine congrue al tipo del progetto corrente
      For Each Machine In Map.refMachinePanelVM.MachineList
         ' se trovo una macchina chiamata come una già inserita ma con suffisso ".new" non la inserisco e passo al successivo elemento del For
         If Machine.Name.EndsWith(".new", StringComparison.InvariantCultureIgnoreCase) AndAlso
            MachineList.Count > 0 AndAlso
            Not IsNothing(MachineList.FirstOrDefault(Function(x) x.Name.Equals(Machine.Name.Substring(0, Machine.Name.Length - 4)))) Then
            Continue For
         End If
         Dim nMachType As MachineType = DirectCast(Machine, MyMachine).nType
         Dim nProjType As BWType
         Dim sMachineName As String = ""
         If Map.refMainMenuVM.SelPage = Pages.VIEW Then
            nProjType = Map.refProjManagerVM.nProjType
            sMachineName = If(Not IsNothing(Map.refProjManagerVM.CurrProj), Map.refProjManagerVM.CurrProj.sMachine, "")
         ElseIf Map.refMainMenuVM.SelPage = Pages.MACHINING Then
            nProjType = Map.refProdManagerVM.nProdType
            sMachineName = If(Not IsNothing(Map.refProdManagerVM.CurrProd), Map.refProdManagerVM.CurrProd.sMachine, "")
         End If
         If nMachType = nProjType OrElse
            (nMachType = 3 And Map.refMainMenuVM.SelPage = Pages.VIEW And Not IsNothing(Map.refProjManagerVM.CurrProj)) OrElse
            (nMachType = 3 And Map.refMainMenuVM.SelPage = Pages.MACHINING And Not IsNothing(Map.refProdManagerVM.CurrProd)) Then
            MachineList.Add(Machine)
            ' Se il nome Macchina coincide setto la macchina selezionata con la macchina associata al progetto
            If Machine.Name = sMachineName Then
               SelectedMachine = MachineList(MachineList.IndexOf(Machine))
               m_OrigSelectedMachine = SelectedMachine
            End If
         End If
      Next
      Map.refCALCPanelVM.SetChooseMachineBtn_Visibility(Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso MachineList.Count > 1 AndAlso GetMainPrivateProfileInt(S_MACH, K_CHANGEMACH, 0) = 1)
   End Sub

   Friend Function IsMachineModified() As Boolean
      Return m_IsMachineApplied AndAlso
         Not IsNothing(SelectedMachine) AndAlso
         Not IsNothing(m_OrigSelectedMachine) AndAlso
         SelectedMachine.Name <> m_OrigSelectedMachine.Name
   End Function

   Friend Sub CloseResetMachine()
      ' ritorno al valore originale e collasso CmBx e pulsante di conferma
      RevertToOriginalMachine()
      SetChooseMachine_Visibility(False)
   End Sub

   Friend Sub RevertToOriginalMachine()
      ' ri-setto SelectedMachine di CALCPanel e MachinePanel al valore originale
      SelectedMachine = m_OrigSelectedMachine
      Map.refMachinePanelVM.SelectedMachine = SelectedMachine
   End Sub

   Friend Sub ResetMachineModified()
      ' aggiorno l'originale SelectedMachine in modo che non appaia modificata
      m_OrigSelectedMachine = SelectedMachine
   End Sub

   Friend Sub PartShowAllChanged()
      NotifyPropertyChanged(NameOf(Verify_IsEnabled))
      NotifyPropertyChanged(NameOf(Simulate_IsEnabled))
      NotifyPropertyChanged(NameOf(Edit_IsEnabled))
   End Sub

#End Region    ' METHODS

#Region "COMMANDS"

#Region "Verify"

   ''' <summary>
   ''' Returns a command that do Open.
   ''' </summary>
   Public ReadOnly Property Verify_Command As ICommand
      Get
         If m_cmdVerify Is Nothing Then
            m_cmdVerify = New Command(AddressOf Verify)
         End If
         Return m_cmdVerify
      End Get
   End Property

   ''' <summary>
   ''' Execute the Open.  This method is invoked by the OpenCommand.
   ''' </summary>
   Friend Sub Verify()
      If (Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso (IsNothing(Map.refProjManagerVM.CurrProj) OrElse IsNothing(Map.refProjectVM.BTLStructureVM)) OrElse
         (Map.refMainMenuVM.SelPage = Pages.MACHINING AndAlso (IsNothing(Map.refProdManagerVM.CurrProd) OrElse IsNothing(Map.refProjectVM.MachGroupPanelVM)))) Then Return
      Dim ProjType As BWType
      If Map.refMainMenuVM.SelPage = Pages.VIEW Then
         ProjType = Map.refProjManagerVM.CurrProj.nType
      Else
         ProjType = Map.refProdManagerVM.CurrProd.nType
      End If
      Dim BarList() As EgtBEAMWALL.Core.Bar
      If Map.refMainMenuVM.SelPage = Pages.VIEW Then
         If Not IsNothing(Map.refProjectVM.BTLStructureVM.SelBTLPart) Then
            Dim TempBarList(0) As EgtBEAMWALL.Core.Bar
            If Not Map.refProjectVM.BTLStructureVM.SelBTLPart.bDO Then Return
            Dim Bar As New EgtBEAMWALL.Core.Bar With {.nBarId = Map.refProjectVM.BTLStructureVM.SelBTLPart.nPartId,
                                                      .nProgramPage = ProjectType.PROJ,
                                                      .nProjType = ProjType,
                                                      .bBarOk = True,
                                                      .nMachineName = Map.refMachinePanelVM.SelectedMachine.Name,
                                                      .nGlobState = Map.refProjectVM.BTLStructureVM.SelBTLPart.nGlobalState}
            Select Case Map.refProjectVM.BTLStructureVM.SelBTLPart.nGlobalState
               Case Core.CalcStates.OK, CalcStates.INFO
                  Bar.nCmdType = CalcIntegration.CmdTypes.GENERATE
               Case Else
                  If Map.refProjectVM.BTLStructureVM.SelBTLPart.nGlobalState = CalcStates.NOTCALCULATED OrElse Map.refProjectVM.BTLStructureVM.SelBTLPart.nFeaturesGlobalState > CalcStates.INFO Then
                     Dim sBTLPartFilePath As String = Map.refProjManagerVM.CurrProj.sProjDirPath & "\" & Map.refProjectVM.BTLStructureVM.SelBTLPart.nPDN.ToString() & ".ori.bwe"
                     If File.Exists(sBTLPartFilePath) Then File.Delete(sBTLPartFilePath)
                  End If
                  Bar.nCmdType = CalcIntegration.CmdTypes.CHECKGEN
            End Select
            TempBarList(0) = Bar
            BarList = TempBarList
         Else
            Return
         End If
         ' disabilito interfaccia
         Map.refProjectVM.SetCalcRunning(True)
         ' lancio calcolo
         EgtBEAMWALL.Core.CalcIntegration.Run(BarList, Map.refProjManagerVM.CurrProj.sProjDirPath, AddressOf ManageCalc)

      ElseIf Map.refMainMenuVM.SelPage = Pages.MACHINING Then
         If Not IsNothing(Map.refMachGroupPanelVM.SelectedMachGroup) Then
            Dim SelMachGroup As MyMachGroupVM = Map.refMachGroupPanelVM.SelectedMachGroup
            ' se barra gia' assegnata a supervisore, esco
            If SelMachGroup.nProduction_State >= ItemState.Assigned Then Return
            Dim TempBarList(0) As EgtBEAMWALL.Core.Bar
            Dim MachineName As String = ""
            EgtGetMachGroupMachineName(SelMachGroup.Id, MachineName)
            Dim Bar As New EgtBEAMWALL.Core.Bar With {.nBarId = SelMachGroup.Id,
                                                      .nProgramPage = ProjectType.PROD,
                                                      .nProjType = ProjType,
                                                      .bBarOk = True,
                                                      .nMachineName = MachineName,
                                                      .nGlobState = SelMachGroup.nGlobalState}
            Select Case SelMachGroup.nGlobalState
               Case Core.CalcStates.OK, CalcStates.INFO
                  Bar.nCmdType = CalcIntegration.CmdTypes.GENERATE
               Case Else
                  If SelMachGroup.nGlobalState = CalcStates.NOTCALCULATED OrElse (SelMachGroup.nPartsGlobalState > CalcStates.INFO) Then
                     Dim sMachGroupFilePath As String = Map.refProdManagerVM.CurrProd.sProdDirPath & "\" & SelMachGroup.Name.ToString() & ".ori.bwe"
                     If File.Exists(sMachGroupFilePath) Then File.Delete(sMachGroupFilePath)
                  End If
                  Bar.nCmdType = CalcIntegration.CmdTypes.CHECKGEN
            End Select
            TempBarList(0) = Bar
            BarList = TempBarList
         Else
            Return
         End If
         ' disabilito interfaccia
         Map.refProjectVM.SetCalcRunning(True)
         ' lancio calcolo
         EgtBEAMWALL.Core.CalcIntegration.Run(BarList, Map.refProdManagerVM.CurrProd.sProdDirPath, AddressOf ManageCalc)
      End If
   End Sub

   ' funzione che gestisce risposta da thread di verifica, aggiorna progress e segnala comando di interruzione
   Private Sub ManageCalc(dProgress As Double, sProgress As String, ByRef bCancel As Boolean)
      If dProgress = 0 Then
         Map.refMyStatusBarVM.SetLoadingProgress_Visibility(True)
         Map.refMyStatusBarVM.SetStopProgress_IsActive(True)
         Map.refMyStatusBarVM.SetStopProgress_IsEnabled(True)
         Map.refMyStatusBarVM.SetOutputMessage(sProgress)
         Map.refMyStatusBarVM.SetStopProgress_IsActive(True)
         Map.refMyStatusBarVM.SetStopProgress_IsEnabled(True)
      ElseIf dProgress = 1 Then
         Map.refMyStatusBarVM.SetLoadingProgress_Visibility(False)
         Map.refMyStatusBarVM.SetStopProgress_IsActive(False)
         Map.refMyStatusBarVM.SetStopProgress_IsEnabled(False)
         Map.refMyStatusBarVM.SetOutputMessage(sProgress, 3)
      End If
      bCancel = Map.refMyStatusBarVM.bStopProgress
      Map.refMyStatusBarVM.SetLoadingProgress(dProgress * 100)
      Map.refMyStatusBarVM.SetOutputMessage(sProgress)
   End Sub

#End Region ' Verify

#Region "VerifyAll"

   ''' <summary>
   ''' Returns a command that do Open.
   ''' </summary>
   Public ReadOnly Property VerifyAll_Command As ICommand
      Get
         If m_cmdVerifyAll Is Nothing Then
            m_cmdVerifyAll = New Command(AddressOf VerifyAll)
         End If
         Return m_cmdVerifyAll
      End Get
   End Property

   ''' <summary>
   ''' Execute the Open.  This method is invoked by the OpenCommand.
   ''' </summary>
   Friend Sub VerifyAll()
      If (Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso (IsNothing(Map.refProjManagerVM.CurrProj) OrElse IsNothing(Map.refProjectVM.BTLStructureVM)) OrElse
         (Map.refMainMenuVM.SelPage = Pages.MACHINING AndAlso (IsNothing(Map.refProdManagerVM.CurrProd) OrElse IsNothing(Map.refProjectVM.MachGroupPanelVM)))) Then Return
      ' se modalita' assemblato
      If Map.refShowBeamPanelVM.ShowBuilding_IsChecked AndAlso Map.refShowBeamPanelVM.bShowAll Then
         ' devo smontarlo prima di calcolare le travi, altrimenti non trova i pezzi
         Map.refProjectVM.BTLStructureVM.ShowBuilding(False, False)
      End If
      Dim ProjType As BWType
      If Map.refMainMenuVM.SelPage = Pages.VIEW Then
         ProjType = Map.refProjManagerVM.CurrProj.nType
      Else
         ProjType = Map.refProdManagerVM.CurrProd.nType
      End If
      Dim BarList() As EgtBEAMWALL.Core.Bar
      If Map.refMainMenuVM.SelPage = Pages.VIEW Then
         Dim TempBarList As New List(Of EgtBEAMWALL.Core.Bar)
         For PartIndex = 0 To Map.refProjectVM.BTLStructureVM.BTLPartVMList.Count - 1
            Dim CurrPart As BTLPartVM = Map.refProjectVM.BTLStructureVM.BTLPartVMList(PartIndex)
            If Not CurrPart.bDO Then Continue For
            Dim Bar As New EgtBEAMWALL.Core.Bar With {.nBarId = CurrPart.nPartId,
                                                     .nProgramPage = ProjectType.PROJ,
                                                     .nProjType = ProjType,
                                                     .bBarOk = True,
                                                     .nMachineName = Map.refMachinePanelVM.SelectedMachine.Name,
                                                     .nGlobState = CurrPart.nGlobalState}
            Select Case CurrPart.nGlobalState
               Case Core.CalcStates.OK, CalcStates.INFO
                  Bar.nCmdType = CalcIntegration.CmdTypes.GENERATE
               Case Else
                  If CurrPart.nGlobalState = CalcStates.NOTCALCULATED OrElse CurrPart.nFeaturesGlobalState > CalcStates.INFO Then
                     Dim sBTLPartFilePath As String = Map.refProjManagerVM.CurrProj.sProjDirPath & "\" & CurrPart.nPDN.ToString() & ".ori.bwe"
                     If File.Exists(sBTLPartFilePath) Then File.Delete(sBTLPartFilePath)
                  End If
                  Bar.nCmdType = CalcIntegration.CmdTypes.CHECKGEN
            End Select
            TempBarList.Add(Bar)
         Next
         BarList = TempBarList.ToArray()
         ' disabilito interfaccia
         Map.refProjectVM.SetCalcRunning(True)
         ' lancio calcolo
         EgtBEAMWALL.Core.CalcIntegration.Run(BarList, Map.refProjManagerVM.CurrProj.sProjDirPath, AddressOf ManageCalc)
      ElseIf Map.refMainMenuVM.SelPage = Pages.MACHINING Then
         Dim TempBarList As New List(Of EgtBEAMWALL.Core.Bar)
         For PartIndex = 0 To Map.refMachGroupPanelVM.MachGroupVMList.Count - 1
            Dim CurrMachGroup As MyMachGroupVM = Map.refMachGroupPanelVM.MachGroupVMList(PartIndex)
            ' se e' gia' stato assegnato a supervisor, la salto e vado alla prossima barra
            If CurrMachGroup.nProduction_State >= ItemState.Assigned Then Continue For
            Dim MachineName As String = ""
            EgtGetMachGroupMachineName(CurrMachGroup.Id, MachineName)
            Dim Bar As New EgtBEAMWALL.Core.Bar With {.nBarId = CurrMachGroup.Id,
                                                      .nProgramPage = ProjectType.PROD,
                                                      .nProjType = ProjType,
                                                      .bBarOk = True,
                                                      .nMachineName = MachineName,
                                                      .nGlobState = CurrMachGroup.nGlobalState}
            Select Case CurrMachGroup.nGlobalState
               Case Core.CalcStates.OK, CalcStates.INFO
                  Bar.nCmdType = CalcIntegration.CmdTypes.GENERATE
               Case Else
                  If CurrMachGroup.nGlobalState = CalcStates.NOTCALCULATED OrElse (CurrMachGroup.nPartsGlobalState > CalcStates.INFO) Then
                     Dim sMachGroupFilePath As String = Map.refProdManagerVM.CurrProd.sProdDirPath & "\" & CurrMachGroup.Name.ToString() & ".ori.bwe"
                     If File.Exists(sMachGroupFilePath) Then File.Delete(sMachGroupFilePath)
                  End If
                  Bar.nCmdType = CalcIntegration.CmdTypes.CHECKGEN
            End Select
            TempBarList.Add(Bar)
         Next
         If TempBarList.Count = 0 Then Return
         BarList = TempBarList.ToArray()
         ' disabilito interfaccia
         Map.refProjectVM.SetCalcRunning(True)
         ' lancio calcolo
         EgtBEAMWALL.Core.CalcIntegration.Run(BarList, Map.refProdManagerVM.CurrProd.sProdDirPath, AddressOf ManageCalc)
      End If
   End Sub

#End Region ' VerifyAll

#Region "ResetCalc"

   ''' <summary>
   ''' Returns a command that do Exec.
   ''' </summary>
   Public ReadOnly Property ResetCalc_Command As ICommand
      Get
         If m_cmdResetCalc Is Nothing Then
            m_cmdResetCalc = New Command(AddressOf ResetCalc)
         End If
         Return m_cmdResetCalc
      End Get
   End Property

   ''' <summary>
   ''' Execute the Exec.  This method is invoked by the ExecCommand.
   ''' </summary>
   Public Sub ResetCalc()
      If (Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso (IsNothing(Map.refProjManagerVM.CurrProj) OrElse IsNothing(Map.refProjectVM.BTLStructureVM)) OrElse
         (Map.refMainMenuVM.SelPage = Pages.MACHINING AndAlso (IsNothing(Map.refProdManagerVM.CurrProd) OrElse IsNothing(Map.refProjectVM.MachGroupPanelVM)))) Then Return
      If Map.refMainMenuVM.SelPage = Pages.VIEW Then
         If (Keyboard.Modifiers And ModifierKeys.Shift) = ModifierKeys.Shift Then
            For Each Part In Map.refProjectVM.BTLStructureVM.BTLPartVMList
               If Part.nGlobalState <> CalcStates.NOTCALCULATED Then
                  ' resetto stato dei calcoli
                  Part.ResetCalcTotalPart()
               End If
            Next
         ElseIf Map.refProjectVM.BTLStructureVM.SelBTLPartsCnt > 1 Then
            For Each SelPart In Map.refProjectVM.BTLStructureVM.SelBTLPartList
               If Not IsNothing(SelPart) AndAlso SelPart.nGlobalState <> CalcStates.NOTCALCULATED Then
                  SelPart.ResetCalcTotalPart()
               End If
            Next
         Else
            Dim SelPart As BTLPartVM = Map.refProjectVM.BTLStructureVM.SelBTLPart
            If IsNothing(SelPart) Then Return
            If SelPart.nGlobalState <> CalcStates.NOTCALCULATED Then
               SelPart.ResetCalcTotalPart()
            End If
         End If
      ElseIf Map.refMainMenuVM.SelPage = Pages.MACHINING Then
         If (Keyboard.Modifiers And ModifierKeys.Shift) = ModifierKeys.Shift Then
            For Each MachGroup As MyMachGroupVM In Map.refProjectVM.MachGroupPanelVM.MachGroupVMList
               If MachGroup.nProduction_State >= ItemState.Assigned Then Continue For
               If MachGroup.nGlobalState <> CalcStates.NOTCALCULATED Then
                  MachGroup.ResetCalcTotalMachGroup()
               End If
            Next
         Else
            Dim SelMachGroup As MyMachGroupVM = Map.refMachGroupPanelVM.SelectedMachGroup
            If IsNothing(SelMachGroup) Then Return
            ' se barra gia' assegnata a supervisore, esco
            If SelMachGroup.nProduction_State >= ItemState.Assigned Then Return
            If SelMachGroup.nGlobalState <> CalcStates.NOTCALCULATED Then
               SelMachGroup.ResetCalcTotalMachGroup()
            End If
         End If
      End If
   End Sub

#End Region    ' ResetCalc

#Region "Simulate"

   ''' <summary>
   ''' Returns a command that do Open.
   ''' </summary>
   Public ReadOnly Property Simulate_Command As ICommand
      Get
         If m_cmdSimulate Is Nothing Then
            m_cmdSimulate = New Command(AddressOf Simulate)
         End If
         Return m_cmdSimulate
      End Get
   End Property

   ''' <summary>
   ''' Execute the Open.  This method is invoked by the OpenCommand.
   ''' </summary>
   Friend Sub Simulate()
      If (Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso (IsNothing(Map.refProjManagerVM.CurrProj) OrElse IsNothing(Map.refProjectVM.BTLStructureVM)) OrElse
         (Map.refMainMenuVM.SelPage = Pages.MACHINING AndAlso (IsNothing(Map.refProdManagerVM.CurrProd) OrElse IsNothing(Map.refProjectVM.MachGroupPanelVM)))) Then Return
      Dim ProjType As BWType
      If Map.refMainMenuVM.SelPage = Pages.VIEW Then
         ProjType = Map.refProjManagerVM.CurrProj.nType
      Else
         ProjType = Map.refProdManagerVM.CurrProd.nType
      End If
      Dim BarList() As EgtBEAMWALL.Core.Bar
      If Map.refMainMenuVM.SelPage = Pages.VIEW Then
         If Not IsNothing(Map.refProjectVM.BTLStructureVM.SelBTLPart) Then
            Dim TempBarList(0) As EgtBEAMWALL.Core.Bar
            Dim Bar As New EgtBEAMWALL.Core.Bar With {.nBarId = Map.refProjectVM.BTLStructureVM.SelBTLPart.nPartId,
                                                     .nProgramPage = ProjectType.PROJ,
                                                     .nProjType = ProjType,
                                                     .bBarOk = True,
                                                     .nMachineName = Map.refMachinePanelVM.SelectedMachine.Name,
                                                     .nCmdType = CalcIntegration.CmdTypes.SIMULATE,
                                                     .nGlobState = Map.refProjectVM.BTLStructureVM.SelBTLPart.nGlobalState}
            If Map.refProjectVM.BTLStructureVM.SelBTLPart.nGlobalState = CalcStates.NOTCALCULATED Then
               Dim sBTLPartFilePath As String = Map.refProjManagerVM.CurrProj.sProjDirPath & "\" & Map.refProjectVM.BTLStructureVM.SelBTLPart.nPDN.ToString() & ".ori.bwe"
               If File.Exists(sBTLPartFilePath) Then File.Delete(sBTLPartFilePath)
            End If
            TempBarList(0) = Bar
            BarList = TempBarList
         Else
            Return
         End If
         ' disabilito interfaccia
         Map.refProjectVM.SetCalcRunning(True)
         ' lancio simulazione
         EgtBEAMWALL.Core.CalcIntegration.Run(BarList, Map.refProjManagerVM.CurrProj.sProjDirPath, AddressOf ManageCalc)
      ElseIf Map.refMainMenuVM.SelPage = Pages.MACHINING Then
         If Not IsNothing(Map.refMachGroupPanelVM.SelectedMachGroup) Then
            Dim SelMachGroup As MyMachGroupVM = Map.refMachGroupPanelVM.SelectedMachGroup
            Dim TempBarList(0) As EgtBEAMWALL.Core.Bar
            Dim MachineName As String = ""
            EgtGetMachGroupMachineName(SelMachGroup.Id, MachineName)
            Dim Bar As New EgtBEAMWALL.Core.Bar With {.nBarId = SelMachGroup.Id,
                                                     .nProgramPage = ProjectType.PROD,
                                                     .nProjType = ProjType,
                                                     .bBarOk = True,
                                                     .nMachineName = MachineName,
                                                     .nCmdType = CalcIntegration.CmdTypes.SIMULATE,
                                                     .nGlobState = SelMachGroup.nGlobalState}
            If SelMachGroup.nGlobalState = CalcStates.NOTCALCULATED Then
               Dim sMachGroupFilePath As String = Map.refProdManagerVM.CurrProd.sProdDirPath & "\" & SelMachGroup.Name.ToString() & ".ori.bwe"
               If File.Exists(sMachGroupFilePath) Then File.Delete(sMachGroupFilePath)
            End If
            TempBarList(0) = Bar
            BarList = TempBarList
         Else
            Return
         End If
         ' disabilito interfaccia
         Map.refProjectVM.SetCalcRunning(True)
         ' lancio simulazione
         EgtBEAMWALL.Core.CalcIntegration.Run(BarList, Map.refProdManagerVM.CurrProd.sProdDirPath, AddressOf ManageCalc)
      End If
   End Sub

#End Region ' Simulate

#Region "Edit"

   ''' <summary>
   ''' Returns a command that do Open.
   ''' </summary>
   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

   ''' <summary>
   ''' Execute the Open.  This method is invoked by the OpenCommand.
   ''' </summary>
   Friend Sub Edit()
      If Map.refMainMenuVM.SelPage = Pages.VIEW AndAlso (IsNothing(Map.refProjManagerVM.CurrProj) OrElse IsNothing(Map.refProjectVM.BTLStructureVM)) Then Return
      Dim ProjType As BWType
      If Map.refMainMenuVM.SelPage = Pages.VIEW Then
         ProjType = Map.refProjManagerVM.CurrProj.nType
      Else
         ProjType = Map.refProdManagerVM.CurrProd.nType
      End If
      Dim BarList() As EgtBEAMWALL.Core.Bar
      If Map.refMainMenuVM.SelPage = Pages.VIEW Then
         If Not IsNothing(Map.refProjectVM.BTLStructureVM.SelBTLPart) Then
            ' salvo il progetto prima di editarlo
            Map.refProjManagerVM.Save()
            Dim TempBarList(0) As EgtBEAMWALL.Core.Bar
            Dim Bar As New EgtBEAMWALL.Core.Bar With {.nBarId = Map.refProjectVM.BTLStructureVM.SelBTLPart.nPartId,
                                                     .nProgramPage = ProjectType.PROJ,
                                                     .nProjType = ProjType,
                                                     .bBarOk = True,
                                                     .nMachineName = Map.refMachinePanelVM.SelectedMachine.Name,
                                                     .nCmdType = CalcIntegration.CmdTypes.EDIT,
                                                     .nGlobState = Map.refProjectVM.BTLStructureVM.SelBTLPart.nGlobalState}
            TempBarList(0) = Bar
            BarList = TempBarList
         Else
            Return
         End If
         ' disabilito interfaccia
         Map.refProjectVM.SetCalcRunning(True)
         ' lancio edit
         EgtBEAMWALL.Core.CalcIntegration.Run(BarList, Map.refProjManagerVM.CurrProj.sProjDirPath, AddressOf ManageCalc)
      End If
   End Sub

#End Region ' Edit

#Region "ChooseMachine"

   ''' <summary>
   ''' Returns a command that do Open.
   ''' </summary>
   Public ReadOnly Property ChooseMachine_Command As ICommand
      Get
         If m_cmdChooseMachine Is Nothing Then
            m_cmdChooseMachine = New Command(AddressOf ChooseMachine)
         End If
         Return m_cmdChooseMachine
      End Get
   End Property

   ''' <summary>
   ''' Execute the Open.  This method is invoked by the OpenCommand.
   ''' </summary>
   Friend Sub ChooseMachine()
      ' rendo visibile la CmBx per la scelta e il pulsante di conferma solo se il Proj corrente non ha associato alcun Prod
      If Map.refProjManagerVM.CurrProj.nProdId > 0 Then
         MessageBox.Show(EgtMsg(61929), EgtMsg(30009), MessageBoxButton.OK, MessageBoxImage.Exclamation)
      Else
         SetChooseMachine_Visibility(True)
      End If
   End Sub

#End Region ' ChooseMachine

#Region "Ok"

   ''' <summary>
   ''' Returns a command that do Open.
   ''' </summary>
   Public ReadOnly Property Ok_Command As ICommand
      Get
         If m_cmdOk Is Nothing Then
            m_cmdOk = New Command(AddressOf Ok)
         End If
         Return m_cmdOk
      End Get
   End Property

   ''' <summary>
   ''' Execute the Open.  This method is invoked by the OpenCommand.
   ''' </summary>
   Friend Sub Ok()
      ' aggiorno la Macchina selezionata nel Machine Panel e collasso CmBx e pulsante di conferma
      If Not IsNothing(SelectedMachine) Then Map.refMachinePanelVM.SelectedMachine = SelectedMachine
      m_IsMachineApplied = True
      SetChooseMachine_Visibility(False)
      ' resetto i parametri errori integration ciclando su ogni Part e per ogni Part ogni Feature
      Dim ProjId = Map.refProjManagerVM.CurrProj.nProjId
      Dim TempList As New List(Of BTLPartM)
      Dim nPartId As Integer = EgtGetFirstPart()
      While nPartId <> GDB_ID.NULL
         ' se devo filtrare un progetto
         If ProjId > 0 Then
            ' verifico se il pezzo appartiene al ProjId
            Dim nPartProjId As Integer
            EgtGetInfo(nPartId, BTL_PRT_PROJ, nPartProjId)
            If nPartProjId = ProjId Then
               EgtRemoveInfo(nPartId, ITG_PROJ_ERR)
               EgtRemoveInfo(nPartId, ITG_PROJ_MSG)
               EgtRemoveInfo(nPartId, ITG_PROJ_ROT)
               EgtRemoveInfo(nPartId, ITG_PROJ_FALL)
               ' ora che ho resettato questo Part resetto le Feature di questo Part
               Dim NewBTLPart As BTLPartM = BTLPartM.CreateBTLPart(nPartId)
               Dim FeatureTempList As New List(Of BTLFeatureM)
               ' Leggo outline
               Dim nOutlineLayerId As Integer = EgtGetFirstNameInGroup(nPartId, OUTLINE)
               Dim nOutlineId As Integer = EgtGetFirstInGroup(nOutlineLayerId)
               While nOutlineId <> GDB_ID.NULL
                  ' verifico che sia una feature
                  Dim nGRP As Integer
                  If EgtGetInfo(nOutlineId, BTL_FTR_GRP, nGRP) Then
                     ' creo la feature
                     FeatureTempList.Add(BTLFeatureM.CreateBTLFeature(NewBTLPart, nOutlineId))
                  End If
                  nOutlineId = EgtGetNext(nOutlineId)
               End While
               ' Leggo feature
               Dim nProcessingId As Integer = EgtGetFirstNameInGroup(nPartId, PROCESSINGS)
               Dim nFeatureId As Integer = EgtGetFirstInGroup(nProcessingId)
               While nFeatureId <> GDB_ID.NULL
                  ' verifico che sia una feature
                  Dim nGRP As Integer
                  If EgtGetInfo(nFeatureId, BTL_FTR_GRP, nGRP) AndAlso Not EgtExistsInfo(nFeatureId, BTL_FTR_MAINID) Then
                     EgtRemoveInfo(nFeatureId, If(Map.refMainMenuVM.SelPage = Pages.VIEW, ITG_PROJ_ERR, ITG_PROD_ERR))
                     EgtRemoveInfo(nFeatureId, If(Map.refMainMenuVM.SelPage = Pages.VIEW, ITG_PROJ_MSG, ITG_PROD_MSG))
                     EgtRemoveInfo(nFeatureId, If(Map.refMainMenuVM.SelPage = Pages.VIEW, ITG_PROJ_ROT, ITG_PROD_ROT))
                  End If
                  nFeatureId = EgtGetNext(nFeatureId)
               End While
            End If
         End If
         nPartId = EgtGetNextPart(nPartId)
      End While
      ' rigenero struttura BTL
      Map.refProjectVM.BTLStructureVM = New BTLStructureVM(BTLStructureM.CreateBTLStructure(ProjId))
   End Sub

#End Region ' Ok

#End Region    ' COMMANDS

End Class
