Imports System.Collections.ObjectModel
Imports System.Collections.Specialized
Imports System.ComponentModel
Imports System.IO
Imports EgtBEAMWALL.Core
Imports EgtUILib
Imports EgtWPFLib5

Public Class MyMachGroupVM
   Inherits Core.MyMachGroupVM

#Region "FIELDS & PROPERTIES"

#Region "Supervisor"

   Public Overrides ReadOnly Property Produce_IsEnabled As Boolean
      Get
         ' se gia' prodotto
         If nProduction_State >= ItemState.Produced Then
            Return False
            ' se gia' in coda o in calcolo
         ElseIf m_bToBeProduced OrElse m_bSentToMachine Then
            Return False
            ' se la macchina e' ferma
         ElseIf IsNothing(Map.refLeftPanelVM.SelOPState) OrElse
                (Map.refLeftPanelVM.SelOPState.Id = 0 OrElse
                 Map.refLeftPanelVM.SelOPState.Id = OPStates.End OrElse
                 Map.refLeftPanelVM.SelOPState.Id = OPStates.Stop OrElse
                 Map.refLeftPanelVM.SelOPState.Id = OPStates.Unspecified) Then
            ' verifico se c'e' un pezzo non finito
            Dim ToBeRestartedPart As MyMachGroupVM = Map.refSupervisorMachGroupPanelVM.MachGroupVMList.FirstOrDefault(Function(x As MyMachGroupVM) x.nProduction_State = Global.EgtBEAMWALL.Core.ItemState.WIP And Not m_bToBeProduced)
            ' se c'e', attivo solo il pezzo non finito
            Return Not (Not IsNothing(ToBeRestartedPart) AndAlso Not ToBeRestartedPart Is Me)
         Else
            If CurrentMachine.Flow = CurrentMachine.FlowTypes.ONEBYONE Then
               Select Case nProduction_State
                  Case ItemState.Assigned, ItemState.Confirmed, ItemState.WIP
                     Return Not m_bToBeProduced AndAlso Not m_bSentToMachine AndAlso Not Map.refSupervisorMachGroupPanelVM.MachGroupVMList.Any(Function(x As MyMachGroupVM) x.bToBeProduced)
                     ' se gia' lavorato
                  Case Else
                     ' disattivo possibilita' di produrlo
                     Return False
               End Select
            Else
               Select Case nProduction_State
                  Case ItemState.Assigned, ItemState.Confirmed
                     Return Not m_bToBeProduced
                  Case ItemState.WIP
                     If Not m_bToBeProduced AndAlso Not m_bSentToMachine Then
                        Return True
                     ElseIf IsNothing(Map.refLeftPanelVM.SelOPState) OrElse
                            (Map.refLeftPanelVM.SelOPState.Id = 0 OrElse
                             Map.refLeftPanelVM.SelOPState.Id = OPStates.End OrElse
                             Map.refLeftPanelVM.SelOPState.Id = OPStates.Stop OrElse
                             Map.refLeftPanelVM.SelOPState.Id = OPStates.Unspecified) Then
                        Return True
                     Else
                        Return False
                     End If
                     ' se gia' lavorato
                  Case Else
                     ' disattivo possibilita' di produrlo
                     Return False
               End Select
            End If
         End If
      End Get
   End Property

   Private m_nProductionIndex As Integer = 10000
   Public ReadOnly Property nProductionIndex As Integer
      Get
         Return m_nProductionIndex
      End Get
   End Property
   Friend Sub SetProductionIndex(nIndex As Integer)
      m_nProductionIndex = nIndex
   End Sub

#End Region    ' Supervisor

#End Region    ' FIELDS & PROPERTIES

#Region "CONSTRUCTORS"

   Sub New(MyMachGroupM As MyMachGroupM)
      MyBase.New(MyMachGroupM)
   End Sub

#End Region    ' CONSTRUCTORS

#Region "METHODS"

