Newer
Older
Qwilight / Qwilight / NoteFile / BaseNoteFile.cs
@Taehui Taehui on 10 Dec 11 KB 2023-12-10 오후 1:58
using Qwilight.Compiler;
using Qwilight.UIComponent;
using Qwilight.Utilities;
using System.IO;
using System.Windows.Media;

namespace Qwilight.NoteFile
{
    public abstract class BaseNoteFile : Computing
    {
        public enum Handled
        {
            Not, Clear, Band1, F = 4, HigherClear, HighestClear
        }

        public enum NoteVariety
        {
            Total, BMS, BMSON = 3, EventNote = 5
        }

        public enum Level
        {
            Level0, Level1, Level2, Level3, Level4, Level5
        }

        public static BaseNoteFile[] GetNoteFiles(string noteFilePath, DefaultEntryItem defaultEntryItem, EntryItem entryItem, int dataID)
        {
            if (noteFilePath.IsTailCaselsss(".bmson"))
            {
                return new[] { new BMSONFile(noteFilePath, defaultEntryItem, entryItem) };
            }
            else if (noteFilePath.IsTailCaselsss(".pms"))
            {
                return new[] { new PMSFile(noteFilePath, defaultEntryItem, entryItem) };
            }
            else
            {
                return new[] { new BMSFile(noteFilePath, defaultEntryItem, entryItem) };
            }
        }

        readonly string[] _judgmentMillisText = new string[6];
        string _fittedText;
        ImageSource _noteDrawing;
        ImageSource _bannerDrawing;
        bool _wantNoteDrawing = true;
        bool _wantBannerDrawing = true;
        Handled _handledValue;
        string _noteID128;
        string _noteID256;
        string _noteID512;

        public virtual int DataID => 0;

        public string FittedText
        {
            get => _fittedText;

            set => SetProperty(ref _fittedText, value, nameof(FittedText));
        }

        public virtual bool IsLogical { get; }

        public bool IsAltDrawing => LogicalDrawing != null || EssentialDrawing != null;

        public virtual ImageSource LogicalDrawing { get; }

        public virtual ImageSource EssentialDrawing { get; }

        public virtual string LogicalAudioFileName => "Default";

        public Color LevelColor => BaseUI.Instance.LevelColors[(int)LevelValue];

        public virtual ImageSource HandledWallDrawing => BaseUI.Instance.HandledWallDrawings[(int)HandledValue];

        public ImageSource NoteDrawing
        {
            get
            {
                if (_wantNoteDrawing && !string.IsNullOrEmpty(NoteDrawingPath))
                {
                    _wantNoteDrawing = false;
                    Task.Run(() =>
                    {
                        var noteDrawingPath = Utility.GetFilePath(NoteDrawingPath, Utility.FileFormatFlag.Drawing);
                        if (!string.IsNullOrEmpty(noteDrawingPath))
                        {
                            try
                            {
                                SetProperty(ref _noteDrawing, DrawingSystem.Instance.LoadDefault(noteDrawingPath, null), nameof(NoteDrawing));
                            }
                            catch
                            {
                            }
                        }
                    });
                }
                return _noteDrawing ?? DrawingSystem.Instance.DefaultDrawing.DefaultDrawing;
            }
        }

        public ImageSource BannerDrawing
        {
            get
            {
                if (_wantBannerDrawing && !string.IsNullOrEmpty(BannerDrawingPath))
                {
                    _wantBannerDrawing = false;
                    Task.Run(() =>
                    {
                        var bannerDrawingPath = Utility.GetFilePath(BannerDrawingPath, Utility.FileFormatFlag.Drawing);
                        if (!string.IsNullOrEmpty(bannerDrawingPath))
                        {
                            try
                            {
                                SetProperty(ref _bannerDrawing, DrawingSystem.Instance.LoadDefault(bannerDrawingPath, null), nameof(BannerDrawing));
                            }
                            catch
                            {
                            }
                        }
                    });
                }
                return _bannerDrawing;
            }
        }

        public string WantLevelID { get; set; } = string.Empty;

        public string HighestJudgmentMillisText
        {
            get => _judgmentMillisText[(int)Component.Judged.Highest];

            set => SetProperty(ref _judgmentMillisText[(int)Component.Judged.Highest], value, nameof(HighestJudgmentMillisText));
        }

        public string HigherJudgmentMillisText
        {
            get => _judgmentMillisText[(int)Component.Judged.Higher];

            set => SetProperty(ref _judgmentMillisText[(int)Component.Judged.Higher], value, nameof(HigherJudgmentMillisText));
        }

        public string HighJudgmentMillisText
        {
            get => _judgmentMillisText[(int)Component.Judged.High];

            set => SetProperty(ref _judgmentMillisText[(int)Component.Judged.High], value, nameof(HighJudgmentMillisText));
        }

        public string LowJudgmentMillisText
        {
            get => _judgmentMillisText[(int)Component.Judged.Low];

            set => SetProperty(ref _judgmentMillisText[(int)Component.Judged.Low], value, nameof(LowJudgmentMillisText));
        }

        public string LowerJudgmentMillisText
        {
            get => _judgmentMillisText[(int)Component.Judged.Lower];

            set => SetProperty(ref _judgmentMillisText[(int)Component.Judged.Lower], value, nameof(LowerJudgmentMillisText));
        }

        public string LowestJudgmentMillisText
        {
            get => _judgmentMillisText[(int)Component.Judged.Lowest];

            set => SetProperty(ref _judgmentMillisText[(int)Component.Judged.Lowest], value, nameof(LowestJudgmentMillisText));
        }

