using System;
using UnityEngine;
namespace Jovian.Calendar {
///
/// ScriptableObject defining the rules of an in-game calendar: day length, hours, minutes,
/// month structure, month names, week length, and starting date. Create via
/// Assets > Create > Jovian > Calendar > Calendar Settings.
///
[CreateAssetMenu(fileName = "CalendarSettings", menuName = "Jovian/Calendar/Calendar Settings")]
public class CalendarSettings : ScriptableObject {
/// How many real-time seconds one full 0 to 1 float cycle represents.
public float secondsPerFullDay;
/// How many in-world hours per day (e.g. 24, or 16 for a shorter day).
public int hoursPerDay;
/// How many in-world minutes per hour (e.g. 60).
public int minutesPerHour;
///
/// Days in each month, in order. Length of this array defines months per year.
/// E.g. { 30, 28, 31 } = 3 months with different lengths.
///
public int[] daysPerMonth;
///
/// Custom month names. Must match daysPerMonth.Length.
///
public string[] monthNames;
/// Optional: days per week for week-tracking. 0 to disable.
public int daysPerWeek;
// --- Starting date ---
public int startYear;
public int startMonth; // 0-indexed
public int startDay; // 0-indexed
public int startHour;
public int startMinute;
/// Number of months in a year, derived from daysPerMonth array length.
public int MonthsPerYear => daysPerMonth?.Length ?? 0;
/// Total days in one full year.
public int TotalDaysInYear {
get {
var total = 0;
if(daysPerMonth == null) {
return 0;
}
foreach(var t in daysPerMonth) {
total += t;
}
return total;
}
}
/// Total in-world minutes in a single day.
public int MinutesPerDay => hoursPerDay * minutesPerHour;
/// Validates all calendar parameters. Throws ArgumentException on invalid configuration.
public void Validate() {
if(secondsPerFullDay <= 0f) {
throw new ArgumentException("SecondsPerFullDay must be > 0");
}
if(hoursPerDay <= 0) {
throw new ArgumentException("HoursPerDay must be > 0");
}
if(minutesPerHour <= 0) {
throw new ArgumentException("MinutesPerHour must be > 0");
}
if(daysPerMonth == null || daysPerMonth.Length == 0) {
throw new ArgumentException("DaysPerMonth must have at least one entry");
}
if(monthNames == null || monthNames.Length != daysPerMonth.Length) {
throw new ArgumentException("MonthNames length must match DaysPerMonth length");
}
for(var i = 0; i < daysPerMonth.Length; i++) {
if(daysPerMonth[i] <= 0) {
throw new ArgumentException($"DaysPerMonth[{i}] must be > 0");
}
}
if(startMonth < 0 || startMonth >= daysPerMonth.Length) {
throw new ArgumentException("StartMonth out of range");
}
if(startDay < 0 || startDay >= daysPerMonth[startMonth]) {
throw new ArgumentException("StartDay out of range for StartMonth");
}
if(startHour < 0 || startHour >= hoursPerDay) {
throw new ArgumentException("StartHour out of range");
}
if(startMinute < 0 || startMinute >= minutesPerHour) {
throw new ArgumentException("StartMinute out of range");
}
}
}
}