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

Public Class SupervisorManagerVM
   Inherits VMBase

#Region "FIELDS & PROPERTIES"

   Private m_OpenProj_Timer As New DispatcherTimer
   Private m_bOpenProj As Boolean = False
   Private m_nProjIdToOpen As Integer = GDB_ID.NULL

   Private m_SupervisorManager_IsEnabled As Boolean = True
   Public ReadOnly Property SupervisorManager_IsEnabled As Boolean
      Get
         Return m_SupervisorManager_IsEnabled
      End Get
   End Property

   Private m_CurrProd As ProdFileVM
   Friend Property CurrProd As ProdFileVM
      Get
         Return m_CurrProd
      End Get
      Set(value As ProdFileVM)
         m_CurrProd = value
      End Set
   End Property

   Private m_bLoadingProd As Boolean = False
   Public Property bLoadingProd As Boolean
      Get
         Return m_bLoadingProd
      End Get
      Set(value As Boolean)
         m_bLoadingProd = value
      End Set
   End Property

   Friend m_MruFiles As New MruList
   Public ReadOnly Property MruFileNames As ObservableCollection(Of String)
      Get
         Dim IdAndBTLFileNames As New ObservableCollection(Of String)
         For Each FileName In m_MruFiles.FileNames.ToList()
            Dim PdId As Integer = 0
            Dim sPdId As String = Path.GetFileNameWithoutExtension(DirectCast(FileName, String).Replace("__", "_"))
            Integer.TryParse(sPdId, PdId)
            Dim PdFileM = DbControllers.m_ProdController.FindCoreByProdId(PdId)
            If IsNothing(PdFileM) Then
               m_MruFiles.Remove(FileName)
            Else
               Dim PdFileVM = New ProdFileVM(PdFileM)
               IdAndBTLFileNames.Add(sPdId & " | " & PdFileVM.sBTLFileName)
            End If
         Next
         Return IdAndBTLFileNames
      End Get
   End Property

   ' indice progetto in caricamento
   Private m_nLoadingProdId As Integer = 0
   Public ReadOnly Property nLoadingProdId As Integer
      Get
         Return m_nLoadingProdId
      End Get
   End Property

   ' Definizione comandi
   Private m_cmdOpen As ICommand
   Private m_cmdOpenMruFile As ICommand
   'Private m_cmdSave As ICommand
   Private m_cmdGoToProd As ICommand

#Region "ToolTip"

   'Proprietà ToolTip
   Public ReadOnly Property OpenToolTip As String
      Get
         Return EgtMsg(MSG_TOPCOMMANDBAR + 2)
      End Get
   End Property
   Public ReadOnly Property GoToProd_ToolTip As String
      Get
         Return EgtMsg(61835)
      End Get
   End Property




#End Region ' ToolTip
#End Region    ' Fields & Properties
#Region "CONSTRUCTOR"

   Sub New()
      ' Creo riferimento a questa classe in Map
      Map.SetRefSupervisorManagerVM(Me)
      ' Impostazioni MruLists
      m_MruFiles.Init(S_MRUSUPERVISORPRODFILES, 8)
      ' imposto timer di apertura da ottimizzatore
      m_OpenProj_Timer.Interval = TimeSpan.FromMilliseconds(500)
      AddHandler m_OpenProj_Timer.Tick, AddressOf OpenProject_Tick
      m_OpenProj_Timer.Start()
   End Sub

#End Region    ' CONSTRUCTOR

