Imports System.Collections.ObjectModel
Imports System.IO
Imports System.Windows.Input
Imports System.Windows.Media
Imports EgtUILib
Imports EgtWPFLib5

Public Class PartM
   Inherits VMBase

#Region "FIELDS & PROPERTIES"

#Region "General"

   Public Event BTLFeatureAdded As EventHandler(Of BTLFeatureAddedEventArgs)

   Protected m_nType As BWType
   Public ReadOnly Property nType As BWType
      Get
         Return m_nType
      End Get
   End Property

   Protected m_ParentMachGroup As MyMachGroupM
   Public ReadOnly Property ParentMachGroup As MyMachGroupM
      Get
         Return m_ParentMachGroup
      End Get
   End Property

   ' Id geometrico del pezzo
   Protected m_nPartId As Integer
   Public ReadOnly Property nPartId As Integer
      Get
         Return m_nPartId
      End Get
   End Property
   Friend Sub SetPartId(nPartId As Integer)
      m_nPartId = nPartId
   End Sub

   ' Proj del pezzo
   Protected m_nProjId As Integer = 0
   Public Property nProjId As Integer
      Get
         Return m_nProjId
      End Get
      Set(value As Integer)
         m_nProjId = value
      End Set
   End Property

   ' Info del pezzo
   Protected m_nPDN As Integer
   Public ReadOnly Property nPDN As Integer
      Get
         Return m_nPDN
      End Get
   End Property

   Protected m_sNAM As String
   Public ReadOnly Property sNAM As String
      Get
         Return m_sNAM
      End Get
   End Property

   Protected m_dBtlL As Double
   Public ReadOnly Property dBtlL As String
      Get
         Return m_dBtlL
      End Get
   End Property
   Public Property dL As Double
      Get
         Dim frBeam As New Frame3d
         EgtGetGroupGlobFrame(nPartId, frBeam)
         If IsX(frBeam.VersX(), EPS_SMALL) Then
            Return m_dBtlL
         ElseIf IsX(frBeam.VersY(), EPS_SMALL) Then
            Return m_dBtlH
         Else
            Return m_dBtlW
         End If
      End Get
      Set(value As Double)
         m_dBtlL = value
      End Set
   End Property

   Protected m_dBtlW As Double
   Public ReadOnly Property dBtlW As String
      Get
         Return m_dBtlW
      End Get
   End Property
   Public Property dW As Double
      Get
         Dim frBeam As New Frame3d
         EgtGetGroupGlobFrame(nPartId, frBeam)
         If IsY(frBeam.VersX()) Then
            Return m_dBtlL
         ElseIf IsY(frBeam.VersY()) Then
            Return m_dBtlH
         Else
            Return m_dBtlW
         End If
      End Get
      Set(value As Double)
         m_dBtlW = value
      End Set
   End Property

   Protected m_dBtlH As Double
   Public ReadOnly Property dBtlH As String
      Get
         Return m_dBtlH
      End Get
   End Property
   Public Property dH As Double
      Get
         Dim frBeam As New Frame3d
         EgtGetGroupGlobFrame(nPartId, frBeam)
         If IsZ(frBeam.VersX()) Then
            Return m_dBtlL
         ElseIf IsZ(frBeam.VersY()) Then
            Return m_dBtlH
         Else
            Return m_dBtlW
         End If
         Return m_dBtlH
      End Get
      Set(value As Double)
         m_dBtlH = value
      End Set
   End Property

   Protected m_dPOSX As Double
   Public Property dPOSX As Double
      Get
         If nType = BWType.WALL Then
            ' verifico che sia attivo MachGroup di questo pezzo
            If EgtGetCurrMachGroup() = ParentMachGroup.Id Then
               ' recupero box pezzo
               Dim b3Part As New BBox3d
               EgtGetBBoxGlob(nPartId, GDB_BB.ONLY_VISIBLE + GDB_BB.IGNORE_TEXT + GDB_BB.IGNORE_DIM, b3Part)
               ' recupero layer del box
               Dim nBoxLayerId As Integer = EgtGetFirstNameInGroup(nPartId, "Box")
               ' recupero box del layer box
               Dim b3Box As New BBox3d
               EgtGetBBoxGlob(nBoxLayerId, GDB_BB.STANDARD, b3Box)
               ' recupero origine grezzo
               Dim nrawPartId As Integer = EgtGetRawPartFromPart(nPartId)
               Dim b3Raw As New BBox3d
               EgtGetRawPartBBox(nrawPartId, b3Raw)
               ' calcolo distanza tra origine pezzo e tavolo
               Dim vtPartRef As New Vector3d(b3Box.Min() - b3Raw.Min())
               m_dPOSX = vtPartRef.x
               Return vtPartRef.x
               ' altrimenti restituisco valore salvato (per quando viene clickato un BTLPart)
            Else
               Return m_dPOSX
            End If
         Else     ' nType = BWType.BEAM
            Return m_dPOSX
         End If
      End Get
      Set(value As Double)
         m_dPOSX = value
      End Set
   End Property

   Protected m_nCNT As Integer
   Public Property nCNT As Integer
      Get
         Return m_nCNT
      End Get
      Set(value As Integer)
         m_nCNT = value
      End Set
   End Property

   Protected m_nINVERTED As Integer
   Public ReadOnly Property nINVERTED As Integer
      Get
         Return m_nINVERTED
      End Get
   End Property
   Public Sub SetInverted(nInverted As Integer)
      m_nINVERTED = nInverted
   End Sub

   Protected m_nROTATED As Integer
   Public ReadOnly Property nROTATED As Integer
      Get
         Return m_nROTATED
      End Get
   End Property
   Public Sub SetRotated(nRotated As Integer)
      m_nROTATED = nRotated
   End Sub

   Protected m_sMATERIAL As String
   Public Property sMATERIAL As String
      Get
         Return m_sMATERIAL
      End Get
      Set(value As String)
         m_sMATERIAL = value
      End Set
   End Property

   Public m_sSTOREY As String
   Public Property sSTOREY As String
      Get
         Return m_sSTOREY
      End Get
      Set(value As String)
         m_sSTOREY = value
      End Set
   End Property

   Public m_sGROUP As String
   Public Property sGROUP As String
      Get
         Return m_sGROUP
      End Get
      Set(value As String)
         m_sGROUP = value
      End Set
   End Property

   Protected m_nBTLPartId As Integer
   Public ReadOnly Property nBTLPartId As Integer
      Get
         Return m_nBTLPartId
      End Get
   End Property

   ' lista delle feature del pezzo
   Protected m_FeatureMList As List(Of BTLFeatureM)
   Public Property FeatureMList As List(Of BTLFeatureM)
      Get
         Return m_FeatureMList
      End Get
      Set(value As List(Of BTLFeatureM))
         m_FeatureMList = value
      End Set
   End Property