#Region "Machgroup"

   Public Overrides Sub RefreshGroupData()

   End Sub

   Overrides Function CnFilePath() As String
      Return Map.refSupervisorManagerVM.CurrProd.sProdDirPath & "\" & Name & ".cnc"
   End Function

   Friend Shared Sub UpdateProduceIsEnabledForAll()
      For Each CurrMachGroup As MyMachGroupVM In Map.refSupervisorMachGroupPanelVM.MachGroupVMList
         CurrMachGroup.NotifyPropertyChanged(NameOf(CurrMachGroup.Produce_IsEnabled))
      Next
   End Sub

#End Region    ' Machgroup

#Region "Parts"

   Protected Overrides Sub CreatePartVMList()
      Dim all As List(Of PartVM) = (From PartM In MyMachGroupM.GetParts()
                                    Select New PartVM(PartM, Me)).ToList()

      For Each PartVM As PartVM In all
         AddHandler PartVM.PropertyChanged, AddressOf OnPartVMPropertyChanged
      Next

      m_PartVMList = New ObservableCollection(Of Core.PartVM)(all)
      AddHandler m_PartVMList.CollectionChanged, AddressOf OnPartVMListChanged
   End Sub

   Public Overrides Sub RefreshPartList()
      If nType = BWType.BEAM Then
         ' leggo StartCut da posizione primo pezzo
         Dim sInfo As String = ""
         Dim sSplitInfo() As String
         Dim bFound As Boolean = False
         EgtGetInfo(Id, MGR_RPT_PART & 1, sInfo)
         If Not String.IsNullOrWhiteSpace(sInfo) Then
            sSplitInfo = sInfo.Split(","c)
            StringToDoubleAdv(sSplitInfo(1), MyMachGroupM.dStartCut)
         Else
            MyMachGroupM.dStartCut = 0
         End If
      End If
   End Sub

#End Region    ' Parts

#Region "Calc"

   Public Overrides Sub CALCEnd()
      ' aggiorno stato per lancio in macchina
      If MyMachGroupM.m_nCALC_GlobalState = Core.CalcStates.OK OrElse MyMachGroupM.m_nCALC_GlobalState = Core.CalcStates.INFO Then
         If m_bToBeProduced AndAlso Not m_bCNReCalculated Then
            m_bCNReCalculated = True
            NotifyPropertyChanged(NameOf(Production_Background))
         End If
      Else
         ResetProduce()
         UpdateProduceIsEnabledForAll()
      End If
   End Sub

#End Region    ' Calc

#End Region    ' METHODS

#Region "COMMANDS"