#Region "METHODS"

   Public Function SetCurrProd(nProdId As Integer) As Boolean
      Dim Currprod As ProdFileM = DbControllers.m_ProdController.FindCoreByProdId(nProdId)
      If IsNothing(Currprod) Then Return False
      m_CurrProd = New ProdFileVM(Currprod)
      Return True
   End Function

   Friend Sub SetSupervisorManagerIsEnabled(bIsEnabled As Boolean)
      m_SupervisorManager_IsEnabled = bIsEnabled
      NotifyPropertyChanged(NameOf(SupervisorManager_IsEnabled))
   End Sub

   Friend Sub Save()
      If IsNothing(m_CurrProd) Then Return
      Map.refSceneHostVM.SaveProject()
      Map.refMainWindowVM.UpdateTitle()
      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(CurrProd.nProdId, MyMachGroupList)
   End Sub

   Public Sub OpenProjectFromOptimizer(ProjIdToOpen As Integer)
      If ProjIdToOpen <> Map.refSupervisorManagerVM.m_CurrProd.nProdId Then
         m_nProjIdToOpen = ProjIdToOpen
         m_bOpenProj = True
      End If
   End Sub

   Public Sub OpenProject_Tick()
      If Not m_bOpenProj Then Return
      m_bOpenProj = False
      ' recupero progetto da Id 
      Dim DbProject As ProdFileM
      DbProject = DbControllers.m_ProdController.FindCoreByProdId(m_nProjIdToOpen)
      Dim ProjectVM As New ProdFileVM(DbProject)
      OpenProject(ProjectVM)
      m_nProjIdToOpen = GDB_ID.NULL
   End Sub

#End Region    ' METHODS

#Region "COMMANDS"

