// Copyright (c) 2024 Synty Studios Limited. All rights reserved. // // Use of this software is subject to the terms and conditions of the Synty Studios End User Licence Agreement (EULA) // available at: https://syntystore.com/pages/end-user-licence-agreement // // For additional details, see the LICENSE.MD file bundled with this software. using SQLite; using Synty.SidekickCharacters.Enums; using Synty.SidekickCharacters.Utils; using System; using System.Collections.Generic; using System.Linq; namespace Synty.SidekickCharacters.Database.DTO { [Table("sk_part_preset")] public class SidekickPartPreset { private SidekickSpecies _species; [PrimaryKey] [AutoIncrement] [Column("id")] public int ID { get; set; } [Column("name")] public string Name { get; set; } [Column("part_group")] public PartGroup PartGroup { get; set; } [Column("ptr_species")] public int PtrSpecies { get; set; } [Column("outfit")] public string Outfit { get; set; } [Ignore] public SidekickSpecies Species { get => _species; set { _species = value; PtrSpecies = value.ID; } } /// /// Gets a specific Preset by its database ID. /// /// The Database Manager to use. /// The id of the required Preset. /// The specific Preset if it exists; otherwise null. public static SidekickPartPreset GetByID(DatabaseManager dbManager, int id) { SidekickPartPreset partPreset = dbManager.GetCurrentDbConnection().Find(id); Decorate(dbManager, partPreset); return partPreset; } /// /// Gets a list of all the Presets in the database. /// /// The Database Manager to use. /// A list of all presets in the database. public static List GetAll(DatabaseManager dbManager) { List partPresets = dbManager.GetCurrentDbConnection().Table().ToList(); foreach (SidekickPartPreset partPreset in partPresets) { Decorate(dbManager, partPreset); } return partPresets; } /// /// Gets a list of all the Part Presets in the database that have the matching species. /// /// The Database Manager to use. /// The species to get all the part presets for. /// A list of all part presets in the database for the given species. public static List GetAllBySpecies(DatabaseManager dbManager, SidekickSpecies species) { List partPresets = dbManager.GetCurrentDbConnection().Table() .Where(partPreset => partPreset.PtrSpecies == species.ID) .ToList(); foreach (SidekickPartPreset partPreset in partPresets) { partPreset.Species = species; } return partPresets; } /// /// Gets a Part Presets in the database with the matching name if one exists. /// /// The Database Manager to use. /// The name of the preset to retrieve. /// Returns a Part Presets in the database with the matching name if one exists; otherwise null. public static SidekickPartPreset GetByName(DatabaseManager dbManager, string name) { SidekickPartPreset partPreset = dbManager.GetCurrentDbConnection() .Table() .FirstOrDefault(partPreset => partPreset.Name == name); if (partPreset != null) { Decorate(dbManager, partPreset); } return partPreset; } /// /// Gets a list of all the Part Presets in the database that have the matching species and part group. /// /// The Database Manager to use. /// The part group to filter search by. /// A list of all part presets in the database for the given species and part group. public static List GetAllByGroup(DatabaseManager dbManager, PartGroup partGroup, bool excludeMissingParts = true) { List partPresets = dbManager.GetCurrentDbConnection().Table() .Where(partPreset => partPreset.PartGroup == partGroup) .ToList(); foreach (SidekickPartPreset partPreset in partPresets) { Decorate(dbManager, partPreset); } if (excludeMissingParts) { List toRemove = new List(); foreach (SidekickPartPreset partPreset in partPresets) { if (!partPreset.HasAllPartsAvailable(dbManager)) { toRemove.Add(partPreset); } } partPresets.RemoveAll(preset => toRemove.Contains(preset)); } return partPresets; } /// /// Gets a list of all the Part Presets in the database that have the matching species and part group. /// /// The Database Manager to use. /// The species to get all the part presets for. /// The part group to filter search by. /// A list of all part presets in the database for the given species and part group. public static List GetAllBySpeciesAndGroup(DatabaseManager dbManager, SidekickSpecies species, PartGroup partGroup) { List partPresets = dbManager.GetCurrentDbConnection().Table() .Where(partPreset => partPreset.PtrSpecies == species.ID && partPreset.PartGroup == partGroup) .ToList(); foreach (SidekickPartPreset partPreset in partPresets) { partPreset.Species = species; } return partPresets; } /// /// Ensures that the given set has its nice DTO class properties set /// /// The Database Manager to use. /// The color set to decorate /// A color set with all DTO class properties set private static void Decorate(DatabaseManager dbManager, SidekickPartPreset partPreset) { if (partPreset.Species == null && partPreset.PtrSpecies >= 0) { partPreset.Species = SidekickSpecies.GetByID(dbManager, partPreset.PtrSpecies); } } /// /// Updates or Inserts this item in the Database. /// /// The database manager to use. public int Save(DatabaseManager dbManager) { if (ID < 0) { dbManager.GetCurrentDbConnection().Insert(this); // in theory this could return a different ID, but in practice it's highly unlikely ID = (int) SQLite3.LastInsertRowid(dbManager.GetCurrentDbConnection().Handle); } dbManager.GetCurrentDbConnection().Update(this); return ID; } /// /// Deletes this item from the database /// /// The database manager to use. public void Delete(DatabaseManager dbManager) { foreach (SidekickPartPresetRow row in SidekickPartPresetRow.GetAllByPreset(dbManager, this)) { row.Delete(dbManager); } foreach (SidekickPresetFilterRow row in SidekickPresetFilterRow.GetAllForPreset(dbManager, this)) { row.Delete(dbManager); } SidekickPartPresetImage image = SidekickPartPresetImage.GetByPresetAndPartGroup(dbManager, this, PartGroup); image?.Delete(dbManager); dbManager.GetCurrentDbConnection().Delete(ID); } /// /// Determines if all the parts associated with this preset are valid (has a file in the project). /// /// The database manager to use. /// True if all parts are valid; otherwise False. public bool HasAllPartsAvailable(DatabaseManager dbManager) { List allRows = SidekickPartPresetRow.GetAllByPreset(dbManager, this); return allRows.Count > 0 && allRows.All(row => row.HasValidPart()); } /// /// Determines if all the parts associated with this preset are valid (has a file in the project). /// /// The database manager to use. /// True if all parts are valid; otherwise False. public bool HasOnlyBasePartsAndAllAvailable(DatabaseManager dbManager) { List allRows = SidekickPartPresetRow.GetAllByPreset(dbManager, this); return allRows.Count > 0 && allRows.All(row => row.HasValidPart() && (row.Part == null || PartUtils.IsBaseSpeciesPart(row.PartName))); } /// /// Checks the equality of this preset to the given preset. /// /// The preset to check equality with. /// True if the presets are equal, otherwise false. protected bool Equals(SidekickPartPreset other) { return ID == other.ID && Name == other.Name && PartGroup == other.PartGroup && PtrSpecies == other.PtrSpecies; } /// public override bool Equals(object obj) { if (ReferenceEquals(null, obj)) { return false; } if (ReferenceEquals(this, obj)) { return true; } if (obj.GetType() != this.GetType()) { return false; } return Equals((SidekickPartPreset) obj); } /// public override int GetHashCode() { return HashCode.Combine(ID, Name, (int) PartGroup, PtrSpecies); } } }