using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.BL;
using Tango.BL.Entities;
using Tango.BL.Enumerations;
using Tango.ColorConversion;
using Tango.Core.Commands;
using Tango.Integration.Operation;
using Tango.Logging;
using Tango.PMR.Printing;
using Tango.PPC.Common;
using Tango.PPC.Common.Navigation;
using Tango.PPC.Common.Notifications;
using Tango.PPC.Jobs.AppBarItems;
using Tango.PPC.Jobs.AppButtons;
using Tango.PPC.Jobs.Dialogs;
using Tango.PPC.Jobs.NavigationObjects;
using Tango.PPC.Jobs.Views;
namespace Tango.PPC.Jobs.ViewModels
{
///
/// Represents the job progress view model.
///
///
public class JobProgressViewVM : PPCViewModel
{
private StopPrintingButton _stop_job_btn;
private JobHandler _handler;
private List _colorSpaces;
private bool _conversion_Busy;
private bool _printingEnded;
#region Properties
private Job _job;
///
/// Gets or sets the job.
///
public Job Job
{
get { return _job; }
set
{
_job = value;
if (_job == null)
{
IsDyeingProcess = false;
}
RaisePropertyChangedAuto();
}
}
private RunningJobStatus _runningJobStatus;
///
/// Gets or sets the running job status.
///
public RunningJobStatus RunningJobStatus
{
get { return _runningJobStatus; }
set
{
_runningJobStatus = value;
if (_runningJobStatus == null)
{
IsDyeingProcess = false;
}
RaisePropertyChangedAuto();
}
}
private bool _displayInputOutput;
public bool DisplayInputOutput
{
get { return _displayInputOutput; }
set { _displayInputOutput = value; RaisePropertyChangedAuto(); }
}
private bool _isDisplayJobOutline;
///
/// Gets or sets a value indicating whether to display the job outline.
///
public bool IsDisplayJobOutline
{
get { return _isDisplayJobOutline; }
set { _isDisplayJobOutline = value; RaisePropertyChangedAuto(); }
}
private JobTicket _jobOutlineTicket;
///
/// Gets or sets the job outline ticket.
///
public JobTicket JobOutlineTicket
{
get { return _jobOutlineTicket; }
set { _jobOutlineTicket = value; RaisePropertyChangedAuto(); }
}
private bool _isDyeingProcess;
public bool IsDyeingProcess
{
get { return _isDyeingProcess; }
set
{
if (_isDyeingProcess != value)
{
_isDyeingProcess = value;
RaisePropertyChangedAuto();
}
}
}
private BrushStop _currentBrushStop;
public BrushStop CurrentBrushStop
{
get { return _currentBrushStop; }
set
{
if (_currentBrushStop != value)
{
_currentBrushStop = value;
OnUpdateCurrentBrush();
}
}
}
private JobBrushStop _jobBrushStop;
public JobBrushStop JobBrushStop
{
get { return _jobBrushStop; }
set
{
if (_jobBrushStop != value)
{
_jobBrushStop = value;
RaisePropertyChanged(nameof(CyanOutput));
RaisePropertyChanged(nameof(LightCyanOutput));
RaisePropertyChanged(nameof(MagentaOutput));
RaisePropertyChanged(nameof(LightMagentaOutput));
RaisePropertyChanged(nameof(YellowOutput));
RaisePropertyChanged(nameof(LightYellowOutput));
RaisePropertyChanged(nameof(BlackOutput));
}
}
}
public double CyanOutput
{
get { return GetVolumeLiquidType(LiquidTypes.Cyan); }
}
public double MagentaOutput
{
get { return GetVolumeLiquidType(LiquidTypes.Magenta); }
}
public double YellowOutput
{
get { return GetVolumeLiquidType(LiquidTypes.Yellow); }
}
public double BlackOutput
{
get { return GetVolumeLiquidType(LiquidTypes.Black); }
}
public double LightCyanOutput
{
get { return GetVolumeLiquidType(LiquidTypes.LightCyan); }
}
public double LightMagentaOutput
{
get { return GetVolumeLiquidType(LiquidTypes.LightMagenta); }
}
public double LightYellowOutput
{
get { return GetVolumeLiquidType(LiquidTypes.LightYellow); }
}
#endregion
#region Commands
///
/// Gets or sets the go to job command.
///
///
/// The go to job command.
///
public RelayCommand GoToJobCommand { get; set; }
///
/// Gets or sets the display job outline command.
///
public RelayCommand DisplayJobOutlineCommand { get; set; }
///
/// Gets or sets the hide job outline command.
///
public RelayCommand HideJobOutlineCommand { get; set; }
#endregion
public JobProgressViewVM()
{
_stop_job_btn = new StopPrintingButton();
_stop_job_btn.Pressed += _stop_job_btn_Pressed;
GoToJobCommand = new RelayCommand(GoToJob);
DisplayJobOutlineCommand = new RelayCommand(DisplayJobOutline);
HideJobOutlineCommand = new RelayCommand(HideJobOutline);
}
#region Private Methods
private void HideJobOutline()
{
IsDisplayJobOutline = false;
}
private void DisplayJobOutline()
{
JobOutlineTicket = _handler.JobTicket;
IsDisplayJobOutline = true;
}
private void GoToJob()
{
NavigationManager.NavigateWithObject(new JobNavigationObject() { Job = _handler.Job });
NavigationManager.ClearHistoryExcept();
}
protected void OnUpdateCurrentBrush()
{
CurrentBrushStop?.SetLiquidVolumes(MachineProvider.Machine.Configuration, Job.Rml, MachineProvider.MachineOperator.CurrentProcessParameters);
RaisePropertyChanged(nameof(CurrentBrushStop));
}
private double GetVolumeLiquidType(LiquidTypes liquidType)
{
if (JobBrushStop != null && JobBrushStop.Dispensers != null && JobBrushStop.Dispensers.Count > 0)
{
var lt = JobBrushStop.Dispensers.FirstOrDefault(x => x.DispenserLiquidType == (DispenserLiquidType)liquidType);
if (lt != null)
{
return Math.Round(lt.Volume, 2);
}
}
return 0;
}
#endregion
#region Override Methods
///
/// Called when the application has been started.
///
public override async void OnApplicationStarted()
{
MachineProvider.MachineOperator.PrintingStarted += MachineOperator_PrintingStarted;
MachineProvider.MachineOperator.PrintingEnded += MachineOperator_PrintingEnded;
try
{
using (var db = ObservablesContext.CreateDefault())
{
_colorSpaces = await db.ColorSpaces.ToListAsync();
}
}
catch (Exception ex)
{
LogManager.Log(ex);
}
}
///
/// Called when the navigation system has navigated to this VM view.
///
public override void OnNavigatedTo()
{
base.OnNavigatedTo();
IsDisplayJobOutline = false;
if (_handler != null && !_handler.Status.IsFailed)
{
_stop_job_btn.Push();
}
}
#endregion
#region Event Handlers
private void _stop_job_btn_Pressed()
{
if (_handler != null)
{
_handler.Cancel();
IsDyeingProcess = false;
}
}
///
/// Handles the PrintingStarted event of the MachineOperator.
///
/// The source of the event.
/// The instance containing the event data.
private void MachineOperator_PrintingStarted(object sender, PrintingEventArgs e)
{
DisplayInputOutput = false;
_printingEnded = false;
_handler = e.JobHandler;
Job = e.Job;
CurrentBrushStop = null;
JobBrushStop = null;
e.JobHandler.StatusChanged += JobHandler_StatusChanged;
e.JobHandler.SpoolChangeRequired += JobHandler_SpoolChangeRequired;
e.JobHandler.Stopped += JobHandler_Stopped;
e.JobHandler.CanCancelChanged += JobHandler_CanCancelChanged;
_stop_job_btn.Push();
_stop_job_btn.IsEnabled = true;
}
private void MachineOperator_PrintingEnded(object sender, PrintingEventArgs e)
{
_printingEnded = true;
CurrentBrushStop = RunningJobStatus.CurrentSegment.BrushStops.OrderBy(x => x.StopIndex).Last();
LogManager.Log("Printing ended, popping job stop button...");
if (_stop_job_btn != null)
{
_stop_job_btn.Pop();
}
else
{
LogManager.Log("Job stop button instance was null!", LogCategory.Warning);
}
}
///
/// Handles the SpoolChangeRequired event of the JobHandler.
///
/// The source of the event.
/// The instance containing the event data.
private void JobHandler_SpoolChangeRequired(object sender, SpoolChangeRequiredEventArgs e)
{
InvokeUI(async () =>
{
if ((await NotificationProvider.ShowDialog(new SpoolChangeViewVM(e))).DialogResult)
{
e.Confirm();
}
else
{
e.Abort();
}
});
}
///
/// Handles the Stopped event of the JobHandler.
///
/// The source of the event.
/// The instance containing the event data.
private void JobHandler_Stopped(object sender, EventArgs e)
{
if (_handler != null)
{
_handler.StatusChanged -= JobHandler_StatusChanged;
_handler.SpoolChangeRequired -= JobHandler_SpoolChangeRequired;
_handler.Stopped -= JobHandler_Stopped;
_handler.CanCancelChanged -= JobHandler_CanCancelChanged;
IsDyeingProcess = false;
}
}
///
/// Handles the JobHandler StatusChanged event.
///
/// The sender.
/// The e.
private void JobHandler_StatusChanged(object sender, RunningJobStatus e)
{
InvokeUI(async () =>
{
RunningJobStatus = e;
IsDyeingProcess = (RunningJobStatus != null && RunningJobStatus.CurrentSegment != null);
if (RunningJobStatus != null && RunningJobStatus.CurrentSegment != null)
{
try
{
if (_runningJobStatus.CurrentSegment.IsInterSegment)
{
var stop = _runningJobStatus.CurrentSegment.BrushStops.FirstOrDefault();
stop.ColorSpace = CurrentBrushStop.ColorSpace;
CurrentBrushStop = stop;
JobBrushStop = null;
}
else
{
var realsegmIndex = 1;
if (Job.EnableInterSegment && Job.InterSegmentLength > 0)
{
int segmentIndex = _runningJobStatus.CurrentSegment.SegmentIndex - (Job.EffectiveSegments.Count * RunningJobStatus.CurrentUnit);
if (RunningJobStatus.CurrentUnit > 0)
{
segmentIndex -= RunningJobStatus.CurrentUnit;// inter segment between units
}
realsegmIndex = (int)(segmentIndex / 2) + 1;
}
else
{
realsegmIndex = Math.Max(_runningJobStatus.CurrentSegment.SegmentIndex - (Job.Segments.Count * RunningJobStatus.CurrentUnit), 0);
}
var segment = Job.Segments.FirstOrDefault(x => x.SegmentIndex == realsegmIndex);
JobSegment jobSegment = null;
if (segment != null)
{
if (_handler.JobTicket.Segments.Count > 0)
{
jobSegment = _handler.JobTicket.Segments[Job.OrderedSegments.IndexOf(segment)];
if (jobSegment.BrushStops.Count == 1)
{
JobBrushStop = jobSegment.BrushStops.First();
}
else if (jobSegment.BrushStops.Count > 1)
{
JobBrushStop = jobSegment.BrushStops.Last(x => x.OffsetMeters <= e.CurrentSegment.Progress);
}
else
{
JobBrushStop = null;
}
}
}
if (segment != null && jobSegment != null && jobSegment.BrushStops.Count > 1)
{
if (!_conversion_Busy)
{
var brushStop = RunningJobStatus.CurrentSegment.FirstBrushStop;
await ApplyJobBrushStopToBrushStop(JobBrushStop, brushStop);
if (!_printingEnded)
{
_currentBrushStop = brushStop;
RaisePropertyChanged(nameof(CurrentBrushStop));
}
}
}
else
{
CurrentBrushStop = RunningJobStatus.CurrentSegment.FirstBrushStop;
}
}
}
catch (Exception ex)
{
LogManager.Log(ex, "Error displaying job progress input output.");
}
DisplayInputOutput = true;
}
});
}
private async Task ApplyJobBrushStopToBrushStop(JobBrushStop stop, BrushStop s)
{
_conversion_Busy = true;
foreach (var dispenser in stop.Dispensers)
{
s.SetVolume(dispenser.Index, dispenser.Volume);
}
s.SetLiquidVolumes(MachineProvider.Machine.Configuration, Job.Rml, MachineProvider.MachineOperator.CurrentProcessParameters);
foreach (var liquidVolume in s.LiquidVolumes.Where(x => x.IdsPack.LiquidType.IsLightInk && x.Volume > 0).ToList())
{
var darkInk = s.LiquidVolumes.FirstOrDefault(x => x.IdsPack.LiquidType.Code == liquidVolume.IdsPack.LiquidType.DarkInkCode);
if (darkInk != null)
{
darkInk.Volume = liquidVolume.Volume / 10d;
liquidVolume.Volume = 0;
}
}
if (_colorSpaces != null)
{
if ((s.BrushColorSpace == ColorSpaces.RGB || s.BrushColorSpace == ColorSpaces.LAB) && (!s.IsLast && !s.IsFirst))
{
var converter = new DefaultColorConverter();
var previousSpace = s.ColorSpace;
s.SetColorSpaceSilent(_colorSpaces.First(x => x.Space == ColorSpaces.Volume));
var output = await converter.ConvertAsync(s, false, false);
s.SetColorSpaceSilent(previousSpace);
if (!_printingEnded)
{
output.ApplyOnBrushStop(s, MachineProvider.MachineOperator.CurrentProcessParameters);
}
}
}
_conversion_Busy = false;
}
///
/// Handles the CanCancelChanged event of the JobHandler control.
///
/// The source of the event.
/// The instance containing the event data.
private void JobHandler_CanCancelChanged(object sender, EventArgs e)
{
_stop_job_btn.IsEnabled = _handler.CanCancel;
}
#endregion
}
}