        public DateTime? LatestDate { get; set; }

        public int HandledCount { get; set; }

        public string FileName { get; set; }

        public bool HasNoteDrawing => _noteDrawing != null;

        public HashSet<DefaultEntryItem> FavoriteEntryItems { get; } = new();

        public DefaultEntryItem DefaultEntryItem { get; }

        public string NoteFilePath { get; }

        public EntryItem EntryItem { get; }

        public Handled HandledValue
        {
            get => _handledValue;

            set => SetProperty(ref _handledValue, value, nameof(HandledWallDrawing));
        }

        public Action OnLevyNoteFile { get; init; }

        public BaseNoteFile(string noteFilePath, DefaultEntryItem defaultEntryItem, EntryItem entryItem)
        {
            NoteFilePath = noteFilePath;
            FileName = Path.GetFileName(NoteFilePath);
            DefaultEntryItem = defaultEntryItem;
            EntryItem = entryItem;
            LongNoteModeDate = Component.LatestLongNoteModeDate;
        }

        public override bool Equals(object obj) => obj is BaseNoteFile noteFile && GetNoteID512() == noteFile.GetNoteID512();

        public override int GetHashCode() => GetNoteID512().GetHashCode();

        public void SetJudgmentMillisTexts(ModeComponent modeComponentValue)
        {
            HighestJudgmentMillisText = GetMillisText(Component.Judged.Highest);
            HigherJudgmentMillisText = GetMillisText(Component.Judged.Higher);
            HighJudgmentMillisText = GetMillisText(Component.Judged.High);
            LowJudgmentMillisText = GetMillisText(Component.Judged.Low);
            LowerJudgmentMillisText = GetMillisText(Component.Judged.Lower);
            LowestJudgmentMillisText = GetMillisText(Component.Judged.Lowest);

            string GetMillisText(Component.Judged judged)
            {
                var judgment0 = Math.Round(Component.GetJudgmentMillis(judged, modeComponentValue, JudgmentStage, Component.LatestJudgmentModeDate, Component.LatestJudgmentMapDate, Component.LatestLongNoteAssistDate, 0), 3);
                var judgment1 = Math.Round(Component.GetJudgmentMillis(judged, modeComponentValue, JudgmentStage, Component.LatestJudgmentModeDate, Component.LatestJudgmentMapDate, Component.LatestLongNoteAssistDate, 1), 3);
                return Math.Abs(judgment0) != Math.Abs(judgment1) ? $"{judgment0} ~ {judgment1} ms" : $"{judgment1} ms";
            }
        }

        public void SetConfigure()
        {
            var (audioWait, mediaWait, media) = DB.Instance.GetWait(this);
            Configure.Instance.AudioWait = audioWait;
            Configure.Instance.MediaWait = mediaWait;
            Configure.Instance.Media = media != false;
            Configure.Instance.NoteFormatID = DB.Instance.GetFormat(this);
        }

        public virtual string GetNoteID128(byte[] data = null)
        {
            if (_noteID128 == null)
            {
                try
                {
                    _noteID128 = Utility.GetID128(data ?? GetContents());
                }
                catch
                {
                    _noteID128 = string.Empty;
                }
            }
            return _noteID128;
        }

        public virtual string GetNoteID256(byte[] data = null)
        {
            if (_noteID256 == null)
            {
                try
                {
                    _noteID256 = Utility.GetID256(data ?? GetContents());
                }
                catch
                {
                    _noteID256 = string.Empty;
                }
            }
            return _noteID256;
        }

        public string GetNoteID512(byte[] data = null)
        {
            if (_noteID512 == null)
            {
                _noteID512 = $"{GetNoteID512Impl(data)}:{DataID}";
            }
            return _noteID512;
        }

        public void SetData()
        {
            FavoriteEntryItems.Clear();
            foreach (var favoriteEntryItem in DB.Instance.GetFavoriteEntryItems(this))
            {
                FavoriteEntryItems.Add(favoriteEntryItem);
            }
            HandledValue = DB.Instance.GetHandled(this);
            (LatestDate, HandledCount) = DB.Instance.GetDate(this, default);
        }

        string GetNoteID512Impl(byte[] data = null)
        {
            try
            {
                return Utility.GetID512(data ?? GetContents());
            }
            catch
            {
                return string.Empty;
            }
        }

        public byte[] GetContents()
        {
            try
            {
                return File.Exists(NoteFilePath) ? File.ReadAllBytes(NoteFilePath) : Array.Empty<byte>();
            }
            catch
            {
                return Array.Empty<byte>();
            }
        }

        public void SetNoteIDs(string noteID128, string noteID256, string noteID512)
        {
            _noteID128 = noteID128;
            _noteID256 = noteID256;
            _noteID512 = noteID512;
        }

        public void Compile(int salt, CancellationTokenSource setCancelCompiler = null)
        {
            if (!IsLogical)
            {
                var data = GetContents();
                GetNoteID128(data);
                GetNoteID256(data);
                GetNoteID512(data);
                InitCompiled();
                BaseCompiler.GetCompiler(this, setCancelCompiler).Compile(this, data, salt);
            }
        }

        public bool IsValid() => GetNoteID512() == $"{GetNoteID512Impl()}:{DataID}";

        public bool IsContinuous(BaseNoteFile noteFile) => noteFile != null && (EntryItem == noteFile.EntryItem || Utility.GetTitle(Title) == Utility.GetTitle(noteFile.Title));

        public override void OnFault(Exception e) => throw e;

        public override void OnCompiled() => FastDB.Instance.SetNoteFile(this);
    }
}