using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using Tango.BL;
using System.Data.Entity;
using Tango.BL.Builders;
using Tango.BL.Entities;
using Tango.BL.Enumerations;
using Tango.ColorConversion;
using Tango.Core.Commands;
using Tango.Core.Components;
using Tango.Core.DI;
using Tango.Core.ExtensionMethods;
using Tango.PPC.Common;
using Tango.PPC.Common.Connection;
using Tango.PPC.Common.ExternalBridge;
using Tango.PPC.Common.Lubrication;
using Tango.PPC.Common.Messages;
using Tango.PPC.Common.OS;
using Tango.PPC.Common.UWF;
using Tango.Settings;
using Tango.SharedUI.Components;
using Tango.WiFi;
using static Tango.Core.Components.CmdCommand;
namespace Tango.PPC.MachineSettings.ViewModels
{
///
/// Represents the main view VM and entry point for .
///
///
public class MainViewVM : PPCViewModel
{
private TimeZoneInfo _previousTimeZone;
private bool _previousEnableUWF;
#region Classes
public class RmlLubricationLevelSettings : RmlLubricationLevel
{
public String Name { get; set; }
public RmlLubricationLevelSettings()
{
}
public RmlLubricationLevelSettings(RmlLubricationLevel rmlLevel, String name)
{
RmlGuid = rmlLevel.RmlGuid;
LubricationLevel = rmlLevel.LubricationLevel;
Name = name;
}
public RmlLubricationLevel ToRmlLubricationLevel()
{
return new RmlLubricationLevel()
{
RmlGuid = RmlGuid,
LubricationLevel = LubricationLevel,
};
}
}
#endregion
#region Properties
[TangoInject]
private IOperationSystemManager OperationSystemManager { get; set; }
[TangoInject]
private IUnifiedWriteFilterManager UnifiedWriteFilterManager { get; set; }
private Machine _machine;
public Machine Machine
{
get { return _machine; }
set { _machine = value; RaisePropertyChangedAuto(); }
}
private SelectedObjectCollection _selectedJobTypes;
public SelectedObjectCollection SelectedJobTypes
{
get { return _selectedJobTypes; }
set { _selectedJobTypes = value; RaisePropertyChangedAuto(); }
}
private SelectedObjectCollection _selectedColorSpaces;
public SelectedObjectCollection SelectedColorSpaces
{
get { return _selectedColorSpaces; }
set { _selectedColorSpaces = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection _tabsColorSpaces;
public ObservableCollection TabsColorSpaces
{
get { return _tabsColorSpaces; }
set { _tabsColorSpaces = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection _rmls;
public ObservableCollection Rmls
{
get { return _rmls; }
set { _rmls = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection _spoolTypes;
public ObservableCollection SpoolTypes
{
get { return _spoolTypes; }
set { _spoolTypes = value; RaisePropertyChangedAuto(); }
}
private bool _enableHotSpot;
public bool EnableHotSpot
{
get { return _enableHotSpot; }
set { _enableHotSpot = value; RaisePropertyChangedAuto(); OnEnableHotSpotChanged(); }
}
private String _hotSpotPassword;
public String HotSpotPassword
{
get { return _hotSpotPassword; }
set { _hotSpotPassword = value; RaisePropertyChangedAuto(); }
}
private bool _enableExternalBridge;
public bool EnableExternalBridge
{
get { return _enableExternalBridge; }
set { _enableExternalBridge = value; RaisePropertyChangedAuto(); OnEnableExternalBridgeChanged(); }
}
private String _externalBridgePassword;
public String ExternalBridgePassword
{
get { return _externalBridgePassword; }
set { _externalBridgePassword = value; RaisePropertyChangedAuto(); }
}
private bool _enableRemoteAssistance;
public bool EnableRemoteAssistance
{
get { return _enableRemoteAssistance; }
set { _enableRemoteAssistance = value; RaisePropertyChangedAuto(); OnEnableRemoteAssistanceChanged(); }
}
private bool _enableLockScreen;
public bool EnableLockScreen
{
get { return _enableLockScreen; }
set { _enableLockScreen = value; RaisePropertyChangedAuto(); }
}
private int _lockScreenTimeoutMinutes;
public int LockScreenTimeoutMinutes
{
get { return _lockScreenTimeoutMinutes; }
set { _lockScreenTimeoutMinutes = value; RaisePropertyChangedAuto(); }
}
private String _lockScreenPassword;
public String LockScreenPassword
{
get { return _lockScreenPassword; }
set { _lockScreenPassword = value; RaisePropertyChangedAuto(); }
}
private Rml _defaultRML;
public Rml DefaultRML
{
get { return _defaultRML; }
set { _defaultRML = value; RaisePropertyChangedAuto(); }
}
private SpoolType _selectedSpoolType;
public SpoolType SelectedSpoolType
{
get { return _selectedSpoolType; }
set { _selectedSpoolType = value; RaisePropertyChangedAuto(); }
}
private ColorSpaces _defaultTabColorSpace;
public ColorSpaces DefaultTabColorSpace
{
get { return _defaultTabColorSpace; }
set { _defaultTabColorSpace = value; RaisePropertyChangedAuto(); }
}
private bool _synchronizeJobs;
public bool SynchronizeJobs
{
get { return _synchronizeJobs; }
set { _synchronizeJobs = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
}
private bool _synchronizeDiagnostics;
public bool SynchronizeDiagnostics
{
get { return _synchronizeDiagnostics; }
set { _synchronizeDiagnostics = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
}
private bool _autoCheckForUpdates;
public bool AutoCheckForUpdates
{
get { return _autoCheckForUpdates; }
set { _autoCheckForUpdates = value; RaisePropertyChangedAuto(); }
}
private List _timeZones;
///
/// Gets or sets the available time zones.
///
public List TimeZones
{
get { return _timeZones; }
set { _timeZones = value; RaisePropertyChangedAuto(); }
}
private TimeZoneInfo _selectedTimeZone;
///
/// Gets or sets the selected time zone.
///
public TimeZoneInfo SelectedTimeZone
{
get { return _selectedTimeZone; }
set { _selectedTimeZone = value; RaisePropertyChangedAuto(); }
}
private bool _enableUWF;
public bool EnableUWF
{
get { return _enableUWF; }
set { _enableUWF = value; RaisePropertyChangedAuto(); }
}
private List _lubricationLevels;
public List LubricationLevels
{
get { return _lubricationLevels; }
set { _lubricationLevels = value; RaisePropertyChangedAuto(); }
}
private RmlLubricationLevelSettings _selectedLubricationLevel;
public RmlLubricationLevelSettings SelectedLubricationLevel
{
get { return _selectedLubricationLevel; }
set { _selectedLubricationLevel = value; RaisePropertyChangedAuto(); }
}
private bool _useLightInks;
public bool UseLightInks
{
get { return _useLightInks; }
set { _useLightInks = value; RaisePropertyChangedAuto(); }
}
private bool _enableProxy;
public bool EnableProxy
{
get { return _enableProxy; }
set { _enableProxy = value; RaisePropertyChangedAuto(); }
}
private int _manualFineTuningLength;
public int FineTuningLength
{
get { return _manualFineTuningLength; }
set { _manualFineTuningLength = value; RaisePropertyChangedAuto(); }
}
#endregion
#region Commands
///
/// Gets or sets the save command.
///
public RelayCommand SaveCommand { get; set; }
///
/// Gets or sets the discard command.
///
public RelayCommand DiscardCommand { get; set; }
///
/// Gets or sets the synchronize command.
///
public RelayCommand SynchronizeCommand { get; set; }
#endregion
public MainViewVM()
{
LubricationLevels = new List();
SaveCommand = new RelayCommand(Save);
DiscardCommand = new RelayCommand(Discard);
SynchronizeCommand = new RelayCommand(Synchronize, () => !MachineDataSynchronizer.IsSynchronizing && IsFree);
}
private void Discard()
{
NavigationManager.NavigateBack();
}
private async void Save()
{
if (Validate())
{
Settings.SupportedJobTypes = SelectedJobTypes.SynchedSource.ToList();
Settings.SupportedColorSpaces = SelectedColorSpaces.SynchedSource.ToList();
Machine.MapPropertiesTo(MachineProvider.Machine, MappingFlags.NoReferenceTypes);
Settings.EnableHotSpot = EnableHotSpot;
Settings.HotSpotPassword = HotSpotPassword;
Settings.EnableExternalBridge = EnableExternalBridge;
Settings.ExternalBridgePassword = ExternalBridgePassword;
Settings.EnableLockScreen = EnableLockScreen;
Settings.LockScreenTimeout = TimeSpan.FromMinutes(LockScreenTimeoutMinutes);
Settings.LockScreenPassword = LockScreenPassword;
Settings.DefaultRmlGuid = DefaultRML?.Guid;
String previousSpoolType = Settings.SpoolTypeGuid;
Settings.SpoolTypeGuid = SelectedSpoolType?.Guid;
Settings.SynchronizeJobs = SynchronizeJobs;
Settings.SynchronizeDiagnostics = SynchronizeDiagnostics;
Settings.AutoCheckForUpdates = AutoCheckForUpdates;
Settings.LubricationLevels = LubricationLevels.Where(x => x.LubricationLevel != LubricationLevel.Standard).Select(x => x.ToRmlLubricationLevel()).ToList();
Settings.DefaultTabColorSpace = DefaultTabColorSpace;
Settings.FineTuningTrialLengthMeters = FineTuningLength;
MachineDataSynchronizer.IsEnabled = SynchronizeJobs || SynchronizeDiagnostics;
var colorConversionSettings = SettingsManager.Default.GetOrCreate();
colorConversionSettings.UseLightInks = UseLightInks;
Settings.Save();
await MachineProvider.SaveMachine();
bool isRestarting = false;
if (SelectedSpoolType != null && previousSpoolType != Settings.SpoolTypeGuid)
{
await MachineProvider.MachineOperator.SetSpoolType((PMR.Printing.JobSpoolType)SelectedSpoolType.Code);
}
if (_previousTimeZone.ToStringSafe() != SelectedTimeZone.ToStringSafe())
{
if (await NotificationProvider.ShowQuestion("Changing the time zone requires the application to restart. Do you wish to restart the application?"))
{
try
{
LogManager.Log($"Setting new time zone to '{SelectedTimeZone.ToString()}'.");
NotificationProvider.SetGlobalBusyMessage("Setting new time zone...");
await OperationSystemManager.ChangeTimeZone(SelectedTimeZone);
NotificationProvider.ReleaseGlobalBusyMessage();
isRestarting = true;
ApplicationManager.Restart();
}
catch (Exception ex)
{
LogManager.Log(ex, "Error changing the time zone.");
NotificationProvider.ReleaseGlobalBusyMessage();
await NotificationProvider.ShowError($"Error setting timezone.\n{ex.FlattenMessage()}");
}
}
}
if (EnableProxy != Settings.EnableProxifier)
{
CmdCommand cmd = null;
CmdCommandResult result = null;
if (!EnableProxy)
{
try
{
cmd = new CmdCommand("taskkill", "/F /IM proxifier.exe");
result = await cmd.Run();
Settings.EnableProxifier = false;
Settings.Save();
}
catch (Exception ex)
{
LogManager.Log(ex, $"Unable to disable the proxy.\n{ex.Message}");
await NotificationProvider.ShowError($"Unable to disable the proxy.\n{ex.Message}");
}
}
else
{
try
{
Process.Start(@"C:\Program Files (x86)\Proxifier\Proxifier.exe");
Settings.EnableProxifier = true;
Settings.Save();
}
catch (Exception ex)
{
LogManager.Log(ex, $"Unable to start the proxy service.\n{ex.Message}");
await NotificationProvider.ShowError($"Unable to start the proxy service.\n{ex.Message}");
}
}
}
if (_previousEnableUWF != EnableUWF)
{
await NotificationProvider.ShowWarning("Changes to disk protection (UWF) will take effect only after a full system restart.");
try
{
LogManager.Log($"Changing UWF mode to '{EnableUWF}'.");
if (EnableUWF)
{
NotificationProvider.SetGlobalBusyMessage("Enabling disk protection (UWF)...");
await UnifiedWriteFilterManager.Enable();
}
else
{
NotificationProvider.SetGlobalBusyMessage("Disabling disk protection (UWF)...");
await UnifiedWriteFilterManager.Disable();
}
NotificationProvider.ReleaseGlobalBusyMessage();
}
catch (Exception ex)
{
NotificationProvider.ReleaseGlobalBusyMessage();
LogManager.Log(ex, "Error setting UWF mode.");
await NotificationProvider.ShowError($"Could not change the disk protection mode\n{ex.FlattenMessage()}");
}
}
if (!isRestarting)
{
await NavigationManager.NavigateBack();
}
}
}
protected override void OnValidating()
{
base.OnValidating();
}
///
/// Called when the application has been started
///
public override void OnApplicationStarted()
{
try
{
TimeZones = OperationSystemManager.GetAvailableTimeZones().ToList();
}
catch (Exception ex)
{
LogManager.Log(ex, "Error retrieving available time zones.");
}
}
public async override void OnApplicationReady()
{
base.OnApplicationReady();
MachineDataSynchronizer.SynchronizationStarted += (_, __) => InvalidateRelayCommands();
MachineDataSynchronizer.SynchronizationEnded += (_, __) => InvalidateRelayCommands();
if (!Settings.EnableProxifier)
{
CmdCommand cmd = null;
CmdCommandResult result = null;
try
{
cmd = new CmdCommand("taskkill", "/F /IM proxifier.exe");
result = await cmd.Run();
}
catch (Exception ex)
{
LogManager.Log(ex, $"Unable to disable the proxy.\n{ex.Message}");
}
}
using (ObservablesContext db = ObservablesContext.CreateDefault())
{
Rmls = (await new RmlsCollectionBuilder(db).SetAll().ForHeadType(MachineProvider.Machine.MachineHeadType).ForSite(MachineProvider.Machine.SiteGuid).BuildAsync()).OrderBy(x => x.FinalName).ToObservableCollection();
try
{
SpoolTypes = (await db.SitesSpoolTypes.Where(x => x.SiteGuid == MachineProvider.Machine.SiteGuid).Include(x => x.SpoolType).Select(x => x.SpoolType).ToListAsync()).OrderBy(x => x.LastUpdated).ToObservableCollection();
if (SpoolTypes.Count == 0)
{
SpoolTypes = new ObservableCollection();
var standardSpool = await db.SpoolTypes.FirstOrDefaultAsync(x => x.Code == (int)BL.Enumerations.SpoolTypes.StandardSpool);
if (standardSpool != null)
{
SpoolTypes.Add(standardSpool);
}
}
}
catch (Exception ex)
{
LogManager.Log(ex, "Error getting machine site spool types.");
}
}
}
public async override void OnNavigatedTo()
{
base.OnNavigatedTo();
Machine = MachineProvider.Machine.ShallowClone();
RaisePropertyChanged(nameof(Machine));
_enableHotSpot = HotSpotProvider.IsEnabled;
RaisePropertyChanged(nameof(EnableHotSpot));
HotSpotPassword = Settings.HotSpotPassword;
_enableExternalBridge = ExternalBridgeService.Enabled;
RaisePropertyChanged(nameof(EnableExternalBridge));
ExternalBridgePassword = Settings.ExternalBridgePassword;
_enableRemoteAssistance = RemoteAssistanceProvider.IsEnabled;
RaisePropertyChanged(nameof(EnableRemoteAssistance));
EnableLockScreen = Settings.EnableLockScreen;
LockScreenTimeoutMinutes = (int)Settings.LockScreenTimeout.TotalMinutes;
LockScreenPassword = Settings.LockScreenPassword;
FineTuningLength = Settings.FineTuningTrialLengthMeters;
SelectedJobTypes = new SelectedObjectCollection(Enum.GetValues(typeof(JobTypes)).Cast().ToObservableCollection(), Settings.SupportedJobTypes.ToObservableCollection());
SelectedColorSpaces = new SelectedObjectCollection(Enum.GetValues(typeof(ColorSpaces)).Cast().Where(x => x.IsUserSpace()).ToObservableCollection(), Settings.SupportedColorSpaces.ToObservableCollection());
TabsColorSpaces = new ObservableCollection(Enum.GetValues(typeof(ColorSpaces)).Cast().Where(x => x!= ColorSpaces.Volume /*&& x!= ColorSpaces.HSB*/).ToObservableCollection());
DefaultTabColorSpace = Settings.DefaultTabColorSpace == null? ColorSpaces.CMYK : TabsColorSpaces.SingleOrDefault(x => x == Settings.DefaultTabColorSpace);
DefaultRML = Rmls.SingleOrDefault(x => x.Guid == Settings.DefaultRmlGuid);
SelectedSpoolType = SpoolTypes.SingleOrDefault(x => x.Guid == Settings.SpoolTypeGuid);
if (SelectedSpoolType == null)
{
SelectedSpoolType = SpoolTypes.FirstOrDefault(x => x.Code == (int)BL.Enumerations.SpoolTypes.StandardSpool);
}
SynchronizeJobs = Settings.SynchronizeJobs;
SynchronizeDiagnostics = Settings.SynchronizeDiagnostics;
AutoCheckForUpdates = Settings.AutoCheckForUpdates;
var colorConversionSettings = SettingsManager.Default.GetOrCreate();
UseLightInks = colorConversionSettings.UseLightInks;
SelectedTimeZone = TimeZones.SingleOrDefault(x => x.StandardName == TimeZone.CurrentTimeZone.StandardName);
_previousTimeZone = SelectedTimeZone;
try
{
EnableUWF = await UnifiedWriteFilterManager.IsEnabled();
_previousEnableUWF = EnableUWF;
}
catch (Exception ex)
{
LogManager.Log(ex, "Error getting UWF status.");
}
try
{
List levels = new List();
foreach (var rml in Rmls)
{
RmlLubricationLevel userLevel = Settings.LubricationLevels.FirstOrDefault(x => x.RmlGuid == rml.Guid);
RmlLubricationLevelSettings rmlLevel = new RmlLubricationLevelSettings();
rmlLevel.RmlGuid = rml.Guid;
rmlLevel.Name = rml.Name;
rmlLevel.LubricationLevel = userLevel != null ? userLevel.LubricationLevel : LubricationLevel.Standard;
levels.Add(rmlLevel);
}
LubricationLevels = levels;
if (SelectedLubricationLevel != null)
{
SelectedLubricationLevel = LubricationLevels.FirstOrDefault(x => x.RmlGuid == SelectedLubricationLevel.RmlGuid);
}
else
{
SelectedLubricationLevel = LubricationLevels.FirstOrDefault();
}
}
catch (Exception ex)
{
LogManager.Log(ex, "Error loading lubrication levels.");
}
EnableProxy = Settings.EnableProxifier;
}
private async void OnEnableRemoteAssistanceChanged()
{
if (EnableRemoteAssistance)
{
try
{
await RemoteAssistanceProvider.EnableRemoteAssistance();
}
catch
{
await NotificationProvider.ShowError("An error occurred while trying to activate the remote assistance service. Please check your device settings and try again.");
_enableRemoteAssistance = false;
}
}
else
{
try
{
await RemoteAssistanceProvider.DisableRemoteAssistance();
}
catch
{
await NotificationProvider.ShowError("An error occurred while trying to deactivate the remote assistance service. Please check your device settings and try again.");
_enableRemoteAssistance = true;
}
}
RaisePropertyChanged(nameof(EnableRemoteAssistance));
}
private async void OnEnableHotSpotChanged()
{
if (EnableHotSpot)
{
if (HotSpotPassword == null || HotSpotPassword.Length < 8 || HotSpotPassword.Length > 16)
{
await NotificationProvider.ShowError("Hot spot requires a password of 8 to 16 characters.");
_enableHotSpot = false;
RaisePropertyChanged(nameof(EnableHotSpot));
return;
}
try
{
await HotSpotProvider.EnableHotSpot(HotSpotPassword);
}
catch
{
await NotificationProvider.ShowError("An error occurred while trying to activate the hot spot network. Please check your device settings and try again.");
_enableHotSpot = false;
}
}
else
{
try
{
await HotSpotProvider.DisableHotSpot();
}
catch
{
await NotificationProvider.ShowError("An error occurred while trying to deactivate the hot spot network.");
_enableHotSpot = true;
}
}
RaisePropertyChanged(nameof(EnableHotSpot));
}
private void OnEnableExternalBridgeChanged()
{
ExternalBridgeService.Enabled = EnableExternalBridge;
}
private async void Synchronize()
{
try
{
IsFree = false;
NotificationProvider.SetGlobalBusyMessage("Synchronizing...");
await MachineDataSynchronizer.Synchronize();
NotificationProvider.ReleaseGlobalBusyMessage();
await NotificationProvider.ShowSuccess("Synchronization completed successfully.");
}
catch (Exception ex)
{
NotificationProvider.ReleaseGlobalBusyMessage();
await NotificationProvider.ShowError($"Error occurred while trying to synchronize.\n{ex.FlattenMessage()}");
}
finally
{
NotificationProvider.ReleaseGlobalBusyMessage();
IsFree = true;
}
}
}
}