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

Public Class BeamMachGroupVM
   Inherits Core.BeamMachGroupVM

   Public Overrides Property sStartCut As String
      Get
         Return LenToString(m_BeamMachGroupM.dStartCut, 3)
      End Get
      Set(value As String)
         Dim dValue As Double
         If StringToLen(value, dValue) Then
            Dim dOldValue As Double = m_BeamMachGroupM.dStartCut
            m_BeamMachGroupM.dStartCut = dValue
            If Not ReDrawBeamMachgroup() Then
               ' rispristino vecchio valore
               m_BeamMachGroupM.dStartCut = dOldValue
               ReDrawBeamMachgroup()
            End If
            m_BeamMachGroupM.dStartCut = dValue
            EgtDraw()
            If PartVMList.Count > 0 Then
               Dim Beam As BeamVM = DirectCast(PartVMList(0), BeamVM)
               Beam.m_BeamM.UpdateOffset()
               Beam.NotifyPropertyChanged(NameOf(Beam.sOffset))
            End If
            ' resetto validazione del pezzo primo pezzo
            If PartVMList.Count > 0 Then
               PartVMList(0).ResetCalcPart()
            Else
               ResetCalcMachGroup()
            End If
         Else
            NotifyPropertyChanged(NameOf(sStartCut))
         End If
      End Set
   End Property

#Region "CONSTRUCTORS"

   Sub New(BeamMachGroupM As BeamMachGroupM)
      MyBase.New(BeamMachGroupM)
      ' aggiorno stato di produzione
      ReadProductionState()
   End Sub

#End Region    ' CONSTRUCTORS