#Region "ProduceMachGroup"

   ' Manage the MainWindow_Unloaded event. This method is invoked by the cmdMainWindow_Unloaded.
   Public Overrides Sub ProduceMachGroup()
      ' se gia' in produzione, non devo fare nulla
      If m_bToBeProduced Then Return
      ' disabilito bottoni di comunicazione durante invio programma
      Map.refMachCommandMessagePanelVM.SetCommBtnIsEnabled(False)
      ' macchina bloccata con reset PER TEST!!!!
      'SetResetWhileCutting(True)
      ' se ripartenza
      If Map.refLeftPanelVM.bRestart Then
         ' verifico se c'e' un visualizzatore o ottimizzatore aperto su questo progetto
         Dim bIsLocked As Boolean = DbControllers.m_ProdController.IsLockByProdId(Map.refSupervisorManagerVM.CurrProd.nProdId)
         If bIsLocked Then
            ' mando notifica ad eventuale ottimizzatore di salvare
            DbControllers.m_StatusMapController.UpdateAction("", Map.refSupervisorManagerVM.CurrProd.nProdId, Map.refSupervisorManagerVM.CurrProd.nProdId, StatusMapItemType.Comm, StatusMapOpType.SupervisorStopRequest, "")
            ' aspetto risposta
            Dim WaitingWnd As New WaitingWndV(Application.Current.MainWindow, New WaitingWndVM)
            Dim WaitingResult As Boolean = WaitingWnd.ShowDialog()
            If Not WaitingResult Then
               ' riabilito bottoni di comunicazione a fine invio programma
               Map.refMachCommandMessagePanelVM.SetCommBtnIsEnabled(True)
               Return
            End If
            ' ricarico progetto corrente
            EgtOpenFile(Map.refSupervisorManagerVM.CurrProd.sProdPath)
         End If
         ' creo nuova barra
         Dim RedoMachGroupVM As MyMachGroupVM = RedoRawPart()
         If IsNothing(RedoMachGroupVM) Then
            MessageBox.Show("New RawPart creation failed!")
            Return
         End If
         ' salvo progetto con nuova barra
         Map.refSceneHostVM.SaveProject()
         Dim MyMachGroupList As New List(Of MyMachGroupM)
         If Not IsNothing(Map.refProjectVM.ProdMachGroupPanelVM) Then
            For Each MachGroup In Map.refProjectVM.ProdMachGroupPanelVM.m_MyMachGroupPanelM.MachGroupMList
               MyMachGroupList.Add(MachGroup)
            Next
         End If
         ' aggiorno pezzi su Db
         DbControllers.m_ProdController.UpdateMachGroup(Map.refSupervisorManagerVM.CurrProd.nProdId, MyMachGroupList)
         If bIsLocked Then
            ' mando notifica di barra creata (sblocco ottimizzatore)
            DbControllers.m_StatusMapController.UpdateAction("", Map.refSupervisorManagerVM.CurrProd.nProdId, Map.refSupervisorManagerVM.CurrProd.nProdId, StatusMapItemType.Comm, StatusMapOpType.SupervisorReleaseStop, RedoMachGroupVM.Id.ToString())
         End If
         ' resetto eventuali stati di ripartenza
         SetResetWhileCutting(False)
         If Map.refLeftPanelVM.bRestart Then
            Map.refLeftPanelVM.bRestart = False
         End If
         ' riabilito produzione di tutti gli altri
         MyMachGroupVM.UpdateProduceIsEnabledForAll()
         ' riabilito bottoni di comunicazione a fine invio programma
         Map.refMachCommandMessagePanelVM.SetCommBtnIsEnabled(True)
         ' reimposto visualizzazione gruppo selezionato
         Map.refSupervisorMachGroupPanelVM.SelectedMachGroup = Map.refSupervisorMachGroupPanelVM.SelectedMachGroup
         Return
      End If
      ' se progetto travi e lavorazione interrotta da reset
      If Map.refSupervisorManagerVM.CurrProd.nType = BWType.BEAM AndAlso (bResetWhileCutting OrElse dtStartTime <> DateTime.MinValue) And Not Map.refLeftPanelVM.bRestart Then
         ' chiedo se riprendere o rifare la barra da zero
         Dim bRedo As MessageBoxResult = MessageBox.Show(EgtMsg(62509), "", MessageBoxButton.YesNo, MessageBoxImage.Information)
         Select Case bRedo
            Case MessageBoxResult.Yes
               ' segno da rifare pezzi non completamente lavorati 
               For Each Part As PartVM In PartVMList
                  If Part.dtEndTime <> DateTime.MinValue Then
                     Part.bDO = False
                  Else
                     Part.SetDo(True)
                  End If
                  'Part.bDO = (Part.dtEndTime = DateTime.MinValue)
                  'Part.NotifyPropertyChanged(NameOf(Part.bRedo))
               Next
               ' se ripresa, mostro lista feature e colonne Redo
               Map.refLeftPanelVM.bRestart = True
               ' blocco produzione di tutti gli altri
               MyMachGroupVM.UpdateProduceIsEnabledForAll()
               ' riabilito bottoni di comunicazione a fine invio programma
               Map.refMachCommandMessagePanelVM.SetCommBtnIsEnabled(True)
               Return
            Case MessageBoxResult.No
               ' annullo stati dei pezzi gia' fatti
               For Each Part In PartVMList
                  If Part.dtEndTime <> DateTime.MinValue Then
                     DbControllers.m_PartController.UpdateEnd(Map.refSupervisorManagerVM.CurrProd.nProdId, Id, Part.nPartId, DateTime.MinValue)
                     ' annullo stato end
                     Part.dtEndTime = DateTime.MinValue
                  End If
                  If Part.dtStartTime <> DateTime.MinValue Then
                     DbControllers.m_PartController.UpdateStart(Map.refSupervisorManagerVM.CurrProd.nProdId, Id, Part.nPartId, DateTime.MinValue)
                     DbControllers.m_PartController.UpdateStatus(Map.refSupervisorManagerVM.CurrProd.nProdId, Id, Part.nPartId, ItemState.Assigned)
                     ' annullo stato start
                     Part.nProduction_State = ItemState.Assigned
                     Part.dtStartTime = DateTime.MinValue
                     Part.NotifyPropertyChanged(NameOf(Part.nProduction_State))
                  End If
               Next
               ' annullo stato del MachGroup
               DbControllers.m_MachGroupController.UpdateStart(Map.refSupervisorManagerVM.CurrProd.nProdId, Id, DateTime.MinValue)
               DbControllers.m_MachGroupController.UpdateStatus(Map.refSupervisorManagerVM.CurrProd.nProdId, Id, ItemState.Assigned)
               ' scrivo stato end
               MyMachGroupM.SetProductionState(ItemState.Assigned)
               dtStartTime = DateTime.MinValue
               dtEndTime = DateTime.MinValue
               NotifyPropertyChanged(NameOf(nProduction_State))
               ' resetto stati di produzione del pezzo
               SetResetWhileCutting(False)
               ResetProduce()
               ' lascio proseguire per rifare barra da capo
         End Select
         ' se progetto pareti e lavorazione interrotta da reset
      ElseIf Map.refSupervisorManagerVM.CurrProd.nType = BWType.WALL AndAlso (bResetWhileCutting OrElse dtStartTime <> DateTime.MinValue) Then
         If False Then
            ' chiedo se riprendere o rifare il pannello da zero
            Dim bRedo As MessageBoxResult = MessageBox.Show("Riprendere lavorazione pannello corrente?", "", MessageBoxButton.YesNo, MessageBoxImage.Information)
            Dim MachIndexVariable As Variable = Map.refMachCommandMessagePanelVM.MainVariablesList.FirstOrDefault(Function(x) x.sName = MACHINDEX)
            Select Case bRedo
               ' se ripresa
               Case MessageBoxResult.Yes
                  ' ripristino indice di lavorazione precedente a reset
                  If MachIndexVariable.sValue <> Map.refMachManaging.nMachIndex Then
                     MachIndexVariable.sValue = Map.refMachManaging.nMachIndex
                  End If
               Case MessageBoxResult.No
                  MachIndexVariable.sValue = 1
            End Select
         End If
         SetResetWhileCutting(True)
      End If
      ' aggiorno stato bottoni in LeftPanel
      Map.refLeftPanelVM.UpdateButtonIsEnabledState()

      ' lancio produzione pezzo
      Produce(New List(Of MachGroupVM)({Me}))

   End Sub

   Friend Shared Sub Produce(MachGroupList As List(Of MachGroupVM))
      ' lancio ricalcolo del CN
      Map.refCALCPanelVM.VerifyMachGroup(MachGroupList)
      For Each MachGroup As MyMachGroupVM In MachGroupList
         ' cerco primo indice di pezzo non in produzione
         Dim NewIndex As Integer = Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupVMList.IndexOf(Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupVMList.FirstOrDefault(Function(x) DirectCast(x, MyMachGroupVM).dtStartTime = DateTime.MinValue AndAlso DirectCast(x, MyMachGroupVM).bToBeProduced = False))
         ' se pezzo da produrre gia' iniziato
         If MachGroup.dtStartTime <> DateTime.MinValue Then
            ' decremento indice di 1
            NewIndex -= 1
         End If
         ' segno pezzo da produrre
         MachGroup.m_bToBeProduced = True
         MachGroup.NotifyPropertyChanged(NameOf(MachGroup.Production_Background))
         Map.refSupervisorMachGroupPanelVM.MachGroupVMList_View.Refresh()

         ' sposto MachGroup in lista come ultimo dei pronti da produrre
         Dim OldIndex As Integer = Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupVMList.IndexOf(MachGroup)
         ' se non ho trovato nessuno che deve partire, tengo indice corrente
         If NewIndex < 0 Then NewIndex = OldIndex

         MachGroup.m_nProductionIndex = NewIndex + 1
         ' aggiorno indice di tutte le barre in coda
         For Each CurrMachGroup As MyMachGroupVM In Map.refSupervisorMachGroupPanelVM.MachGroupVMList
            If Not (CurrMachGroup Is MachGroup) AndAlso CurrMachGroup.nProductionIndex >= MachGroup.m_nProductionIndex AndAlso CurrMachGroup.nProductionIndex < 5000 Then
               CurrMachGroup.SetProductionIndex(CurrMachGroup.m_nProductionIndex + 1)
               DbControllers.m_MachGroupController.UpdateOrder(Map.refSupervisorManagerVM.CurrProd.nProdId, CurrMachGroup.Id, CurrMachGroup.nProductionIndex)
            End If
         Next
         ' sposto machgroup corrente
         DbControllers.m_MachGroupController.UpdateOrder(Map.refSupervisorManagerVM.CurrProd.nProdId, MachGroup.Id, MachGroup.m_nProductionIndex)
         Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupVMList.Move(OldIndex, NewIndex)
         If CurrentMachine.Flow = FlowTypes.ONEBYONE Then
            UpdateProduceIsEnabledForAll()
         Else
            MachGroup.NotifyPropertyChanged(NameOf(MachGroup.Produce_IsEnabled))
         End If
      Next

   End Sub

   Public Function RedoRawPart() As MyMachGroupVM
      If IsNothing(Map.refSupervisorManagerVM.CurrProd) Then Return Nothing
      ' variabile che contiene anticipo di pinzaggio primo pezzo
      Dim dHCING As Double = 0
      ' creo nuovo gruppo di lavorazione
      Map.refProjectVM.ProdMachGroupPanelVM.AddMachGroup()
      Dim nCurrMachGroup As Integer = EgtGetCurrMachGroup()
      Dim sCurrMachGroupName As String = ""
      Dim MachGroup As MyMachGroupVM = Nothing
      EgtGetMachGroupName(nCurrMachGroup, sCurrMachGroupName)
      Dim sLogPath As String = Map.refMainWindowVM.MainWindowM.sTempDir & "\RawPartLog.txt"
      ' scrivo dati per variabili P di comunicazione con la macchina in gruppo di lavorazione
      EgtSetInfo(nCurrMachGroup, MGR_RPT_PRODID, Map.refSupervisorManagerVM.CurrProd.nProdId)
      EgtSetInfo(nCurrMachGroup, MGR_RPT_PATTID, nCurrMachGroup)
      EgtSetInfo(nCurrMachGroup, MGR_RPT_MATERIAL, sMATERIAL)
      If Map.refSupervisorManagerVM.CurrProd.nType = BWType.BEAM Then
         ' recupero lista dei pezzi BTL originali
         Dim PartList As New List(Of RedoPart)
         For Each Part In m_PartVMList
            Dim FeatureList As New Dictionary(Of Integer, Boolean)
            For Each Feature In Part.FeatureVMList
               FeatureList.Add(Feature.nPRID, Feature.bDO)
            Next
            PartList.Add(New RedoPart(MyMachGroupPanelM.DuploGetOriginal(Part.nPartId), FeatureList))
         Next
         ' analizzo barra di origine
         Dim dInitialCutOut As Double = 0
         ' scrivo dati costruzione grezzo in gruppo di lavorazione
         Dim nDone As Integer = 0
         For Index = 0 To m_PartVMList.Count - 1
            Dim CurrPart As PartVM = m_PartVMList(Index)
            If CurrPart.bDO Then
               ' se primo pezzo da fare
               If nDone = 0 Then
                  ' recupero anticipo di pinzaggio da vecchia barra
                  dHCING = GetHCING(CurrPart.nPartId)
                  dInitialCutOut += CurrPart.dOffset - 0.1
               End If
               nDone += 1
               ' creo copia del pezzo
               Dim nPartDuploId As Integer = EgtDuploNew(PartList(Index).nPartId)
               PartList(Index).SetDuploId(nPartDuploId)
               ' elimino valori calcolo dell'originale
               MyMachGroupPanelVM.DuploRemoveProjCalc(nPartDuploId)
               ' lo rendo std
               EgtSetMode(nPartDuploId, GDB_MD.STD)
               ' verifico attivazione feature
               Dim DuploFeatureList As List(Of BTLFeatureM) = PartM.LoadBTLFeatures(Nothing, nPartDuploId)
               For Each Feature In DuploFeatureList
                  Dim bOk As Boolean = PartList(Index).FeatureList.Item(Feature.nPRID)
                  EgtBeamEnableProcess(Feature.nFeatureId, bOk)
               Next
               ' scrivo dati costruzione grezzo in gruppo di lavorazione
               EgtSetInfo(nCurrMachGroup, MGR_RPT_PART & nDone, nPartDuploId & "," & DoubleToString(CurrPart.dPOSX - dInitialCutOut, 3))
            Else
               dInitialCutOut += CurrPart.dOffset + CurrPart.dL
            End If
         Next
         EgtSetInfo(nCurrMachGroup, MGR_RPT_BARLEN, dL - dInitialCutOut)
         Dim BeamMachGroup As MyMachGroupVM = Map.refProjectVM.ProdMachGroupPanelVM.GetLastMachGroup()
         ' eseguo script creazione grezzo
         If Not ExecBeam(sLogPath, Map.refMachinePanelVM.SelectedMachine.Name, CalcIntegration.CmdTypes.RAWPART, False) Then
            BeamMachGroup.DeleteMachGroup()
            If File.Exists(sLogPath) Then
               Dim LogFile As String() = File.ReadAllLines(sLogPath)
               If LogFile.Count >= 2 AndAlso Not IsNothing(LogFile(1)) Then
                  MessageBox.Show(LogFile(1), EgtMsg(30007), MessageBoxButton.OK, MessageBoxImage.Error)
               End If
            End If
            Return Nothing
         End If
         ' aggiorno anticipo di pinzaggio in primo pezzo
         EgtSetInfo(EgtGetFirstRawPart(), "HCING", dHCING)
         'aggiorno lista pezzi
         BeamMachGroup.MyMachGroupM.RefreshPartList()
         BeamMachGroup.MyMachGroupM.RefreshGroupData()
         Core.ViewPanelVM.BWSetView(VT.ISO_SW, False)
         ' salvo nuovo grezzo nel progetto
         Map.refSupervisorManagerVM.Save()
         Dim LastDonePart As PartVM = Nothing
         ' segno pezzi non completati come scrap
         For Index = 0 To m_PartVMList.Count - 1
            Dim CurrPart As PartVM = m_PartVMList(Index)
            If CurrPart.bDO Then
               Dim Part As PartVM = m_PartVMList(Index)
               Dim nP_Prod As Integer = Map.refSupervisorManagerVM.CurrProd.nProdId
               Dim nP_Machgroup As Integer = Id
               Dim nP_Part As Integer = m_PartVMList(Index).nPartId
               DbControllers.m_PartController.UpdateEnd(nP_Prod, nP_Machgroup, nP_Part, DateTime.MinValue)
               DbControllers.m_PartController.UpdateStatus(nP_Prod, nP_Machgroup, nP_Part, ItemState.Scrapped)
               ' scrivo stato end
               Part.nProduction_State = ItemState.Scrapped
               Part.dtEndTime = DateTime.MinValue
               Part.NotifyPropertyChanged(NameOf(Part.nProduction_State))
               ' resetto stato redo
               Part.bRedo = False
            Else
               LastDonePart = CurrPart
            End If
         Next
         ' imposto fine MachGroup su fine ultimo pezzo o inizio Machgroup + 1 secondo
         Dim MachGroupEnd As DateTime = dtStartTime + New TimeSpan(0, 0, 1)
         If Not IsNothing(LastDonePart) AndAlso LastDonePart.dtEndTime <> DateTime.MinValue Then
            MachGroupEnd = LastDonePart.dtEndTime
         End If
         ' scrivo data end su Db barra
         DbControllers.m_MachGroupController.UpdateEnd(Map.refSupervisorManagerVM.CurrProd.nProdId, Id, MachGroupEnd)
         DbControllers.m_MachGroupController.UpdateStatus(Map.refSupervisorManagerVM.CurrProd.nProdId, Id, ItemState.Produced)
         ' scrivo stato end
         MyMachGroupM.SetProductionState(ItemState.Produced)
         dtEndTime = MachGroupEnd
         NotifyPropertyChanged(NameOf(nProduction_State))
         NotifyPropertyChanged(NameOf(Produce_IsEnabled))
         MachGroup = BeamMachGroup
      ElseIf Map.refSupervisorManagerVM.CurrProd.nType = BWType.WALL Then
         '' scrivo dati in gruppo di lavorazione
         'Dim dPosX As Double = dKerf
         'Dim dPosY As Double = dKerf
         'EgtSetInfo(nCurrMachGroup, MGR_RPT_PANELLEN, dL)
         'EgtSetInfo(nCurrMachGroup, MGR_RPT_PANELWIDTH, dW)
         'EgtSetInfo(nCurrMachGroup, MGR_RPT_PART & 1, nPartDuploId & "," & dPosX & "," & dPosY & "," & 0 & "," & 0)
         'Dim WallMachGroup As WallMachGroupVM = DirectCast(Map.refMachGroupPanelVM.MachGroupVMList(Map.refMachGroupPanelVM.MachGroupVMList.Count - 1), WallMachGroupVM)
         '' eseguo script creazione grezzo
         'If Not ExecWall(sLogPath, Map.refMachinePanelVM.SelectedMachine.Name, CalcIntegration.CmdType.RAWPART, False) Then
         '   WallMachGroup.DeleteMachGroup()
         '   If File.Exists(sLogPath) Then
         '      Dim LogFile As String() = File.ReadAllLines(sLogPath)
         '      If LogFile.Count >= 2 AndAlso Not IsNothing(LogFile(1)) Then
         '         MessageBox.Show(LogFile(1), EgtMsg(30007), MessageBoxButton.OK, MessageBoxImage.Error)
         '      End If
         '   Else
         '      MessageBox.Show("Impossible creating rawpart", EgtMsg(30007), MessageBoxButton.OK, MessageBoxImage.Error)
         '   End If
         '   Return
         'End If
         '' scrivo dati pezzo
         'EgtSetInfo(nPartDuploId, MGR_PRT_POSX, dPosX)
         'EgtSetInfo(nPartDuploId, MGR_PRT_POSY, dPosY)
         'EgtSetInfo(nPartDuploId, MGR_PRT_ROT, 0)
         'EgtSetInfo(nPartDuploId, MGR_PRT_FLIP, False)
         '' aggiorno contatore pezzi usati in Prod
         'SelPart.RefreshPartInProd()
         '' aggiorno lista pezzi
         'WallMachGroup.m_WallMachGroupM.RefreshPartList()
         'WallMachGroup.m_WallMachGroupM.RefreshGroupData()
         '' aggiorno dati ultilizzo barra
         'WallMachGroup.UpdateUsage()
         'EgtSetView(VT.TOP, False)
      End If
      ' aggiorno dati utilizzo grezzo
      MachGroup.UpdateUsage()
      'passo machgroup a supervisor su Db
      DbControllers.m_MachGroupController.UpdateSupervisor(Map.refSupervisorManagerVM.CurrProd.nProdId, MachGroup.Id, DbControllers.m_SupervisorId)
      MachGroup.SentToSupervisor()
      MachGroup.NotifyPropertyChanged(NameOf(MachGroup.Background))
      ' assegno a nuova barra indice successivo a quella di partenza
      MachGroup.SetProductionIndex(m_nProductionIndex + 1)
      ' assegno stati a pezzi
      For Each Part As PartVM In MachGroup.PartVMList
         DbControllers.m_PartController.UpdateStatus(Map.refSupervisorManagerVM.CurrProd.nProdId, MachGroup.Id, Part.nPartId, ItemState.Assigned)
         Part.nProduction_State = ItemState.Assigned
         Part.NotifyPropertyChanged(NameOf(Part.Background))
         '' disabilito impostazione modificato
         'Dim DisableMgr As New DisableModifiedMgr
         '' blocco modifica del pezzo
         'EgtDuploSetLocked(Part.nPartId)
         '' ripristino precedente impostazione modificato
         'DisableMgr.ReEnable()
      Next
      ' aggiorno indice di tutte le barre in coda
      For Each CurrMachGroup As MyMachGroupVM In Map.refSupervisorMachGroupPanelVM.MachGroupVMList
         If Not (CurrMachGroup Is MachGroup) AndAlso CurrMachGroup.nProductionIndex >= MachGroup.nProductionIndex AndAlso CurrMachGroup.nProductionIndex < 5000 Then
            CurrMachGroup.SetProductionIndex(CurrMachGroup.m_nProductionIndex + 1)
            DbControllers.m_MachGroupController.UpdateOrder(Map.refSupervisorManagerVM.CurrProd.nProdId, CurrMachGroup.Id, CurrMachGroup.nProductionIndex)
         End If
      Next
      ' aggiungo nuova barra subito dopo vecchia
      DbControllers.m_MachGroupController.UpdateOrder(Map.refSupervisorManagerVM.CurrProd.nProdId, MachGroup.Id, MachGroup.nProductionIndex)
      ' aggiungo Machgroup a lista supervisor
      If Not IsNothing(MachGroup) Then Map.refProjectVM.SupervisorMachGroupPanelVM.AddMachGroupToSupervisor(MachGroup)
      ' lo posiziono subito dopo il gruppo di ripartenza
      Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupVMList.Move(Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupVMList.Count - 1, Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupVMList.IndexOf(Me) + 1)
      EgtResetCurrMachGroup()
      EgtZoom(ZM.ALL)
      Return MachGroup
   End Function

   Private Function GetHCING(nOrigPartId As Integer) As Double
      ' inizializzo nuovo contesto
      Dim nCurrCtx As Integer = EgtGetCurrentContext()
      Dim nTempCtx As Integer = EgtInitContext()
      ' inizializzo gestore lavorazioni
      EgtInitMachMgr(Map.refMainWindowVM.MainWindowM.sMachinesRoot, Map.refMainWindowVM.MainWindowM.sToolMakersDir)
      Dim g = EgtOpenFile(Map.refSupervisorManagerVM.CurrProd.sProdDirPath & "\" & Name & ".bwe")
      Dim nFirstId As Integer = EgtGetFirstMachGroup()
      Dim f = EgtSetCurrMachGroup(nFirstId)
      Dim nOldRawId As Integer = EgtGetRawPartFromPart(nOrigPartId)
      Dim dHCING As Double = 0
      EgtGetInfo(nOldRawId, "HCING", dHCING)
      EgtSetCurrentContext(nCurrCtx)
      EgtDeleteContext(nTempCtx)
      Return dHCING
   End Function

#End Region ' ProduceMachGroup

#End Region    ' COMMANDS

#Region "EVENTS"

   Protected Overrides Sub OnPartAdded(sender As Object, e As PartAddedEventArgs)
      Dim PartVM As PartVM = New PartVM(e.NewPart, Me)
      PartVMList.Add(PartVM)
   End Sub

#End Region    ' EVENTS

End Class

Class RedoPart

   Private m_nPartId As Integer
   Public ReadOnly Property nPartId As Integer
      Get
         Return m_nPartId
      End Get
   End Property

   Private m_nDuploId As Integer
   Public ReadOnly Property nDuploId As Integer
      Get
         Return m_nDuploId
      End Get
   End Property
   Friend Sub SetDuploId(nDuploId As Integer)
      m_nDuploId = nDuploId
   End Sub

   Private m_FeatureList As New Dictionary(Of Integer, Boolean)
   Public ReadOnly Property FeatureList As Dictionary(Of Integer, Boolean)
      Get
         Return m_FeatureList
      End Get
   End Property

   Sub New(nPartId As Integer, FeatureList As Dictionary(Of Integer, Boolean))
      m_nPartId = nPartId
      m_FeatureList = FeatureList
   End Sub

End Class