<commit_before>﻿using System.Linq;
using DereTore.Applications.StarlightDirector.Components;
using DereTore.Applications.StarlightDirector.Extensions;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace DereTore.Applications.StarlightDirector.Entities {
    [JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy), MemberSerialization = MemberSerialization.OptIn)]
    public sealed class Score {

        [JsonProperty]
        public InternalList<Bar> Bars { get; }

        public Project Project { get; internal set; }

        public Difficulty Difficulty { get; internal set; }

        public Bar AddBar() {
            return InsertBar(Bars.Count);
        }

        public Bar InsertBar(int indexBefore) {
            return InsertBar(indexBefore, null);
        }

        public Bar InsertBar(int indexBefore, BarParams barParams) {
            var bar = new Bar(this, indexBefore) {
                Params = barParams
            };
            if (indexBefore == Bars.Count) {
                Bars.Add(bar);
            } else {
                foreach (var b in Bars.Skip(indexBefore)) {
                    ++b.Index;
                }
                Bars.Insert(indexBefore, bar);
            }
            return bar;
        }

        public Bar[] AddBars(int startIndex, int count) {
            return AddBars(startIndex, count, null);
        }

        public Bar[] AddBars(int startIndex, int count, BarParams barParams) {
            var bars = new Bar[count];
            for (var i = 0; i < count; ++i) {
                bars[i] = new Bar(this, startIndex + i) {
                    Params = barParams
                };
            }
            if (startIndex == Bars.Count - 1) {
                Bars.AddRange(bars);
            } else {
                foreach (var b in Bars.Skip(startIndex - 1)) {
                    ++b.Index;
                }
                Bars.InsertRange(startIndex, bars);
            }
            return bars;
        }

        public bool RemoveBarAt(int index) {
            if (index < 0 || index >= Bars.Count) {
                return false;
            }
            return RemoveBar(Bars[index]);
        }

        public bool RemoveBar(Bar bar) {
            var bars = Bars;
            if (!bars.Contains(bar)) {
                return false;
            }
            var index = bars.IndexOf(bar);
            foreach (var note in bar.Notes) {
                Notes.Remove(note);
            }
            bars.Remove(bar);
            for (var i = index; i < bars.Count; ++i) {
                --bars[i].Index;
            }
            return true;
        }

        public bool HasAnyNote => Notes.Count > 0;

        public InternalList<Note> Notes { get; }

        [JsonConstructor]
        internal Score(Project project, Difficulty difficulty) {
            Bars = new InternalList<Bar>();
            Project = project;
            Difficulty = difficulty;
            Notes = new InternalList<Note>();
            _flickGroupIDGenerator = new IntegerIDGenerator(1);
        }

        internal void ResolveReferences(Project project) {
            if (Bars == null) {
                return;
            }
            Project = project;
            foreach (var bar in Bars) {
                foreach (var note in bar.Notes) {
                    note.Bar = bar;
                }<commit_msg>[director] Added stub for score validation.<commit_after>﻿using System;
using System.Linq;
using DereTore.Applications.StarlightDirector.Components;
using DereTore.Applications.StarlightDirector.Extensions;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;

namespace DereTore.Applications.StarlightDirector.Entities {
    [JsonObject(NamingStrategyType = typeof(CamelCaseNamingStrategy), MemberSerialization = MemberSerialization.OptIn)]
    public sealed class Score {

        [JsonProperty]
        public InternalList<Bar> Bars { get; }

        public Project Project { get; internal set; }

        public Difficulty Difficulty { get; internal set; }

        public Bar AddBar() {
            return InsertBar(Bars.Count);
        }

        public Bar InsertBar(int indexBefore) {
            return InsertBar(indexBefore, null);
        }

        public Bar InsertBar(int indexBefore, BarParams barParams) {
            var bar = new Bar(this, indexBefore) {
                Params = barParams
            };
            if (indexBefore == Bars.Count) {
                Bars.Add(bar);
            } else {
                foreach (var b in Bars.Skip(indexBefore)) {
                    ++b.Index;
                }
                Bars.Insert(indexBefore, bar);
            }
            return bar;
        }

        public Bar[] AddBars(int startIndex, int count) {
            return AddBars(startIndex, count, null);
        }

        public Bar[] AddBars(int startIndex, int count, BarParams barParams) {
            var bars = new Bar[count];
            for (var i = 0; i < count; ++i) {
                bars[i] = new Bar(this, startIndex + i) {
                    Params = barParams
                };
            }
            if (startIndex == Bars.Count - 1) {
                Bars.AddRange(bars);
            } else {
                foreach (var b in Bars.Skip(startIndex - 1)) {
                    ++b.Index;
                }
                Bars.InsertRange(startIndex, bars);
            }
            return bars;
        }

        public bool RemoveBarAt(int index) {
            if (index < 0 || index >= Bars.Count) {
                return false;
            }
            return RemoveBar(Bars[index]);
        }

        public bool RemoveBar(Bar bar) {
            var bars = Bars;
            if (!bars.Contains(bar)) {
                return false;
            }
            var index = bars.IndexOf(bar);
            foreach (var note in bar.Notes) {
                Notes.Remove(note);
            }
            bars.Remove(bar);
            for (var i = index; i < bars.Count; ++i) {
                --bars[i].Index;
            }
            return true;
        }

        public bool HasAnyNote => Notes.Count > 0;

        public InternalList<Note> Notes { get; }

        public bool Validate(out string[] problems) {
            // Rules:
            // 1. [error] Hold lines do not cross on other notes;
            // 2. [warning] Two notes on the same grid line have no sync relation;
            // 3. [warning] Flick group contains only one flick note.
            throw new NotImplementedException();
        }

        public bool Validate() {
            string[] dummy;
            return Validate(out dummy);
        }

        [JsonConstructor]
        internal Score(Project project, Difficulty difficulty) {
            Bars = new InternalList<Bar>();
            Project = project;
            Difficulty = difficulty;
            Notes = new InternalList<Note>();
            _flickGroupIDGenerator = new IntegerIDGenerator(1);
        }

        internal void ResolveReferences(Project project) {
            if (Bars == null) {
                return;
            }
            Project = project;
            foreach (var bar in Bars) {
                foreach (var note in bar.Notes) {
                    note.Bar = bar;
                }
{'fraction_non_alphanumeric': 0.09226149856694418, 'fraction_numerical': 0.002047222601337519, 'mean_word_length': 1.460711887172599, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7246608', 'n_tokens_mistral': 1954, 'n_tokens_neox': 1831, 'n_words': 504}