using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
using Tango.Core.Commands;
using Tango.Core.Helpers;
using Tango.BL.Entities;
using Tango.MachineStudio.Common.Notifications;
using Tango.SharedUI;
using SimpleValidator.Extensions;
using Tango.MachineStudio.Common.StudioApplication;
using Tango.MachineStudio.Common;
using Tango.BL;
using Tango.AutoComplete.Editors;
using System.Data.Entity;
namespace Tango.MachineStudio.MachineDesigner.ViewModels
{
public class MainViewVM : StudioViewModel
{
private INotificationProvider _notification;
private ObservablesContext _db;
private Configuration _original_configuration;
#region Properties
private ObservablesStaticCollections _adapter;
///
/// Gets or sets the db static adapter.
///
public ObservablesStaticCollections Adapter
{
get { return _adapter; }
set { _adapter = value; RaisePropertyChangedAuto(); }
}
private bool _canWork;
///
/// Gets or sets a value indicating whether this instance can work.
///
public bool CanWork
{
get { return _canWork; }
set { _canWork = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
}
private Machine _machine;
///
/// Gets or sets the current editable machine.
///
public Machine Machine
{
get { return _machine; }
set { _machine = value; RaisePropertyChangedAuto(); }
}
private Machine _selectedMachine;
///
/// Gets or sets the selected machine from the drop down.
///
public Machine SelectedMachine
{
get { return _selectedMachine; }
set
{
if (_selectedMachine != value)
{
_selectedMachine = value; RaisePropertyChangedAuto(); OnSelectedMachineChanged();
}
}
}
private Configuration _configuration;
///
/// Gets or sets the editable machine configuration.
///
public Configuration Configuration
{
get { return _configuration; }
set { _configuration = value; RaisePropertyChangedAuto(); }
}
private IdsPack _selectedIds;
///
/// Gets or sets the selected ids pack.
///
public IdsPack SelectedIds
{
get { return _selectedIds; }
set { _selectedIds = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
}
private ObservableCollection _history;
///
/// Gets or sets the machine configuration history.
///
public ObservableCollection History
{
get { return _history; }
set { _history = value; RaisePropertyChangedAuto(); }
}
private Configuration _selectedHistoryConfiguration;
///
/// Gets or sets the machine selected configuration from history.
///
public Configuration SelectedHistoryConfiguration
{
get { return _selectedHistoryConfiguration; }
set { _selectedHistoryConfiguration = value; RaisePropertyChangedAuto(); OnHistoryConfigurationSelected(); }
}
private String _filter;
///
/// Gets or sets the configuration components filter.
///
public String Filter
{
get { return _filter; }
set { _filter = value; RaisePropertyChangedAuto(); OnFilterChanged(); }
}
///
/// Gets or sets the machines provider.
///
public ISuggestionProvider MachinesProvider { get; set; }
#endregion
#region Commands
///
/// Gets or sets the save command.
///
public RelayCommand SaveCommand { get; set; }
///
/// Gets or sets the add ids command.
///
public RelayCommand AddIdsCommand { get; set; }
///
/// Gets or sets the remove ids command.
///
public RelayCommand RemoveIdsCommand { get; set; }
///
/// Gets or sets the set version configuration command.
///
public RelayCommand SetVersionConfigurationCommand { get; set; }
///
/// Gets or sets the set as default command.
///
public RelayCommand SetAsDefaultCommand { get; set; }
///
/// Gets or sets the reset command.
///
public RelayCommand ResetCommand { get; set; }
#endregion
#region Constructors
public MainViewVM()
{
}
///
/// Initializes a new instance of the class.
///
public MainViewVM(INotificationProvider notification)
{
CanWork = true;
_notification = notification;
Configuration = new Configuration();
Configuration.Name = "Untitled";
Machine = new Machine();
Machine.Configuration = Configuration;
SaveCommand = new RelayCommand(Save, (x) => CanWork);
AddIdsCommand = new RelayCommand(AddIds, (x) => CanWork && Configuration.IdsPacks.Count < 8);
RemoveIdsCommand = new RelayCommand(RemoveIds, (x) => CanWork && SelectedIds != null);
SetVersionConfigurationCommand = new RelayCommand(SetVersionConfiguration, (x) => CanWork);
SetAsDefaultCommand = new RelayCommand(SetAsDefaultConfiguration, (x) => CanWork);
ResetCommand = new RelayCommand(Reset, () => CanWork);
MachinesProvider = new SuggestionProvider((filter) =>
{
return _db.Machines.Where(x => x.SerialNumber.StartsWith(filter)).ToList();
});
}
#endregion
#region Application Ready
public async override void OnApplicationReady()
{
await InitCollections();
}
#endregion
private Task InitCollections()
{
return Task.Factory.StartNew(() =>
{
CanWork = false;
_db = ObservablesContext.CreateDefault();
_db.Configuration.LazyLoadingEnabled = false;
Adapter = new ObservablesStaticCollections();
Adapter.ApplicationDisplayPanelVersions = _db.ApplicationDisplayPanelVersions.ToObservableCollection();
Adapter.ApplicationFirmwareVersions = _db.ApplicationFirmwareVersions.ToObservableCollection();
Adapter.ApplicationOsVersions = _db.ApplicationOsVersions.ToObservableCollection();
Adapter.EmbeddedFirmwareVersions = _db.EmbeddedFirmwareVersions.ToObservableCollection();
Adapter.DispenserTypes = _db.DispenserTypes.ToObservableCollection();
Adapter.LiquidTypes = _db.LiquidTypes.ToObservableCollection();
Adapter.MidTankTypes = _db.MidTankTypes.ToObservableCollection();
Adapter.CartridgeTypes = _db.CartridgeTypes.ToObservableCollection();
Adapter.IdsPackFormulas = _db.IdsPackFormulas.ToObservableCollection();
Adapter.HardwareVersions = _db.HardwareVersions.ToObservableCollection();
Adapter.MachineVersions = _db.MachineVersions.ToObservableCollection();
Adapter.Organizations = _db.Organizations.ToObservableCollection();
Adapter.InitCollectionSources();
CanWork = true;
});
}
private void Reset()
{
using (_notification.PushTaskItem("Resetting designer..."))
{
SelectedMachine = null;
Machine = new Machine();
Configuration = new Configuration();
History = new ObservableCollection();
SelectedHistoryConfiguration = null;
Filter = String.Empty;
InitCollections();
}
}
#region Virtual Methods
///
/// Called when the selected machine has changed.
///
protected virtual void OnSelectedMachineChanged()
{
if (SelectedMachine != null)
{
CanWork = false;
using (_notification.PushTaskItem("Loading machine configuration..."))
{
Task.Factory.StartNew(() =>
{
InitCollections().Wait();
Machine = _db.Machines.Where(x => x.Guid == SelectedMachine.Guid).Include(x => x.Organization).SingleOrDefault(x => x.Guid == SelectedMachine.Guid);
Configuration = _db.Adapter.GetConfiguration(x => x.Guid == Machine.ConfigurationGuid);
SetHistory();
_original_configuration = Configuration.Clone();
});
}
CanWork = true;
}
else
{
History = new ObservableCollection();
}
}
///
/// Called when the history configuration has been selected
///
protected virtual void OnHistoryConfigurationSelected()
{
if (SelectedHistoryConfiguration != null && CanWork)
{
using (_notification.PushTaskItem("Loading Configuration..."))
{
Task.Factory.StartNew(() =>
{
CanWork = false;
SelectedHistoryConfiguration = _db.Adapter.GetConfiguration(x => x.Guid == SelectedHistoryConfiguration.Guid);
Configuration = SelectedHistoryConfiguration;
Machine.Configuration = Configuration;
CanWork = true;
});
}
}
}
///
/// Called when the filter has changed
///
protected virtual void OnFilterChanged()
{
List collections = new List();
collections.Add(Adapter.ApplicationFirmwareVersionsViewSource);
collections.Add(Adapter.ApplicationDisplayPanelVersionsViewSource);
collections.Add(Adapter.ApplicationOsVersionsViewSource);
collections.Add(Adapter.EmbeddedFirmwareVersionsViewSource);
collections.Add(Adapter.DispenserTypesViewSource);
collections.Add(Adapter.CartridgeTypesViewSource);
collections.Add(Adapter.LiquidTypesViewSource);
collections.Add(Adapter.MidTankTypesViewSource);
collections.Add(Adapter.HardwareVersionsViewSource);
foreach (var collection in collections)
{
collection.Filter = (x) =>
{
foreach (var prop in x.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(y => y.PropertyType == typeof(String)))
{
String value = prop.GetValue(x).ToStringSafe();
if (value != null && Filter != null)
{
if (value.ToLower().Contains(Filter.ToLower()))
{
return true;
}
}
}
return false;
};
}
}
#endregion
#region Drag Drop Handlers
///
/// Drops the ids pack.
///
/// The ids pack1.
/// The ids pack2.
public void DropIdsPack(IdsPack idsPack1, IdsPack idsPack2)
{
Configuration.IdsPacks.Swap(idsPack1, idsPack2);
}
///
/// Drops the touch panel.
///
/// The application display panel version.
public void DropTouchPanel(ApplicationDisplayPanelVersion applicationDisplayPanelVersion)
{
Configuration.ApplicationDisplayPanelVersion = applicationDisplayPanelVersion;
Configuration.ApplicationDisplayPanelVersionGuid = applicationDisplayPanelVersion.Guid;
}
///
/// Drops the application firmware version.
///
/// The application firmware version.
public void DropApplicationFirmwareVersion(ApplicationFirmwareVersion applicationFirmwareVersion)
{
Configuration.ApplicationFirmwareVersion = applicationFirmwareVersion;
Configuration.ApplicationFirmwareVersionGuid = applicationFirmwareVersion.Guid;
}
///
/// Drops the hardware version.
///
/// The hardware version.
public void DropHardwareVersion(HardwareVersion hardwareVersion)
{
Configuration.HardwareVersion = hardwareVersion;
Configuration.HardwareVersionGuid = hardwareVersion.Guid;
}
///
/// Drops the embedded firmware.
///
/// The embedded firmware version.
public void DropEmbeddedFirmware(EmbeddedFirmwareVersion embeddedFirmwareVersion)
{
Configuration.EmbeddedFirmwareVersion = embeddedFirmwareVersion;
Configuration.EmbeddedFirmwareVersionGuid = embeddedFirmwareVersion.Guid;
}
///
/// Drops the application os version.
///
/// The application os version.
public void DropApplicationOsVersion(ApplicationOsVersion applicationOsVersion)
{
Configuration.ApplicationOsVersion = applicationOsVersion;
Configuration.ApplicationOsVersionGuid = applicationOsVersion.Guid;
}
///
/// Drops the type of the cartridge.
///
/// Type of the cartridge.
/// The ids pack.
public void DropCartridgeType(CartridgeType cartridgeType, IdsPack idsPack)
{
idsPack.CartridgeType = cartridgeType;
idsPack.CartridgeTypeGuid = cartridgeType.Guid;
}
///
/// Drops the dispenser.
///
/// The dispenser.
/// The ids pack.
public void DropDispenserType(DispenserType dispenserType, IdsPack idsPack)
{
idsPack.DispenserType = dispenserType;
idsPack.DispenserTypeGuid = dispenserType.Guid;
}
///
/// Drops the type of the mid tank.
///
/// Type of the mid tank.
/// The ids pack.
public void DropMidTankType(MidTankType midTankType, IdsPack idsPack)
{
idsPack.MidTankType = midTankType;
idsPack.MidTankTypeGuid = midTankType.Guid;
}
///
/// Drops the type of the liquid.
///
/// Type of the liquid.
/// The ids pack.
public void DropLiquidType(LiquidType liquidType, IdsPack idsPack)
{
idsPack.LiquidType = liquidType;
idsPack.LiquidTypeGuid = liquidType.Guid;
}
///
/// Drops the ids formula.
///
/// The ids pack formula.
/// The ids pack.
///
public void DropIdsFormula(IdsPackFormula idsPackFormula, IdsPack idsPack)
{
idsPack.IdsPackFormula = idsPackFormula;
idsPack.IdsPackFormulaGuid = idsPackFormula.Guid;
}
#endregion
#region Private Methods
///
/// Removes the selected IDS pack.
///
private void RemoveIds()
{
_db.IdsPacks.Remove(SelectedIds);
SelectedIds = null;
}
///
/// Adds a new IDS pack.
///
private void AddIds()
{
_db.IdsPacks.Add(new IdsPack() { Configuration = Configuration });
InvalidateRelayCommands();
}
///
/// Saves the current machine configuration.
///
private async void Save()
{
foreach (var ids in Configuration.IdsPacks)
{
ids.PackIndex = Configuration.IdsPacks.IndexOf(ids);
ids.Configuration = Configuration;
ids.ConfigurationGuid = Configuration.Guid;
}
//Validate
List errors = new List();
if (Machine.MachineVersion == null)
{
errors.Add("Machine version is required.");
}
if (Machine.Name.IsNullOrWhiteSpace())
{
errors.Add("Machine name is required.");
}
if (Machine.Organization == null)
{
errors.Add("Machine organization is required.");
}
if (Machine.SerialNumber.IsNullOrWhiteSpace())
{
errors.Add("Machine serial number is required.");
}
if (Configuration.Name.IsNullOrWhiteSpace())
{
errors.Add("Configuration name is required.");
}
if (Configuration.ApplicationDisplayPanelVersion == null)
{
errors.Add("Touch Panel is required.");
}
if (Configuration.ApplicationFirmwareVersion == null)
{
errors.Add("Application firmware is required.");
}
if (Configuration.ApplicationOsVersion == null)
{
errors.Add("Application operation system is required.");
}
if (Configuration.EmbeddedFirmwareVersion == null)
{
errors.Add("Embedded firmware is required.");
}
if (Configuration.HardwareVersion == null)
{
errors.Add("Hardware version is required.");
}
foreach (var pack in Configuration.IdsPacks)
{
if (pack.LiquidType != null || pack.CartridgeType != null || pack.DispenserType != null || pack.IdsPackFormula != null || pack.MidTankType != null)
{
if (pack.Name.IsNullOrWhiteSpace())
{
errors.Add(String.Format("Name is required on IDS pack number '{0}'.", Configuration.IdsPacks.IndexOf(pack) + 1));
continue;
}
if (pack.CartridgeType == null)
{
errors.Add(String.Format("Cartridge type is required on IDS pack '{0}'.", pack.Name));
}
if (pack.DispenserType == null)
{
errors.Add(String.Format("Dispenser type is required on IDS pack '{0}'.", pack.Name));
}
if (pack.LiquidType == null)
{
errors.Add(String.Format("Liquid type is required on IDS pack '{0}'.", pack.Name));
}
if (pack.MidTankType == null)
{
errors.Add(String.Format("Mid Tank type is required on IDS pack '{0}'.", pack.Name));
}
if (pack.IdsPackFormula == null)
{
errors.Add(String.Format("Formula type is required on IDS pack '{0}'.", pack.Name));
}
pack.IsEmpty = false;
}
else
{
pack.IsEmpty = true;
pack.Name = String.Empty;
}
}
if (errors.Count > 0)
{
String errorsString = "Please fix the following validation errors before trying to save." + Environment.NewLine + Environment.NewLine;
errorsString += String.Join(Environment.NewLine, errors);
_notification.ShowError(errorsString);
return;
}
//Validate
try
{
CanWork = false;
using (_notification.PushTaskItem("Saving Machine Configuration..."))
{
if (!_db.Machines.Any(x => x.SerialNumber.ToLower() == Machine.SerialNumber.ToLower()))
{
if (!_notification.ShowQuestion("The specified machine serial number does not exist. Do you wish to create a new machine?"))
{
CanWork = true;
return;
}
else
{
Machine.Configuration = Configuration;
Configuration.CreationDate = DateTime.UtcNow;
Machine.ProductionDate = DateTime.UtcNow;
_db.Machines.Add(Machine);
_db.MachinesConfigurations.Add(new MachinesConfiguration()
{
Configuration = Configuration,
Machine = Machine,
});
}
}
else
{
bool add_history = History.Count == 0 || _original_configuration.Name != Configuration.Name;
if (add_history)
{
_db.Configurations.Add(_original_configuration);
_db.MachinesConfigurations.Add(new MachinesConfiguration()
{
Configuration = _original_configuration,
Machine = Machine
});
}
}
await _db.SaveChangesAsync();
OnSelectedMachineChanged();
}
}
catch (Exception ex)
{
_notification.ShowError("An error occurred while trying to save the configuration" + Environment.NewLine + ex.Message);
}
finally
{
CanWork = true;
InvalidateRelayCommands();
}
}
///
/// Sets the specified machine history.
///
/// The machine.
private void SetHistory()
{
History = _db.MachinesConfigurations.Where(x => x.MachineGuid == Machine.Guid).Select(x => x.Configuration).ToObservableCollection();
//History.Insert(0, Machine.Configuration);
}
///
/// Sets the current configuration to the selected machine version default configuration.
///
private async void SetVersionConfiguration()
{
if (Machine.MachineVersion != null)
{
using (_notification.PushTaskItem("Applying default configuration..."))
{
CanWork = false;
await Task.Factory.StartNew(() =>
{
var version = _db.MachineVersions.Where(x => x.Guid == Machine.MachineVersion.Guid).Include(x => x.DefaultConfiguration).FirstOrDefault();
var version_config = _db.Adapter.GetConfiguration(x => x.Guid == version.DefaultConfiguration.Guid);
Configuration = version_config.Clone();
Machine.Configuration = Configuration;
});
CanWork = true;
}
}
else
{
_notification.ShowError("No machine version selected.");
}
}
///
/// Sets the current configuration as a default machine version configuration.
///
private void SetAsDefaultConfiguration()
{
_notification.ShowModalDialog(async (vm) =>
{
CanWork = false;
try
{
using (_notification.PushTaskItem("Saving Default Configuration..."))
{
if (vm.SelectedVersion != null)
{
var version = _db.MachineVersions.Where(x => x.Guid == vm.SelectedVersion.Guid).Include(x => x.DefaultConfiguration).SingleOrDefault(x => x.Guid == vm.SelectedVersion.Guid);
_db.Configurations.Remove(version.DefaultConfiguration);
var cloned = Configuration.Clone();
_db.Configurations.Add(cloned);
version.DefaultConfiguration = cloned;
await _db.SaveChangesAsync();
}
else
{
MachineVersion newVersion = new MachineVersion();
newVersion.Version = vm.Version;
newVersion.Name = vm.VersionName;
var cloned = Configuration.Clone();
_db.Configurations.Add(cloned);
newVersion.DefaultConfiguration = cloned;
_db.MachineVersions.Add(newVersion);
await _db.SaveChangesAsync();
}
}
}
catch (Exception ex)
{
_notification.ShowError(ex.Message);
}
finally
{
CanWork = true;
}
}, () =>
{
});
}
#endregion
}
}