#End Region    ' General

#Region "Beam"

   ' Id del grezzo
   Protected m_nRawPartId As Integer = GDB_ID.NULL
   Public ReadOnly Property nRawPartId As Integer
      Get
         Return m_nRawPartId
      End Get
   End Property

   Protected m_dOffset As Double
   Public Property dOffset As Double
      Get
         Return m_dOffset
      End Get
      Set(value As Double)
         m_dOffset = value
      End Set
   End Property

#End Region    ' Beam

#Region "Wall"

   Protected m_dPOSY As Double
   Public Property dPOSY As Double
      Get
         ' verifico che sia attivo MachGroup di questo pezzo
         If EgtGetCurrMachGroup() = ParentMachGroup.Id Then
            ' recupero box pezzo
            Dim b3Part As New BBox3d
            EgtGetBBoxGlob(nPartId, GDB_BB.ONLY_VISIBLE + GDB_BB.IGNORE_TEXT + GDB_BB.IGNORE_DIM, b3Part)
            ' recupero layer del box
            Dim nBoxLayerId As Integer = EgtGetFirstNameInGroup(nPartId, "Box")
            ' recupero box del layer box
            Dim b3Box As New BBox3d
            EgtGetBBoxGlob(nBoxLayerId, GDB_BB.STANDARD, b3Box)
            ' recupero origine grezzo
            Dim nrawPartId As Integer = EgtGetRawPartFromPart(nPartId)
            Dim b3Raw As New BBox3d
            EgtGetRawPartBBox(nrawPartId, b3Raw)
            ' calcolo distanza tra origine pezzo e tavolo
            Dim vtPartRef As New Vector3d(b3Box.Min() - b3Raw.Min())
            m_dPOSY = vtPartRef.y
            Return vtPartRef.y
            ' altrimenti restituisco valore salvato (per quando viene clickato un BTLPart)
         Else
            Return m_dPOSY
         End If
         'Return m_dPOSY
      End Get
      Set(value As Double)
         m_dPOSY = value
      End Set
   End Property

   Protected m_dROT As Double
   Public Property dROT As Double
      Get
         Return m_dROT
      End Get
      Set(value As Double)
         m_dROT = value
      End Set
   End Property

   Protected m_nFLIP As Integer
   Public Property nFLIP As Integer
      Get
         Return m_nFLIP
      End Get
      Set(value As Integer)
         m_nFLIP = value
      End Set
   End Property

   Protected m_dVolume As Double
   Public Property dVolume As Double
      Get
         Return m_dVolume
      End Get
      Set(value As Double)
         m_dVolume = value
      End Set
   End Property