#Region "OpenCommand"

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

   ''' <summary>
   ''' Execute the Open.  This method is invoked by the OpenCommand.
   ''' </summary>
   Friend Sub Open()
      OpenProject(Nothing)
   End Sub

   Friend Sub OpenProject(TempCurrProd As ProdFileVM)
      ' se macchina connessa e non in reset  
      If Not IsNothing(Map.refMachManaging) AndAlso Map.refLeftPanelVM.SelOPState.Id <> OPStates.End Then
         ' impedisco cambio progetto
         MessageBox.Show("Press reset before changing program!!")
         Return
      End If
      Dim sFilePath As String = ""
      ' se la string è vuota
      Dim OpenProjectFileDialogVM As OpenProjectFileDialogVM = Nothing
      If IsNothing(TempCurrProd) Then
         ' apro dialogo di scelta file
         OpenProjectFileDialogVM = New OpenProjectFileDialogVM
         Dim OpenFile As New OpenProjectFileDialogV(Application.Current.MainWindow, OpenProjectFileDialogVM)
         Dim DialogResult As Boolean? = OpenFile.EgtShowDialog(ProjectType.PROD)
         If IsNothing(DialogResult) OrElse Not DialogResult Then Return
         sFilePath = OpenProjectFileDialogVM.SelProject.sProdPath
         TempCurrProd = OpenProjectFileDialogVM.SelProject
      Else
         sFilePath = If(Not IsNothing(TempCurrProd.sProdPath), TempCurrProd.sProdPath, "")
      End If
      Core.ViewPanelVM.UpdateBWType(TempCurrProd.nType)
      ' imposto ProdId di caricamento
      m_nLoadingProdId = TempCurrProd.nProdId
      m_bLoadingProd = True
      If File.Exists(sFilePath) Then
         ' se la macchina del progetto in apertura non è quella del supervisore, lo segnalo e apro un progetto vuoto
         If CurrentMachine.sMachineName <> TempCurrProd.sMachine Then
            ' rimuovo il file in apertura dalla lista degli MRU
            m_MruFiles.Remove(sFilePath)
            MessageBox.Show(String.Format("Impossible opening a project done with {0} in a supervisor on a {1}!", {TempCurrProd.sMachine, CurrentMachine.sMachineName}), EgtMsg(10001), MessageBoxButton.OK, MessageBoxImage.Error)        'Error
            EgtNewFile()
            EgtDraw()
            Map.refProjectVM.ProdMachGroupPanelVM = New MyMachGroupPanelVM(MyMachGroupPanelM.CreateMyMachGroupPanel(Map.refMachinePanelVM.MachineList.ToList()))
            Map.refProjectVM.SupervisorMachGroupPanelVM = New SupervisorMachGroupPanelVM(MachGroupPanelM.CreateNewMachGroupPanel())
            CurrProd = Nothing
            Map.refMainWindowVM.UpdateTitle()
            m_bLoadingProd = False
            NotifyPropertyChanged(NameOf(MruFileNames))
            LoadingWndHelper.CloseLoadingWnd(ActiveIds.OPENPROD)
            Return
         End If
         LoadingWndHelper.OpenLoadingWnd(ActiveIds.OPENPROD, 3, EgtMsg(63000), EgtMsg(63001), 50)        'Project opening        'Loading project geometries
         If Map.refSceneHostVM.MainController.OpenProject(sFilePath, False) Then
            m_CurrProd = TempCurrProd
            Map.refMainWindowVM.UpdateTitle()
            ' inizializzo visibilita' bottone done per i Part
            Map.refLeftPanelVM.NotifyPropertyChanged(NameOf(Map.refLeftPanelVM.DonePart_Visibility))
            'If Map.refMachGroupPanelVM.InitMachGroupList() Then
            '   m_CurrProd = TempCurrProd
            '   Map.refMainWindowVM.SetTitle(CurrProd.nProdId.ToString("0000") & " - EgtBEAMWALL")
            'Else
            'MessageBox.Show("Impossibile aprire gruppi di lavorazione del file!!")
            'Map.refSceneHostVM.MainController.NewProject()
            'Map.refMainWindowVM.SetTitle("New - EgtBEAMWALL")
            'End If
         Else
            MessageBox.Show("Impossibile aprire il file!!")
            Map.refSceneHostVM.MainController.NewProject()
            Map.refMainWindowVM.SetTitle("New - EgtBEAMWALL")
            m_bLoadingProd = False
            NotifyPropertyChanged(NameOf(MruFileNames))
            LoadingWndHelper.CloseLoadingWnd(ActiveIds.OPENPROD)
            Return
         End If
      Else
         MessageBox.Show("File non trovato!!")
         Map.refSceneHostVM.MainController.NewProject()
         Map.refMainWindowVM.SetTitle("New - EgtBEAMWALL")
         m_bLoadingProd = False
         NotifyPropertyChanged(NameOf(MruFileNames))
         LoadingWndHelper.CloseLoadingWnd(ActiveIds.OPENPROD)
         Return
      End If
      LoadingWndHelper.UpdateLoadingWnd(ActiveIds.OPENPROD, 3, EgtMsg(63004), 70, 100)          ' Loading production data
      Map.refProjectVM.SupervisorMachGroupPanelVM = New SupervisorMachGroupPanelVM(MachGroupPanelM.CreateNewMachGroupPanel())
      ' apro sessione di comunicazione e fisso indice a 0
      DbControllers.m_StatusMapController.StartProd(Map.refSupervisorManagerVM.CurrProd.nProdId, m_SupervisorId)
      Map.refSupervisorManagerVM.CurrProd.SetModificationIndex(0)
      ' recupero elementi modificati
      Dim MachGroupList As List(Of StatusMapModel) = DbControllers.m_StatusMapController.GetFrom(m_SupervisorId, 0)
      ' carico dictionary di tutti i Machgroup
      For Each MachGroup In MachGroupList
         If Not Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupFullList.ContainsKey(MachGroup.ItemId) Then
            Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupFullList.Add(MachGroup.ItemId, {0, 0})
         End If
      Next
      ' carico solo elementi passati al supervisore
      Dim TempList As List(Of DataLayer.DatabaseModels.MachGroupModel) = DbControllers.m_MachGroupController.GetByProdSupervisor(Map.refSupervisorManagerVM.CurrProd.nProdId, m_SupervisorId)
      For Each DBMachGroup In TempList
         Dim MachGroup As MyMachGroupVM = Map.refProjectVM.ProdMachGroupPanelVM.MachGroupVMList.FirstOrDefault(Function(x) x.Id = DBMachGroup.MachGroupId)
         ' leggo dati da Db
         MachGroup.dtStartTime = DBMachGroup.DtStart
         MachGroup.dtEndTime = DBMachGroup.DtEnd
         MachGroup.MyMachGroupM.SetProductionState(DBMachGroup.State)
         MachGroup.SetProductionIndex(DBMachGroup.ProdIndex)
         For Each Part In MachGroup.PartVMList
            Dim DBPart As PartModel = DbControllers.m_PartController.FindByPartId(Map.refSupervisorManagerVM.CurrProd.nProdId, Part.nPartId)
            If Not IsNothing(DBPart) Then
               Part.dtStartTime = DBPart.DtStart
               Part.dtEndTime = DBPart.DtEnd
               Part.nProduction_State = DBPart.State
            Else
               EgtOutLog("Error: part found in project not found on Db!!!")
            End If
         Next
         Map.refProjectVM.SupervisorMachGroupPanelVM.AddMachGroupToSupervisor(MachGroup)
      Next
      ' seleziono primo gruppo
      If Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupVMList.Count > 0 Then
         Map.refProjectVM.SupervisorMachGroupPanelVM.SelFirstMachGroup()
      Else
         ManageBTLParts.HideAll()
      End If
      Map.refProjectVM.SupervisorMachGroupPanelVM.NotifyPropertyChanged(NameOf(Map.refProjectVM.SupervisorMachGroupPanelVM.MachGroupVMList))
      m_bLoadingProd = False

      MyComparer.RefreshColumns()
      Map.refSupervisorMachGroupPanelVM.SetMachGroupVMListView()
      Map.refSupervisorMachGroupPanelVM.RefreshMachGroupVMSort()

      NotifyPropertyChanged(NameOf(MruFileNames))
      LoadingWndHelper.CloseLoadingWnd(ActiveIds.OPENPROD)
   End Sub

#End Region ' OpenCommand

#Region "OpenMruFileCommand"

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

   ''' <summary>
   ''' Execute the Open.  This method is invoked by the OpenCommand.
   ''' </summary>
   Public Sub OpenMruFile(ByVal param As Object)
      '' verifico se progetto modificato, e chiedo se salvare
      'If Not ProdFileVM.VerifyProjectModification(CurrProd) Then Return
      ' ricavo l'Id e il progetto associato per l'apertura di quest'ultimo
      Dim PdId As Integer = 0
      Dim arrStrPdId As String() = DirectCast(param, String).Split("|")
      Integer.TryParse(arrStrPdId(0), PdId)
      Dim PdFileM = DbControllers.m_ProdController.FindCoreByProdId(PdId)
      Dim PdFileVM = New ProdFileVM(PdFileM)
      OpenProject(PdFileVM)
   End Sub

