Imports System.IO
Imports System.Threading
Imports EgtBEAMWALL.Core
Imports EgtWPFLib5

Public Class MainWindowVM
   Inherits VMBase

   Private m_ViewerOptimizerCommThread As Thread

   ' Riferimento al Model della MainWindow
   Private m_MainWindowM As MainWindowM
   Friend ReadOnly Property MainWindowM As MainWindowM
      Get
         Return m_MainWindowM
      End Get
   End Property

   ' Titolo
   Private m_Title As String
   Public ReadOnly Property Title As String
      Get
         Return m_Title
      End Get
   End Property

   ' proprietà che seleziona la giusta pagina del TabControl
   Public Property nSelTabPage As Integer
      Get
         If IsNothing(Map.refMainMenuVM.SelPage) OrElse Map.refMainMenuVM.SelPage = -1 OrElse Map.refMainMenuVM.SelPage = Pages.SUPERVISOR Then
            Return 0    ' Supervisor
         ElseIf Map.refMainMenuVM.SelPage = Pages.INPUTS Then
            Return 1    ' Ingressi
         ElseIf Map.refMainMenuVM.SelPage = Pages.OUTPUTS Then
            Return 2    ' Uscite
         Else
            Return 3    ' Configurazione
         End If
      End Get
      Set(value As Integer)
      End Set
   End Property

   ' Definizione comandi
   Private m_cmdAboutBox As ICommand
   Private m_cmdCloseApplication As ICommand

#Region "CONSTRUCTOR"

   Sub New()
      ' Avvio l'inizializzazione della mappa passandogli il riferimento al MainWindowVM
      Map.BeginInit(Me)
      ' Creo Model della MainWindow
      m_MainWindowM = New MainWindowM
   End Sub

#End Region    ' CONSTRUCTOR

#Region "METHODS"

   Friend Sub SetTitle(sTitle As String)
      m_Title = sTitle
      NotifyPropertyChanged(NameOf(Title))
   End Sub
   Public Sub UpdateTitle()
      m_Title = ""
      If Not IsNothing(Map.refSupervisorManagerVM.CurrProd) Then
         m_Title = Map.refSupervisorManagerVM.CurrProd.nProdId.ToString("0000") & " - EgtBEAMWALL"
      End If
      NotifyPropertyChanged(NameOf(Title))
   End Sub

   Friend Sub ContentRendered()
      '' chiamata a caso su Db per inizializzarlo
      DbControllers.m_ProdController.FindByProdDbId(0)
      '   Verifico che l'inizializzazione di tutte le parti del programma sia andata a buon fine
      '   If Map.EndInit() Then
      '      m_bInitStatus = True
      '      altrimenti chiudo il programma
      '   Else
      '      m_bInitStatus = False
      '   End If
      '   Aggiorno visualizzazione unità di misura
      '   Map.refStatusBarVM.SetMeasureUnit(If(EgtUiUnitsAreMM(), MeasureUnitOpt.MM, MeasureUnitOpt.INCH))
      '   Se istanza oltre la prima, chiedo cosa aprire
      '   If Not m_MainWindowM.bFirstInstance Then
      '      Map.refProjectManagerVM.Open()
      '      ' altrimenti verifico se richiesto ultimo progetto
      '   ElseIf GetMainPrivateProfileInt(S_GENERAL, K_AUTOLOADLASTPROJ, 0) = 1 Then
      '      Dim sLastProjectPath As String = String.Empty
      '      GetMainPrivateProfileString(S_GENERAL, K_LASTPROJ, String.Empty, sLastProjectPath)
      '      If Not String.IsNullOrWhiteSpace(sLastProjectPath) AndAlso File.Exists(sLastProjectPath) Then
      '         Map.refProjectManagerVM.OpenProject(sLastProjectPath)
      '      Else
      '         Map.refProjectManagerVM.NewCmd()
      '      End If
      '      ' altrimenti nuovo progetto
      '   Else
      '      Map.refProjectManagerVM.NewCmd()
      '   End If
      '   apro in modalita' VIEW
      '   Map.refMainMenuVM.SelPage = Pages.VIEW

      ' imposto MainWindow per finestra di Loading
      LoadingWndHelper.SetMainWindow(Application.Current.MainWindow)


      ' leggo riga di comando
      Dim nCommandType As Integer = 0
      Dim nPage As Pages = Pages.VIEW
      Dim nProdId As Integer = 0
      If ProcessCommandLine(nCommandType, nProdId) AndAlso nCommandType = 1 Then
         Map.refSupervisorManagerVM.SetCurrProd(nProdId)
      Else
         ' setto il primo file dalla lista degli MRU come progetto corrente da aprire
         Dim sLastProdPath As String = String.Empty
         GetMainPrivateProfileString(S_MRUSUPERVISORPRODFILES, K_FILE & "1", String.Empty, sLastProdPath)
         If Not String.IsNullOrWhiteSpace(sLastProdPath) AndAlso File.Exists(sLastProdPath) Then
            ' ricavo l'Id e il prod associato per l'apertura di quest'ultimo
            Dim PdId As Integer = 0
            Dim sPdId As String = Path.GetFileNameWithoutExtension(sLastProdPath)
            Integer.TryParse(sPdId, PdId)
            Map.refSupervisorManagerVM.SetCurrProd(PdId)
         End If
      End If
      ' apro prod
      If Not IsNothing(Map.refSupervisorManagerVM.CurrProd) Then Map.refSupervisorManagerVM.OpenProject(Map.refSupervisorManagerVM.CurrProd)
      ' apro in modalita' SUPERVISOR
      Map.refMainMenuVM.SelPage = Pages.SUPERVISOR

      Map.refLeftPanelVM.NotifyPropertyChanged(NameOf(Map.refLeftPanelVM.FeatureList_Visibility))

      ' inizializzo thread di aggiornamento e comunicazione con DB
      ' creo thread di comunicazione con ViewOptim
      m_ViewerOptimizerCommThread = New Thread(Sub()
                                                  ViewerOptimizerCommThread.ViewerOptimizerCommThreadFunction()
                                               End Sub)
      m_ViewerOptimizerCommThread.SetApartmentState(ApartmentState.STA)
      ' avvio thread di gestione comunicazione con ViewOptim
      m_ViewerOptimizerCommThread.Start()
      ' se controllo axium, chiudo eventuale server di comunicazione rimasto aperto
      If CurrentMachine.NCType = NCTypes.NUM_AXIUM_APSERVER Then
         Dim ServerProcList As Process() = Process.GetProcessesByName("APServer")
         Dim LogProcList As Process() = Process.GetProcessesByName("APLog")
         For Each ServerProc In ServerProcList
            ServerProc.Kill()
         Next
         For Each LogProc In LogProcList
            LogProc.Kill()
         Next
      End If
   End Sub

   Friend Function ProcessCommandLine(ByRef nCommandType As Integer, ByRef nProdId As Integer) As Boolean
      ' Se non ci sono veri parametri su linea di comando, esco (il primo è sempre il nome del programma)
      If Environment.GetCommandLineArgs.Count() <= 1 Then Return False
      ' Recupero primo parametro che dovrebbe essere il tipo di modalita' riga di comando
      Dim sFile As String = Environment.GetCommandLineArgs(1)
      If String.IsNullOrWhiteSpace(sFile) OrElse Not Integer.TryParse(sFile, nCommandType) OrElse nCommandType <= 0 Then Return False
      Select Case nCommandType
         Case 1         ' apri progetto in supervisore
            ' recupero secondo parametro
            Dim sProdId As String = Environment.GetCommandLineArgs(2)
            If Not Integer.TryParse(sProdId, nProdId) OrElse nProdId <= 0 Then Return False
            Return True
      End Select
      Return False
   End Function

   Friend Sub KeyDown(PressedKey As Key)
      ' Con ESC esco dall'azione corrente
      If PressedKey = Key.Escape Then
         ' se in ripartenza
         If Map.refLeftPanelVM.bRestart Then
            ' sblocco interfaccia
            Map.refLeftPanelVM.bRestart = False
         End If
         '' se misura attiva, la disattivo
         'If Map.refInstrumentPanelVM.GetDistIsChecked Then
         '   Map.refInstrumentPanelVM.SetGetDistance_IsChecked(False)
         'End If
         ' pulisco output
         Map.refMyStatusBarVM.ClearOutputMessage()
      End If
   End Sub

