/*
* GNU AFFERO GENERAL PUBLIC LICENSE
* Version 3, 19 November 2007
* Copyright (C) 2007 Free Software Foundation, Inc.
* Everyone is permitted to copy and distribute verbatim copies
* of this license document, but changing it is not allowed.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using UVtools.Core.Extensions;
using UVtools.Core.Objects;
namespace UVtools.Core.Managers;
public class MaterialManager : BindableBase, IList
{
#region Settings
public static string FilePath = Path.Combine(CoreSettings.DefaultSettingsFolderAndEnsureCreation, "materials.xml");
#endregion
#region Singleton
private static Lazy _instanceHolder =
new(() => new MaterialManager());
///
/// Instance of (singleton)
///
public static MaterialManager Instance => _instanceHolder.Value;
//public static List Operations => _instance.Operations;
#endregion
#region Members
private RangeObservableCollection _materials = new();
#endregion
#region Properties
public RangeObservableCollection Materials
{
get => _materials;
set => RaiseAndSetIfChanged(ref _materials, value);
}
///
/// Gets the total number of bottles in stock
///
public int BottlesInStock => this.Sum(material => material.BottlesInStock);
///
/// Gets the total number of bottles ever owned
///
public int OwnedBottles => this.Sum(material => material.OwnedBottles);
///
/// Gets the total of consumed volume in milliliters
///
public decimal ConsumedVolume => this.Sum(material => material.ConsumedVolume);
///
/// Gets the total of consumed volume in liters
///
public decimal ConsumedVolumeLiters => this.Sum(material => material.ConsumedVolumeLiters);
///
/// Gets the total volume in stock in milliliters
///
public decimal VolumeInStock => this.Sum(material => material.VolumeInStock);
///
/// Gets the total volume in stock in liters
///
public decimal VolumeInStockLiters => VolumeInStock / 1000;
///
/// Gets the total costs
///
public decimal TotalCost => this.Sum(material => material.TotalCost);
///
/// Gets the total print time in hours
///
public double PrintTime => this.Sum(material => material.PrintTime);
///
/// Gets the total print time
///
public TimeSpan PrintTimeSpan => TimeSpan.FromHours(PrintTime);
#endregion
#region Constructor
private MaterialManager()
{
}
#endregion
#region Methods
public Material this[int index]
{
get => _materials[index];
set => _materials[index] = value;
}
public Material this[uint index]
{
get => _materials[(int) index];
set => _materials[(int) index] = value;
}
public Material? this[Material material]
{
get
{
var index = IndexOf(material);
return index < 0 ? this[index] : null;
}
set
{
var index = IndexOf(material);
if(index >= 0) this[index] = value!;
}
}
public IEnumerator GetEnumerator() => _materials.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public void Add(Material item)
{
_materials.Add(item);
RaisePropertiesChanged();
}
public void Add(Material item, bool save)
{
Add(item);
if (save) Save();
}
public void Clear()
{
_materials.Clear();
RaisePropertiesChanged();
}
public void Clear(bool save)
{
Clear();
if(save) Save();
}
public bool Contains(Material item) => _materials.Contains(item);
public void CopyTo(Material[] array, int arrayIndex)
{
_materials.CopyTo(array, arrayIndex);
RaisePropertiesChanged();
}
public bool Remove(Material item)
{
if (_materials.Remove(item))
{
RaisePropertiesChanged();
return true;
}
return false;
}
public void Remove(Material item, bool save)
{
Remove(item);
if (save) Save();
}
public void RemoveRange(IEnumerable collection)
{
_materials.RemoveRange(collection);
}
public int Count => _materials.Count;
public bool IsReadOnly => false;
public int IndexOf(Material item) => _materials.IndexOf(item);
public void Insert(int index, Material item)
{
_materials.Insert(index, item);
RaisePropertiesChanged();
}
public void Insert(int index, Material item, bool save)
{
Insert(index, item);
if (save) Save();
}
public void RemoveAt(int index)
{
_materials.RemoveAt(index);
RaisePropertiesChanged();
}
public void RemoveAt(int index, bool save)
{
RemoveAt(index);
if (save) Save();
}
public void RaisePropertiesChanged()
{
RaisePropertyChanged(nameof(BottlesInStock));
RaisePropertyChanged(nameof(OwnedBottles));
RaisePropertyChanged(nameof(ConsumedVolume));
RaisePropertyChanged(nameof(ConsumedVolumeLiters));
RaisePropertyChanged(nameof(VolumeInStock));
RaisePropertyChanged(nameof(VolumeInStockLiters));
RaisePropertyChanged(nameof(TotalCost));
RaisePropertyChanged(nameof(PrintTime));
RaisePropertyChanged(nameof(PrintTimeSpan));
RaisePropertyChanged(nameof(Count));
}
///
/// Load settings from file
///
public static void Load()
{
if (string.IsNullOrWhiteSpace(FilePath) || !File.Exists(FilePath))
{
return;
}
try
{
var instance = XmlExtensions.DeserializeFromFile(FilePath);
_instanceHolder = new Lazy(() => instance);
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
}
///
/// Save settings to file
///
public static void Save()
{
try
{
XmlExtensions.SerializeToFile(Instance, FilePath, XmlExtensions.SettingsIndent);
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
}
public void SortByName()
{
_materials.Sort((material, material1) => string.Compare(material.Name, material1.Name, StringComparison.Ordinal));
}
#endregion
}