/// <summary>
            /// call to create chunks from the game script
            /// </summary>
            /// <param name="allLinesMetaInfo"></param>
            public static List <ScriptTextChunk> GetChunks(List <LineMetaInfo> allLinesMetaInfo)
            {
                ScriptTextChunk currentChunk = new ScriptTextChunk();

                List <ScriptTextChunk> allScriptChunks = new List <ScriptTextChunk>();

                foreach (LineMetaInfo metaInfo in allLinesMetaInfo)
                {
                    switch (metaInfo.lineType)
                    {
                    case LineType.Japanese:
                        currentChunk.AddJapaneseMeta(metaInfo);
                        break;

                    case LineType.English:
                        currentChunk.AddEnglishMeta(metaInfo);
                        break;

                    case LineType.Other:
                        if (!currentChunk.Empty())
                        {
                            //if see any other type of line, end the chunk
                            allScriptChunks.Add(currentChunk);
                            currentChunk = new ScriptTextChunk();
                        }
                        break;

                    case LineType.CommentOrBlank:
                        //ignore comment or blank lines
                        break;

                    default:
                        throw new Exception("Unknown metaInfo type in GetChunks() of ScriptTextChunker");
                    }
                }

                return(allScriptChunks);
            }
        /// <summary>
        /// Call to copy the 'voicedelay' and 'voicewait' commands from the english lines into the japanese lines.
        /// NOTE: there are only 13 voicewait comamnds in the script, and they are outside the langen/langjp markers, so they will occur for both languages automatically.
        /// </summary>
        /// <param name="allScriptLines"></param>
        public static void FixVoiceDelaysInScript(List <string> allScriptLines, Logger logger, bool logNoOldDelay, bool logSuccessfulInsertions)
        {
            //for each line, generate a linemetainfo object.
            List <LineMetaInfo> allLinesMetaInfo = LineMetaInfo.GetLineMetaInfoFromRawLines(allScriptLines);

            //feed into chunker to chunk together japanese and english lines
            List <ScriptTextChunk> allChunks = ScriptTextChunk.GetChunks(allLinesMetaInfo);

            foreach (ScriptTextChunk chunk in allChunks)
            {
                List <string> voiceDelayStrings = GenerateMatchesFromMetaInfos(chunk.englishMetas, VOICE_WAIT_REGEX, out bool gotAtLeastOneVoiceDelay);

                //exit here if no voice delays were found
                if (!gotAtLeastOneVoiceDelay)
                {
                    continue;
                }

                //verify number of japanese and english lines are the same.
                if (!chunk.NumJapaneseAndEnglishLinesEqual())
                {
                    logger.Error($"Chunk has unequal lines. Tried to fix anyway\n{chunk.ToString()}\n");
                }

                //identify any delay types (!d100, !w100, delay, wait, etc) already existing on japanese lines. If more than one on a line, log error (or just error out)
                List <string> oldDelayStrings = GenerateMatchesFromMetaInfos(chunk.japaneseMetas, OLD_DELAY_REGEX, out bool gotAtLeastOneOldDelayRegex);

                //check that the japanese line's delays match the english delays
                bool japaneseAndEnglishDontMatch = false;
                for (int i = 0; (i < voiceDelayStrings.Count) && (i < oldDelayStrings.Count); i++)
                {
                    bool voiceDelayNull = voiceDelayStrings[i] == null;
                    bool oldDelayNull   = oldDelayStrings[i] == null;

                    if (voiceDelayNull && !oldDelayNull || !voiceDelayNull && oldDelayNull)
                    {
                        japaneseAndEnglishDontMatch = true;
                        break;
                    }
                }

                if (japaneseAndEnglishDontMatch && logNoOldDelay)
                {
                    logger.Warning($"WARNING: Japanese !d dont match English voiceDelay\n");
                }

                //remove the existing delays (replace?) on correspondiing japanese lines, and replace with english delays.
                for (int i = 0; (i < chunk.englishMetas.Count) && (i < chunk.japaneseMetas.Count); i++)
                {
                    //skip lines without voicedelay on them
                    if (voiceDelayStrings[i] == null)
                    {
                        continue;
                    }

                    //get the corresponding japanese line metainfo
                    LineMetaInfo japaneseMetaInfo = chunk.japaneseMetas[i];

                    string workingString = japaneseMetaInfo.Get();

                    //remove any !d100 etc. on the line, if it exists
                    workingString = OLD_DELAY_REGEX.Replace(workingString, "");
                    //replace 'langjp' with 'langjp:voicedelay [delayAmount]:' exactly once
                    workingString = LANGJP_REGEX.Replace(workingString, $"langjp:{voiceDelayStrings[i]}:", count: 1);
                    //collapse multiple colons ':::' on the line
                    workingString = MULTI_COLON_REGEX.Replace(workingString, ":");

                    //replace the string in the 'allLines' list
                    japaneseMetaInfo.Set(workingString);
                }

                if (logSuccessfulInsertions)
                {
                    logger.Information($"Succesfully converted chunk:\n{chunk.ToString()}\n");
                }
            }
        }