#End Region    ' METHODS

#Region "COMMANDS"

#Region "AboutBoxCommand"

   ' Returns a command that manage the MainWindow_Unloaded command
   Public ReadOnly Property AboutBox_Command As ICommand
      Get
         If m_cmdAboutBox Is Nothing Then
            m_cmdAboutBox = New Command(AddressOf AboutBox)
         End If
         Return m_cmdAboutBox
      End Get
   End Property

   ' Manage the MainWindow_Unloaded event. This method is invoked by the cmdMainWindow_Unloaded.
   Public Sub AboutBox(ByVal param As Object)
      Dim AboutBoxWindow As New AboutBoxV
      AboutBoxWindow.Owner = Application.Current.MainWindow
      AboutBoxWindow.ShowDialog()
   End Sub

#End Region ' AboutBoxCommand

#Region "CloseApplication"

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

   ''' <summary>
   ''' Execute the Exec.  This method is invoked by the ExecCommand.
   ''' </summary>
   Public Sub CloseApplication()
      ' se macchina sta funzionando
      If Not IsNothing(Map.refMachManaging) AndAlso Map.refMachManaging.bConnected AndAlso
         (Map.refLeftPanelVM.SelOPState.Id <> OPStates.End AndAlso Map.refLeftPanelVM.SelOPState.Id <> OPStates.Unspecified) Then
         MessageBox.Show("Impossible closing software while machine is working. If you want to close, first press reset and stop the machine!", "Error", MessageBoxButton.OK, MessageBoxImage.Error)
         Return
      End If
      ' disconnetto comunicazione con macchina
      MachManaging.AddToCommandList(ThreadCommand.CreateCommand(CommandTypes.DISCONNECT))
      ' termino thread di comunicazione con Db ed altri programmi
      ViewerOptimizerCommThread.StopThread()
      ' Verifico modifica parametri in Configurazione e chiedo il salvataggio
      If Map.refMainMenuVM.SelPage = Pages.CONFIG Then Map.refConfigurationPageVM.VerifyConfigPageModification()
      ' Termino il Model
      MainWindowM.Close()
      ' Chiudo la finestra principale del programma
      Application.Current.MainWindow.Close()
   End Sub

#End Region    ' CloseApplication

#End Region    ' COMMANDS

End Class