#End Region    ' Wall

#Region "Calc"

   Protected m_nCALC_GlobalState As CalcStates = CalcStates.NOTCALCULATED
   Public Property nCALC_GlobalState As CalcStates
      Get
         Return m_nCALC_GlobalState
      End Get
      Set(value As CalcStates)
         m_nCALC_GlobalState = value
      End Set
   End Property

   Private m_nCALC_GlobalERR As Integer
   Public Property nCALC_GlobalERR As Integer
      Get
         Return m_nCALC_GlobalERR
      End Get
      Set(value As Integer)
         m_nCALC_GlobalERR = value
      End Set
   End Property

   Protected m_nCALC_State As CalcStates = CalcStates.NOTCALCULATED
   Public Property nCALC_State As CalcStates
      Get
         Return m_nCALC_State
      End Get
      Set(value As CalcStates)
         m_nCALC_State = value
      End Set
   End Property

   Protected m_nCALC_ERR As Integer
   Public Property nCALC_ERR As Integer
      Get
         Return m_nCALC_ERR
      End Get
      Set(value As Integer)
         m_nCALC_ERR = value
      End Set
   End Property

   Protected m_sCALC_MSG As String = String.Empty
   Public Property sCALC_MSG As String
      Get
         Return MessageFromLuaMsg(m_sCALC_MSG)
      End Get
      Set(value As String)
         m_sCALC_MSG = value
      End Set
   End Property

   Protected m_nCALC_ROT As Integer
   Public Property nCALC_ROT As Integer
      Get
         Return m_nCALC_ROT
      End Get
      Set(value As Integer)
         m_nCALC_ROT = value
      End Set
   End Property

   Protected m_nCALC_FALL As Integer
   Public Property nCALC_FALL As Integer
      Get
         Return m_nCALC_FALL
      End Get
      Set(value As Integer)
         m_nCALC_FALL = value
      End Set
   End Property

   Protected m_nCALC_TIME As Integer
   Public Property nCALC_TIME As Integer
      Get
         Return m_nCALC_TIME
      End Get
      Set(value As Integer)
         m_nCALC_TIME = value
      End Set
   End Property

#End Region    ' Calc

#Region "Supervisor"

   Protected m_nProductionState As ItemState = ItemState.ND
   Public ReadOnly Property nProductionState As ItemState
      Get
         Return m_nProductionState
      End Get
   End Property
   Public Sub SetProductionState(nState As CalcStates)
      m_nProductionState = nState
   End Sub

   Protected m_dtStartTime As DateTime
   Public Property dtStartTime As DateTime
      Get
         Return m_dtStartTime
      End Get
      Set(value As DateTime)
         m_dtStartTime = value
      End Set
   End Property

   Protected m_dtEndTime As DateTime
   Public Property dtEndTime As DateTime
      Get
         Return m_dtEndTime
      End Get
      Set(value As DateTime)
         m_dtEndTime = value
      End Set
   End Property

#End Region    ' Supervisor

#End Region    ' FIELDS & PROPERTIES