#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

   Private Sub ReadProductionState()
      If IsNothing(Map.refProdManagerVM.CurrProd) OrElse IsNothing(Map.refProdManagerVM.CurrProd.nProdId) Then Return
      Dim MachGroupModel As MachGroupModel = DbControllers.m_MachGroupController.FindByMachGroupId(Map.refProdManagerVM.CurrProd.nProdId, Id)
      If Not IsNothing(MachGroupModel) Then
         If Not String.IsNullOrEmpty(MachGroupModel.SupervisorId) Then
            SetSupervisorId(MachGroupModel.SupervisorId)
         End If
         MyMachGroupM.SetProductionState(MachGroupModel.State)
      End If
   End Sub

   Public Overrides Sub RefreshPartList()
      ' 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)
         StringToDouble(sSplitInfo(1), m_BeamMachGroupM.dStartCut)
      Else
         m_BeamMachGroupM.dStartCut = 0
      End If
      '' aggiorno lista pezzi
      'PartVMList.Clear()
      'Dim nRawPartId As Integer = EgtGetFirstRawPart()
      'While nRawPartId <> GDB_ID.NULL
      '   Dim nPartId As Integer = EgtGetFirstPartInRawPart(nRawPartId)
      '   If nPartId <> GDB_ID.NULL Then
      '      Dim NewBeam As BeamVM = New BeamVM(Me, nPartId, nRawPartId)
      '      PartVMList.Add(NewBeam)
      '      NewBeam.UpdateOffset()
      '   End If
      '   nRawPartId = EgtGetNextRawPart(nRawPartId)
      'End While
   End Sub

   Public Overrides Sub RefreshGroupData()

   End Sub

   Friend Sub UpdateUsage()
      m_BeamMachGroupM.SetTotMat(dL)
      m_BeamMachGroupM.SetMatForPart(0)
      For Each Part In PartVMList
         m_BeamMachGroupM.SetMatForPart(m_BeamMachGroupM.dMatForPart + Part.dL)
      Next
      NotifyPropertyChanged(NameOf(dUsage))
      NotifyPropertyChanged(NameOf(dWaste))
   End Sub

   Friend Function ReDrawBeamMachgroup() As Boolean
      ' scrivo dati di tutti i pezzi
      Dim dPosX As Double = m_BeamMachGroupM.dStartCut
      Dim nIndex As Integer
      For nIndex = 0 To PartVMList.Count - 1
         If nIndex <> 0 Then
            Dim Beam As BeamVM = DirectCast(PartVMList(nIndex), BeamVM)
            dPosX += Beam.m_BeamM.dOffset
         End If
         PartVMList(nIndex).dPOSX = dPosX
         EgtSetInfo(Id, MGR_RPT_PART & nIndex + 1, PartVMList(nIndex).nPartId & "," & DoubleToString(dPosX, 3))
         dPosX += PartVMList(nIndex).dL
      Next
      ' elimino eventuali successive info pezzi di troppo
      nIndex = PartVMList.Count + 1
      Dim sTemp As String = ""
      While EgtGetInfo(Id, MGR_RPT_PART & nIndex, sTemp)
         EgtSetInfo(Id, MGR_RPT_PART & nIndex, "")
         nIndex += 1
      End While
      ' elimino vecchio grezzo ed eseguo script creazione nuovo
      Dim nRawId As Integer = EgtGetFirstRawPart()
      While nRawId <> GDB_ID.NULL
         EgtRemovePartFromRawPart(EgtGetFirstPartInRawPart(nRawId))
         EgtRemoveRawPart(nRawId)
         nRawId = EgtGetFirstRawPart()
      End While
      If Not ExecBeam(Map.refMainWindowVM.MainWindowM.sTempDir, Map.refMachinePanelVM.SelectedMachine.Name, CalcIntegration.CmdType.RAWPART, False) Then Return False

      Return True
   End Function

   Friend Sub MoveBeam(Beam As BeamVM, MoveDirection As MoveDirections)
      Dim nBeamIndex As Integer = PartVMList.IndexOf(Beam)
      If nBeamIndex = 0 AndAlso MoveDirection = MoveDirections.UP Then Return
      If nBeamIndex = PartVMList.Count - 1 AndAlso MoveDirection = MoveDirections.DOWN Then Return
      ' se pezzo mosso diventa primo
      Dim FirstBeam As BeamVM
      If (nBeamIndex = 1 AndAlso MoveDirection = MoveDirections.UP) OrElse (nBeamIndex = 0 AndAlso MoveDirection = MoveDirections.DOWN) Then
         '' resetto offset per vecchio primo
         FirstBeam = DirectCast(PartVMList(0), BeamVM)
         FirstBeam.ResetOffset()
      End If
      PartVMList.Move(nBeamIndex, nBeamIndex + MoveDirection)
      ReDrawBeamMachgroup()
      ' aggiorno offset primo pezzo
      FirstBeam = DirectCast(PartVMList(0), BeamVM)
      FirstBeam.m_BeamM.UpdateOffset()
      FirstBeam.NotifyPropertyChanged(NameOf(FirstBeam.sOffset))
   End Sub

   Friend Sub ReorderBeam()
      Dim TempPartList = PartVMList.OrderBy(Function(x) x.dL).ToList()
      ' verifico se sono già in oridne
      Dim bSort As Boolean = True
      For PartIndex = 0 To PartVMList.Count - 1
         If PartVMList(PartIndex).nPartId <> TempPartList(PartIndex).nPartId Then
            bSort = False
            Exit For
         End If
      Next
      If bSort Then Return
      ' resetto offset primo pezzo
      Dim FirstBeam As BeamVM = DirectCast(PartVMList(0), BeamVM)
      FirstBeam.ResetOffset()
      For PartIndex = 0 To TempPartList.Count - 1
         If PartVMList(PartIndex).nPartId <> TempPartList(PartIndex).nPartId Then
            PartVMList.Move(PartVMList.IndexOf(TempPartList(PartIndex)), PartIndex)
         End If
      Next
      ReDrawBeamMachgroup()
      ' aggiorno offset primo pezzo
      FirstBeam = DirectCast(PartVMList(0), BeamVM)
      FirstBeam.m_BeamM.UpdateOffset()
      FirstBeam.NotifyPropertyChanged(NameOf(FirstBeam.sOffset))
   End Sub

   Public Overrides Function Copy() As Core.MyMachGroupVM
      EgtResetCurrMachGroup()
      ' recupero lista dei pezzi BTL originali
      Dim PartList As New List(Of BTLPartVM)
      For Each Part In m_PartVMList
         PartList.Add(BTLPartVM.RetrieveBTLPartFromPart(Part.nPartId))
      Next
      ' verifico che nessun pezzo da copiare abbia raggiunto il numero massimo
      If Not VerifyPartCount(PartList) Then Return Nothing
      ' creo nuovo gruppo di lavorazione
      Map.refMachGroupPanelVM.AddMachGroup()
      Dim nCurrMachGroup As Integer = EgtGetCurrMachGroup()
      Dim sCurrMachGroupName As String = ""
      EgtGetMachGroupName(nCurrMachGroup, sCurrMachGroupName)
      ' scrivo dati per variabili P di comunicazione con la macchina in gruppo di lavorazione
      EgtSetInfo(nCurrMachGroup, MGR_RPT_PRODID, Map.refProdManagerVM.CurrProd.nProdId)
      EgtSetInfo(nCurrMachGroup, MGR_RPT_MATERIAL, sMATERIAL)
      EgtSetInfo(nCurrMachGroup, MGR_RPT_PATTID, nCurrMachGroup)
      ' scrivo dati costruzione grezzo in gruppo di lavorazione
      EgtSetInfo(nCurrMachGroup, MGR_RPT_BARLEN, dL)
      For Index = 0 To m_PartVMList.Count - 1
         ' creo copia del pezzo
         Dim nPartDuploId As Integer = EgtDuploNew(PartList(Index).nPartId)
         ' 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 & 1, nPartDuploId & "," & m_PartVMList(Index).sPOSX)
      Next
      Dim BeamMachGroup As BeamMachGroupVM = Map.refMachGroupPanelVM.GetLastMachGroup()
      ' eseguo script creazione grezzo
      Dim sLogPath As String = Map.refMainWindowVM.MainWindowM.sTempDir & "\RawPartLog.txt"
      If Not ExecBeam(sLogPath, Map.refMachinePanelVM.SelectedMachine.Name, CalcIntegration.CmdType.RAWPART, False) Then
         BeamMachGroup.DeleteMachGroup()
         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
         Return Nothing
      End If
      ' aggiorno contatore pezzi usati in Prod
      For Each Part In PartList
         Part.RefreshPartInProd()
      Next
      'aggiorno lista pezzi
      BeamMachGroup.m_BeamMachGroupM.RefreshPartList()
      BeamMachGroup.m_BeamMachGroupM.RefreshGroupData()
      ' aggiorno dati ultilizzo barra
      BeamMachGroup.UpdateUsage()
      EgtSetView(VT.ISO_SW, False)
      Return BeamMachGroup
   End Function

   Private Function VerifyPartCount(SelParts As List(Of BTLPartVM)) As Boolean
      Dim sPartToAdd As String = "Raggiunto numero di pezzi da produrre per:"
      Dim bPartToAdd As Boolean = False
      For Each Part In SelParts
         ' verifico se ci sono pezzi da aggiungere
         If Not Part.CanAddPartToCount() Then
            bPartToAdd = True
            sPartToAdd &= Environment.NewLine & "- PDN" & Part.nPDN & " | BTL QTY " & Part.nCNT & " | ADDED QTY " & Part.nADDED
         End If
      Next
      sPartToAdd &= Environment.NewLine & "Aggiungerli?"
      If bPartToAdd Then
         If MessageBox.Show(sPartToAdd, "", MessageBoxButton.YesNo, MessageBoxImage.Question) = MessageBoxResult.Yes Then
            For Each Part In SelParts
               If Not Part.CanAddPartToCount() Then Part.AddNewPartToAdded()
            Next
         Else
            Return False
         End If
      End If
      Return True
   End Function

