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

Public Class BeamMachGroupVM
   Inherits Core.BeamMachGroupVM

   Public Overrides ReadOnly Property Produce_IsEnabled As Boolean
      Get
         Select Case nProduction_State
            Case ItemState.Assigned, ItemState.Confirmed
               Return Not m_bToBeProduced
            Case ItemState.WIP
               If Map.refMachCommandMessagePanelVM.OPState = 0 OrElse
                  Map.refMachCommandMessagePanelVM.OPState = MachCommandMessagePanelVM.MachineOperatingState.End OrElse
                  Map.refMachCommandMessagePanelVM.OPState = MachCommandMessagePanelVM.MachineOperatingState.Stop OrElse
                  Map.refMachCommandMessagePanelVM.OPState = MachCommandMessagePanelVM.MachineOperatingState.Unspecified Then
                  Return True
               End If
            Case Else
               Return False
         End Select
      End Get
   End Property

   ' definizione comandi
   Private m_cmdDeleteMachGroup As ICommand

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

#Region "METHODS"

   Protected Overrides Sub CreateBeamVMList()
      Dim all As List(Of BeamVM) = (From BeamM In m_BeamMachGroupM.GetParts()
                                    Select New BeamVM(BeamM, Me)).ToList()

      For Each BeamVM As BeamVM In all
         AddHandler BeamVM.PropertyChanged, AddressOf OnBeamVMPropertyChanged
      Next

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

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

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

   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
         m_bCNReCalculated = True
         NotifyPropertyChanged(NameOf(Production_Background))
      End If
   End Sub