#End Region ' OpenMruFileCommand

#Region "GoToProd"

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

   ''' <summary>
   ''' Execute the Open.  This method is invoked by the OpenCommand.
   ''' </summary>
   Friend Sub GoToProd()
      If IsNothing(m_CurrProd) Then Return
      ' apro ottimizzatore
      Dim sOptimizerName As String = "EgtBEAMWALL.ViewerOptimizerR32"
      ' recupero processo del supervisore
      Dim localProc As Process() = Process.GetProcessesByName(sOptimizerName)
      If localProc.Length > 0 Then
         For Each p As Process In localProc
            ' porto in primo piano il Supervisor
            BringWindowToFront(p.MainWindowHandle)
            Exit For
         Next
      Else
         Dim sOptimizerPath As String = Path.GetDirectoryName(System.AppDomain.CurrentDomain.BaseDirectory) & "\" & sOptimizerName & ".exe"
         Try
            Process.Start(sOptimizerPath, "1 " & CurrProd.nProdId)
         Catch ex As Exception
            EgtOutLog("Error: impossible starting optimizer from path " & sOptimizerPath)
         End Try
      End If
      ' mando richiesta di apertura progetto in ottimizzatore
      DbControllers.m_StatusMapController.UpdateAction(DbControllers.m_SupervisorId, Map.refSupervisorManagerVM.CurrProd.nProdId, Map.refSupervisorManagerVM.CurrProd.nProdId, StatusMapItemType.Comm, StatusMapOpType.ChangeProdInProdRequest, "")
   End Sub

#End Region ' GoToProd

#End Region    ' Commands

End Class