#Region "CONSTRUCTOR"

   Sub New(nParentMachGroup As MyMachGroupM, nPartId As Integer)
      m_ParentMachGroup = nParentMachGroup
      SetPartId(nPartId)
      ' imposto BtlPart da cui deriva questo Duplo
      m_nBTLPartId = MyMachGroupPanelM.DuploGetOriginal(nPartId)
   End Sub

   Public Shared Function CreatePart(Type As BWType, nParentMachGroup As MyMachGroupM, nPartId As Integer, nRawPartId As Integer) As PartM
      Dim NewPartM As New PartM(nParentMachGroup, nPartId)
      NewPartM.m_nType = Type
      NewPartM.m_nRawPartId = nRawPartId
      ' leggo info pezzo
      EgtGetInfo(nPartId, BTL_PRT_PROJ, NewPartM.m_nProjId)
      EgtGetInfo(nPartId, BTL_PRT_PDN, NewPartM.m_nPDN)
      EgtGetInfo(nPartId, BTL_PRT_NAM, NewPartM.m_sNAM)
      EgtGetInfo(nPartId, BTL_PRT_L, NewPartM.m_dBtlL)
      EgtGetInfo(nPartId, BTL_PRT_W, NewPartM.m_dBtlW)
      EgtGetInfo(nPartId, BTL_PRT_H, NewPartM.m_dBtlH)
      EgtGetInfo(nPartId, BTL_PRT_CNT, NewPartM.m_nCNT)
      EgtGetInfo(nPartId, BTL_PRT_GROUP, NewPartM.m_sGROUP)
      EgtGetInfo(nPartId, BTL_PRT_STOREY, NewPartM.m_sSTOREY)
      EgtGetInfo(nPartId, BTL_PRT_MATERIAL, NewPartM.m_sMATERIAL)
      Dim nTemp As Integer = 0
      If Not EgtGetInfo(nPartId, BTL_PRT_ROTATED, nTemp) Then
         nTemp = 0
      End If
      NewPartM.SetRotated(nTemp)
      If Not EgtGetInfo(nPartId, BTL_PRT_INVERTED, nTemp) Then
         nTemp = 0
      End If
      NewPartM.SetInverted(nTemp)
      If NewPartM.m_nType = BWType.BEAM Then
         ' leggo PosX
         Dim sInfo As String = ""
         Dim Index = 1
         Dim sSplitInfo() As String = Nothing
         Dim bFound As Boolean = False
         While EgtGetInfo(NewPartM.m_ParentMachGroup.Id, MGR_RPT_PART & Index, sInfo)
            If Not String.IsNullOrWhiteSpace(sInfo) Then
               sSplitInfo = sInfo.Split(","c)
               If sSplitInfo(0) = nPartId Then
                  bFound = True
                  Exit While
               End If
            End If
            Index += 1
         End While
         If bFound Then
            StringToDoubleAdv(sSplitInfo(1), NewPartM.m_dPOSX)
         End If
      Else
         ' leggo PosX, PosY, Rot e Flip
         EgtGetInfo(nPartId, MGR_PRT_POSX, NewPartM.m_dPOSX)
         EgtGetInfo(nPartId, MGR_PRT_POSY, NewPartM.m_dPOSY)
         EgtGetInfo(nPartId, MGR_PRT_ROT, NewPartM.m_dROT)
         EgtGetInfo(nPartId, MGR_PRT_FLIP, NewPartM.m_nFLIP)
      End If
      ' leggo volume 
      If Not EgtGetInfo(nPartId, BTL_PRT_VOLUME, NewPartM.dVolume) Then
         Dim nOrigId As Integer = EgtDuploGetOriginal(nPartId)
         EgtGetInfo(nOrigId, BTL_PRT_VOLUME, NewPartM.dVolume)
      End If
      ' leggo feature
      NewPartM.m_FeatureMList = LoadBTLFeatures(NewPartM, nPartId)
      ReadMachGroupData(NewPartM)
      Return NewPartM
   End Function

#End Region    ' CONSTRUCTOR

#Region "METHODS"

