using System;
using System.Collections.Generic;
using System.Linq;
using Artemis.Core.Modules;
using Artemis.Storage.Entities.Profile;
namespace Artemis.Core;
///
/// Represents the configuration of a profile, contained in a
///
public class ProfileConfiguration : BreakableModel, IStorageModel, IDisposable
{
///
/// Represents an empty profile.
///
public static readonly ProfileConfiguration Empty = new(ProfileCategory.Empty, "Empty", "Empty");
private ActivationBehaviour _activationBehaviour;
private bool _activationConditionMet;
private ProfileCategory _category;
private Hotkey? _disableHotkey;
private bool _disposed;
private Hotkey? _enableHotkey;
private ProfileConfigurationHotkeyMode _hotkeyMode;
private bool _isBeingEdited;
private bool _isMissingModule;
private bool _isSuspended;
private bool _fadeInAndOut;
private Module? _module;
private string _name;
private int _order;
private Profile? _profile;
internal ProfileConfiguration(ProfileCategory category, string name, string icon)
{
_name = name;
_category = category;
Entity = new ProfileConfigurationEntity();
Icon = new ProfileConfigurationIcon(Entity);
Icon.SetIconByName(icon);
ActivationCondition = new NodeScript("Activate profile", "Whether or not the profile should be active", this);
}
internal ProfileConfiguration(ProfileCategory category, ProfileConfigurationEntity entity)
{
// Will be loaded from the entity
_name = null!;
_category = category;
Entity = entity;
Icon = new ProfileConfigurationIcon(Entity);
ActivationCondition = new NodeScript("Activate profile", "Whether or not the profile should be active", this);
Load();
}
///
/// Gets or sets the name of this profile configuration
///
public string Name
{
get => _name;
set => SetAndNotify(ref _name, value);
}
///
/// The order in which this profile appears in the update loop and sidebar
///
public int Order
{
get => _order;
set => SetAndNotify(ref _order, value);
}
///
/// Gets or sets a boolean indicating whether this profile is suspended, disabling it regardless of the
///
///
public bool IsSuspended
{
get => _isSuspended;
set => SetAndNotify(ref _isSuspended, value);
}
///
/// Gets a boolean indicating whether this profile configuration is missing any modules
///
public bool IsMissingModule
{
get => _isMissingModule;
private set => SetAndNotify(ref _isMissingModule, value);
}
///
/// Gets or sets the category of this profile configuration
///
public ProfileCategory Category
{
get => _category;
internal set => SetAndNotify(ref _category, value);
}
///
/// Gets or sets the used to determine hotkey behaviour
///
public ProfileConfigurationHotkeyMode HotkeyMode
{
get => _hotkeyMode;
set => SetAndNotify(ref _hotkeyMode, value);
}
///
/// Gets or sets the hotkey used to enable or toggle the profile
///
public Hotkey? EnableHotkey
{
get => _enableHotkey;
set => SetAndNotify(ref _enableHotkey, value);
}
///
/// Gets or sets the hotkey used to disable the profile
///
public Hotkey? DisableHotkey
{
get => _disableHotkey;
set => SetAndNotify(ref _disableHotkey, value);
}
///
/// Gets or sets the behaviour of when this profile is activated
///
public ActivationBehaviour ActivationBehaviour
{
get => _activationBehaviour;
set => SetAndNotify(ref _activationBehaviour, value);
}
///
/// Gets a boolean indicating whether the activation conditions where met during the last call
///
public bool ActivationConditionMet
{
get => _activationConditionMet;
private set => SetAndNotify(ref _activationConditionMet, value);
}
///
/// Gets or sets a boolean indicating whether this profile configuration is being edited
///
public bool IsBeingEdited
{
get => _isBeingEdited;
set => SetAndNotify(ref _isBeingEdited, value);
}
///
/// Gets the profile of this profile configuration
///
public Profile? Profile
{
get => _profile;
internal set => SetAndNotify(ref _profile, value);
}
///
/// Gets or sets a boolean indicating whether this profile should fade in and out when enabling or disabling
///
public bool FadeInAndOut
{
get => _fadeInAndOut;
set => SetAndNotify(ref _fadeInAndOut, value);
}
///
/// Gets or sets the module this profile uses
///
public Module? Module
{
get => _module;
set
{
SetAndNotify(ref _module, value);
IsMissingModule = false;
}
}
///
/// Gets the icon configuration
///
public ProfileConfigurationIcon Icon { get; }
///
/// Gets the data model condition that must evaluate to for this profile to be activated
/// alongside any activation requirements of the , if set
///
public NodeScript ActivationCondition { get; }
///
/// Gets the entity used by this profile config
///
public ProfileConfigurationEntity Entity { get; }
///
/// Gets the ID of the profile of this profile configuration
///
public Guid ProfileId => Entity.ProfileId;
#region Overrides of BreakableModel
///
public override string BrokenDisplayName => "Profile Configuration";
#endregion
///
/// Updates this configurations activation condition status
///
public void Update()
{
if (_disposed)
throw new ObjectDisposedException("ProfileConfiguration");
if (!ActivationCondition.ExitNodeConnected)
{
ActivationConditionMet = true;
}
else
{
ActivationCondition.Run();
ActivationConditionMet = ActivationCondition.Result;
}
}
///
/// Determines whether the profile of this configuration should be active
///
/// Whether or not to take activation conditions into consideration
public bool ShouldBeActive(bool includeActivationCondition)
{
if (_disposed)
throw new ObjectDisposedException("ProfileConfiguration");
if (IsBeingEdited)
return true;
if (Category.IsSuspended || IsSuspended || IsMissingModule)
return false;
if (includeActivationCondition)
return ActivationConditionMet && (Module == null || Module.IsActivated);
return Module == null || Module.IsActivated;
}
///
public override string ToString()
{
return $"[ProfileConfiguration] {nameof(Name)}: {Name}";
}
internal void LoadModules(List enabledModules)
{
if (_disposed)
throw new ObjectDisposedException("ProfileConfiguration");
Module = enabledModules.FirstOrDefault(m => m.Id == Entity.ModuleId);
IsMissingModule = Module == null && Entity.ModuleId != null;
}
///
public void Dispose()
{
_disposed = true;
ActivationCondition.Dispose();
}
#region Implementation of IStorageModel
///
public void Load()
{
if (_disposed)
throw new ObjectDisposedException("ProfileConfiguration");
Name = Entity.Name;
IsSuspended = Entity.IsSuspended;
ActivationBehaviour = (ActivationBehaviour) Entity.ActivationBehaviour;
HotkeyMode = (ProfileConfigurationHotkeyMode) Entity.HotkeyMode;
FadeInAndOut = Entity.FadeInAndOut;
Order = Entity.Order;
Icon.Load();
if (Entity.ActivationCondition != null)
ActivationCondition.LoadFromEntity(Entity.ActivationCondition);
EnableHotkey = Entity.EnableHotkey != null ? new Hotkey(Entity.EnableHotkey) : null;
DisableHotkey = Entity.DisableHotkey != null ? new Hotkey(Entity.DisableHotkey) : null;
}
///
public void Save()
{
if (_disposed)
throw new ObjectDisposedException("ProfileConfiguration");
Entity.Name = Name;
Entity.IsSuspended = IsSuspended;
Entity.ActivationBehaviour = (int) ActivationBehaviour;
Entity.HotkeyMode = (int) HotkeyMode;
Entity.ProfileCategoryId = Category.Entity.Id;
Entity.FadeInAndOut = FadeInAndOut;
Entity.Order = Order;
Icon.Save();
ActivationCondition.Save();
Entity.ActivationCondition = ActivationCondition.Entity;
EnableHotkey?.Save();
Entity.EnableHotkey = EnableHotkey?.Entity;
DisableHotkey?.Save();
Entity.DisableHotkey = DisableHotkey?.Entity;
if (!IsMissingModule)
Entity.ModuleId = Module?.Id;
}
#endregion
}
///
/// Represents a type of behaviour when this profile is activated
///
public enum ActivationBehaviour
{
///
/// Do nothing to other profiles
///
None,
///
/// Disable all other profiles
///
DisableOthers,
///
/// Disable all other profiles below this one
///
DisableOthersBelow,
///
/// Disable all other profiles above this one
///
DisableOthersAbove,
///
/// Disable all other profiles in the same category
///
DisableOthersInCategory,
///
/// Disable all other profiles below this one in the same category
///
DisableOthersBelowInCategory,
///
/// Disable all other profiles above this one in the same category
///
DisableOthersAboveInCategory
}
///
/// Represents a hotkey mode for a profile configuration
///
public enum ProfileConfigurationHotkeyMode
{
///
/// Use no hotkeys
///
None,
///
/// Toggle the profile with one hotkey
///
Toggle,
///
/// Enable and disable the profile with two separate hotkeys
///
EnableDisable
}