#End Region    ' METHODS

#Region "COMMANDS"

#Region "DeleteMachGroup"

   ' Manage the MainWindow_Unloaded event. This method is invoked by the cmdMainWindow_Unloaded.
   Public Overrides Sub DeleteMachGroup()
      ' elimino tutte le copie
      Dim nRawPartId As Integer = EgtGetFirstRawPart()
      If nType = BWType.BEAM Then
         Dim nBeamId As Integer = EgtGetFirstPartInRawPart(nRawPartId)
         While nRawPartId <> GDB_ID.NULL
            If EgtRemovePartFromRawPart(nBeamId) Then
               Dim BTLPart As BTLPartVM = BTLPartVM.RetrieveBTLPartFromPart(nBeamId)
               EgtErase(nBeamId)
               If Not IsNothing(BTLPart) Then BTLPart.RefreshPartInProd()
            End If
            nRawPartId = EgtGetNextRawPart(nRawPartId)
            nBeamId = EgtGetFirstPartInRawPart(nRawPartId)
         End While
      Else
         Dim nWallId As Integer = EgtGetFirstPartInRawPart(nRawPartId)
         While nWallId <> GDB_ID.NULL
            If EgtRemovePartFromRawPart(nWallId) Then
               Dim BTLPart As BTLPartVM = BTLPartVM.RetrieveBTLPartFromPart(nWallId)
               EgtErase(nWallId)
               If Not IsNothing(BTLPart) Then BTLPart.RefreshPartInProd()
            End If
            nWallId = EgtGetFirstPartInRawPart(nRawPartId)
         End While
      End If
      ' elimino MachGroup
      EgtRemoveMachGroup(Me.Id)
      ' rimuovo dalla lista grezzi
      Dim Index As Integer = Map.refMachGroupPanelVM.MachGroupVMList.IndexOf(Me)
      If Index = 0 Then
         If Map.refMachGroupPanelVM.MachGroupVMList.Count > 1 Then
            Map.refMachGroupPanelVM.SelectedMachGroup = Map.refMachGroupPanelVM.MachGroupVMList(0)
         Else
            Map.refMachGroupPanelVM.SelectedMachGroup = Nothing
            EgtDraw()
         End If
      ElseIf Index = Map.refMachGroupPanelVM.MachGroupVMList.Count - 1 Then
         If Map.refMachGroupPanelVM.MachGroupVMList.Count > 1 Then
            Map.refMachGroupPanelVM.SelectedMachGroup = Map.refMachGroupPanelVM.MachGroupVMList(Map.refMachGroupPanelVM.MachGroupVMList.Count - 2)
         Else
            Map.refMachGroupPanelVM.SelectedMachGroup = Nothing
            EgtDraw()
         End If
      Else
         Map.refMachGroupPanelVM.SelectedMachGroup = Map.refMachGroupPanelVM.MachGroupVMList(Index - 1)
      End If
      Map.refMachGroupPanelVM.MachGroupVMList.Remove(Me)
   End Sub

#End Region ' DeleteMachGroup

#End Region    ' COMMANDS

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

End Class