#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
      SetResetWhileCutting(True)
      If Map.refLeftPanelVM.bRestart 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
            Return
         End If
         ' ricarico progetto corrente
         EgtOpenFile(Map.refSupervisorManagerVM.CurrProd.sProdPath)
         ' creo nuova barra
         Dim RedoMachGroupVM As MyMachGroupVM = RedoRawPart()
         ' 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)
         ' mando notifica di barra creata (sblocco ottimizzatore)
         DbControllers.m_StatusMapController.UpdateAction("", Map.refSupervisorManagerVM.CurrProd.nProdId, Map.refSupervisorManagerVM.CurrProd.nProdId, StatusMapItemType.Comm, StatusMapOpType.SupervisorReleaseStop, "")
         ' resetto eventuali stati di ripartenza
         If bResetWhileCutting Then
            SetResetWhileCutting(False)
            If Map.refLeftPanelVM.bRestart Then
               Map.refLeftPanelVM.bRestart = False
            End If
         End If
         '' lancio produzione del nuovo 
         'RedoMachGroupVM.ProduceMachGroup()
         Return
      End If
      ' se lavorazione interrotta da reset
      If bResetWhileCutting And Not Map.refLeftPanelVM.bRestart Then
         ' chiedo se riprendere o rimandare i pezzi non fatti all'ottimizzatore
         If MessageBox.Show("Riprendere lavorazione barra corrente?", "", MessageBoxButton.YesNo, MessageBoxImage.Information) = MessageBoxResult.Yes Then
            ' se ripresa, mostro lista feature e colonne Redo
            Map.refLeftPanelVM.bRestart = True
            Return
         End If
      End If
      ' 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))
      ' segno pezzo da produrre
      m_bToBeProduced = True
      NotifyPropertyChanged(NameOf(Production_Background))
      ' lancio ricalcolo del CN
      Map.refCALCPanelVM.VerifyMachGroup(Me)

      ' sposto MachGroup in lista come ultimo dei pronti da produrre
      Dim OldIndex As Integer = Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupVMList.IndexOf(Me)
      DbControllers.m_MachGroupController.UpdateOrder(Map.refSupervisorManagerVM.CurrProd.nProdId, Id, NewIndex + 1)
      Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupVMList.Move(OldIndex, NewIndex)
      NotifyPropertyChanged(NameOf(Produce_IsEnabled))
   End Sub

   Public Function RedoRawPart() As MyMachGroupVM
      If IsNothing(Map.refSupervisorManagerVM.CurrProd) Then Return Nothing
      ' creo nuovo gruppo di lavorazione
      Map.refProjectVM.ProdMachGroupPanelVM.AddMachGroup()
      Dim nCurrMachGroup As Integer = EgtGetCurrMachGroup()
      Dim sCurrMachGroupName As String = ""
      Dim MachGroup As MyMachGroupVM
      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 Integer)
         For Each Part In m_PartVMList
            PartList.Add(EgtDuploGetOriginal(Part.nPartId))
         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 BeamVM = m_PartVMList(Index)
            If CurrPart.bDO Then
               nDone += 1
               ' creo copia del pezzo
               Dim nPartDuploId As Integer = EgtDuploNew(PartList(Index))
               ' elimino valori calcolo dell'originale
               MyMachGroupPanelVM.DuploRemoveProjCalc(nPartDuploId)
               ' lo rendo std
               EgtSetMode(nPartDuploId, GDB_MD.STD)
               ' scrivo dati costruzione grezzo in gruppo di lavorazione
               EgtSetInfo(nCurrMachGroup, MGR_RPT_PART & nDone, nPartDuploId & "," & CurrPart.sPOSX - dInitialCutOut)
            Else
               dInitialCutOut += CurrPart.dOffset + CurrPart.dL
            End If
         Next
         EgtSetInfo(nCurrMachGroup, MGR_RPT_BARLEN, dL - dInitialCutOut)
         Dim BeamMachGroup As BeamMachGroupVM = Map.refProjectVM.ProdMachGroupPanelVM.GetLastMachGroup()
         ' eseguo script creazione grezzo
         If Not ExecBeam(sLogPath, Map.refMachinePanelVM.SelectedMachine.Name, CalcIntegration.CmdType.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 lista pezzi
         BeamMachGroup.m_BeamMachGroupM.RefreshPartList()
         BeamMachGroup.m_BeamMachGroupM.RefreshGroupData()
         ''' aggiorno dati utilizzo barra
         ''BeamMachGroup.UpdateUsage()
         EgtSetView(VT.ISO_SW, False)
         ' segno pezzi non completati come scrap
         For Index = 0 To m_PartVMList.Count - 1
            Dim CurrPart As BeamVM = 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 = 2
               Part.dtEndTime = DateTime.MinValue
               Part.NotifyPropertyChanged(NameOf(Part.nProduction_State))
               ' resetto stato redo
               Part.bRedo = False
               ' scrivo data end su Db barra
               DbControllers.m_MachGroupController.UpdateEnd(nP_Prod, nP_Machgroup, DateTime.MinValue)
               DbControllers.m_MachGroupController.UpdateStatus(nP_Prod, nP_Machgroup, ItemState.Produced)
               ' scrivo stato end
               MyMachGroupM.SetProductionState(2)
               dtEndTime = DateTime.MinValue
               NotifyPropertyChanged(NameOf(nProduction_State))
            End If
         Next
         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
      'passo machgroup a supervisor su Db
      DbControllers.m_MachGroupController.UpdateSupervisor(Map.refSupervisorManagerVM.CurrProd.nProdId, MachGroup.Id, DbControllers.m_SupervisorId)
      DbControllers.m_MachGroupController.UpdateOrder(Map.refSupervisorManagerVM.CurrProd.nProdId, MachGroup.Id, 10000)
      ' aggiungo Machgroup a lista supervisor
      If Not IsNothing(MachGroup) Then Map.refProjectVM.SupervisorMachGroupPanelVM.AddMachGroupToSupervisor(MachGroup)
      ' lo posiziono subito dopo il gruppo di ripartenza (devo cambiare indice anche su DB??)
      Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupVMList.Move(Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupVMList.Count - 1, Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupVMList.IndexOf(Me) + 1)
      EgtZoom(ZM.ALL)
      Return MachGroup
   End Function

#End Region ' ProduceMachGroup

#End Region    ' COMMANDS

End Class