#Region "Part"

   Public Shared Sub ReadMachGroupData(NewPartM As PartM)
      ' leggo calc error
      Dim nErr As Integer = 0
      Dim nRot As Integer = 0
      Dim nFall As Integer = 0
      Dim sMsg As String = ""
      Dim bCalc As Boolean = False
      bCalc = EgtGetInfo(NewPartM.nPartId, ITG_PROD_ERR, nErr)
      EgtGetInfo(NewPartM.nPartId, ITG_PROD_ROT, nRot)
      EgtGetInfo(NewPartM.nPartId, ITG_PROD_FALL, nFall)
      EgtGetInfo(NewPartM.nPartId, ITG_PROD_MSG, sMsg)
      If Not bCalc Then
         NewPartM.m_nCALC_State = CalcStates.NOTCALCULATED
         NewPartM.m_nCALC_ERR = -1
         NewPartM.m_nCALC_ROT = 0
         NewPartM.m_nCALC_FALL = 0
         NewPartM.m_sCALC_MSG = ""
      Else
         NewPartM.m_nCALC_ERR = nErr
         NewPartM.m_nCALC_ROT = nRot
         NewPartM.m_nCALC_FALL = nFall
         NewPartM.m_sCALC_MSG = sMsg
         Select Case nErr
            Case 0
               NewPartM.nCALC_State = CalcStates.OK
            Case 22
               NewPartM.nCALC_State = CalcStates.COLLISION
            Case 17, 19
               NewPartM.nCALC_State = CalcStates.WARNING
            Case < 0
               NewPartM.nCALC_State = CalcStates.INFO
            Case > 0
               NewPartM.nCALC_State = CalcStates.ERROR_
         End Select
      End If
      EgtGetInfo(NewPartM.nPartId, ITG_PROD_TIME, NewPartM.m_nCALC_TIME)
   End Sub

   Public Sub ReadVolume()
      ' leggo volume 
      If Not EgtGetInfo(nPartId, BTL_PRT_VOLUME, dVolume) Then
         Dim nOrigId As Integer = EgtDuploGetOriginal(nPartId)
         EgtGetInfo(nOrigId, BTL_PRT_VOLUME, dVolume)
      End If
   End Sub

#End Region    ' Part

#Region "Beam"

   Public Sub UpdateOffset()
      ' calcolo offset
      Dim nBeamIndex As Integer = ParentMachGroup.PartMList.IndexOf(Me)
      If nBeamIndex > 0 Then
         m_dOffset = dPOSX - (ParentMachGroup.PartMList(nBeamIndex - 1).dPOSX + ParentMachGroup.PartMList(nBeamIndex - 1).dL)
      Else
         m_dOffset = dPOSX
      End If
   End Sub

#End Region    ' Beam

#Region "Features"

   Public Shared Function LoadBTLFeatures(NewPartM As PartM, nPartId As Integer) As List(Of BTLFeatureM)
      Dim TempList As New List(Of BTLFeatureM)
      ' Aggiungo outline
      Dim nOutLayerId As Integer = EgtGetFirstNameInGroup(nPartId, OUTLINE)
      Dim nOutlineId As Integer = EgtGetFirstInGroup(nOutLayerId)
      While nOutlineId <> GDB_ID.NULL
         ' verifico che sia una feature
         Dim nGRP As Integer
         If EgtGetInfo(nOutlineId, BTL_FTR_GRP, nGRP) AndAlso Not EgtExistsInfo(nOutlineId, BTL_FTR_MAINID) Then
            ' creo la feature
            TempList.Add(BTLFeatureM.CreateBTLFeature(NewPartM, nOutlineId, False))
         End If
         nOutlineId = EgtGetNext(nOutlineId)
      End While
      ' Aggiungo 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
            ' creo la feature
            TempList.Add(BTLFeatureM.CreateBTLFeature(NewPartM, nFeatureId, False))
         End If
         nFeatureId = EgtGetNext(nFeatureId)
      End While
      Return TempList
   End Function

   Public Sub AddBTLFeature(BTLFeatureM As BTLFeatureM)
      If IsNothing(BTLFeatureM) Then Return
      If Not m_FeatureMList.Contains(BTLFeatureM) Then
         m_FeatureMList.Add(BTLFeatureM)
         RaiseEvent BTLFeatureAdded(Me, New BTLFeatureAddedEventArgs(BTLFeatureM))
      End If
   End Sub

   Public Function GetBTLFeatures() As List(Of BTLFeatureM)
      Return New List(Of BTLFeatureM)(m_FeatureMList)
   End Function

#End Region    ' Features

#End Region    ' METHODS

End Class
