<commit_before>"""
Provides the Configuration object for creating and modifying
configuration files for the Project CARS Replay Enhancer.
"""

from collections import OrderedDict
import csv
import re
import os
import json
from os.path import commonprefix
from glob import glob
from natsort import natsorted
from struct import unpack

import moviepy.editor as mpy
from tqdm import tqdm

class Configuration:
    """
    Creates a Configuration that is written to a JSON file for the
    Project CARS Replay Enhancer
    """

    def __init__(self, previous_file=None):
        self.font = None
        self.heading_font = None
        self.heading_color = None

        self.backdrop = None
        self.logo = None
        self.logo_height = None
        self.logo_width = None
        self.series_logo = None

        self.show_champion = None

        self.heading_text = None
        self.subheading_text = None

        self.margin = None
        self.column_margin = None

        self.source_video = None
        self.source_telemetry = None
        self.telemetry_file = None
        self.output_video = None

        self.car_data = None
        self.team_data = None
        self.points = None

        self.point_structure = None

        self.video_threshold = None
        self.video_gaptime = None
        self.video_skipstart = None
        self.video_skipend = None
        self.video_cache = None

        self.sync_racestart = None

        self.participant_config = None

        self.previous_file = previous_file
        if previous_file:
            self.config_file = os.path.realpath(previous_file)
            self.__load_configuration(previous_file)

    def new_configuration(self):
        previous_file = self.previous_file

        print("Beginning configuration. Press CTRL+C at any time to",
            "abort.")

        try:
            self.sync_racestart = 0.0

            while True:
                print("Enter destination file for configuration.")
                print(".json file extension will be added ",
                    "automatically.")
                print("CAUTION: Existing file contents will be ",
                    "overwritten.")
                prompt = "({})".format(self.config_file) \
                    if previous_file else ""
                config_file = input(prompt+"--> ")

                if len(config_file) == 0 and previous_file:
                    break
                elif os.path.isdir(os.path.split(
                        os.path.realpath(config_file))[0]):
                    self.config_file = config_file+".json"
                    break
                else:
                    print("Configuration file location invalid. ",
                        "Please try again.")
                    print("Directories must be created before ",
                        "running script.")

            while True:
                print("Enter source video file.")
                prompt = "({})".format(self.source_video) \
                    if previous_file else ""
                source_video = input(prompt+"--> ")

                if len(source_video) == 0 and previous_file:
                    break
                elif os.path.isfile(os.path.realpath(source_video)):
                    self.source_video = source_video
                    break
                else:
                    print("Not a file. Please try again.")

            while True:
                print("Enter source telemetry directory.")
                prompt = "({})".format(self.source_telemetry) \
                    if previous_file else ""
                source_telemetry = input(prompt+"--> ")

                if len(source_telemetry) == 0 and previous_file:
                    break
                elif os.path.isdir(os.path.realpath(source_telemetry)):
                    if source_telemetry[-1] != os.sep:
                        self.source_telemetry = source_telemetry+os.sep
                    else:
                        self.source_telemetry = source_telemetry
                    break
                else:
                    print("Not a directory. Please try again.")

            while True:
                print("Enter output video file.")
                prompt = "({})".format(self.output_video) \
                    if previous_file else ""
                output_video = input(prompt+"--> ")

                if len(output_video) == 0 and previous_file:
                    break;
                elif os.path.isdir(os.path.split(
                        os.path.realpath(output_video))[0]):
                    self.output_video = output_video
                    break
                else:
                    print("Configuration file location invalid. ",
                        "Please try again.")
                    print("Directories must be created before ",
                        "running script.")

            while True:
                print("Enter path to font.")
                prompt = "({})".format(self.font) \
                    if previous_file else ""
                font = input(prompt+"--> ")

                if len(font) == 0 and previous_file:
                    break
                elif os.path.isfile(os.path.realpath(font)):
                    self.font = font
                    break
                else:
                    print("Not a file. Please try again.")

            while True:
                print("Enter size of font.")
                prompt = "({})".format(self.font_size) \
                    if previous_file else "15"
                font_size = input(prompt+"--> ")

                if len(font_size) == 0 and previous_file:
                    break
                elif len(font_size) == 0:
                    self.font_size = 15
                    break
                elif len(font_size) != 0:
                    try:
                        self.font_size = int(font_size)
                    except ValueError:
                        print("Font size should be an integer value.")
                    else:
                        break

            while True:
                print("Enter path to heading font.")
                prompt = "({})".format(self.heading_font) \
                    if previous_file else ""
                heading_font = input(prompt+"--> ")

                if len(heading_font) == 0 and previous_file:
                    break
                elif os.path.isfile(os.path.realpath(heading_font)):
                    self.heading_font = heading_font
                    break
                else:
                    print("Not a file. Please try again.")

            while True:
                print("Enter size of heading font.")
                prompt = "({})".format(self.heading_font_size) \
                    if previous_file else str(int(self.font_size/0.75))
                heading_font_size = input(prompt+"--> ")

                if len(heading_font_size) == 0 and previous_file:
                    break
                elif len(heading_font_size) == 0:
                    self.heading_font_size = int(self.font_size/0.75)
                    break
                elif len(heading_font_size) != 0:
                    try:
                        self.heading_font_size = int(heading_font_size)
                    except ValueError:
                        print("Heading font size should be an integer ",
                            "value.")
                    else:
                        break

            while True:
                print("Enter margin width.")
                prompt = "({})".format(self.margin) \
                    if previous_file else str(self.heading_font_size)
                margin = input(prompt+"--> ")

                if len(margin) == 0 and previous_file:
                    break
                elif len(margin) == 0:
                    self.margin = self.heading_font_size
                    break
                elif len(margin) != 0:
                    try:
                        self.margin = int(margin)
                    except ValueError:
                        print("Margin width should be an integer value")
                    else:
                        break

            while True:
                print("Enter column margin width.")
                prompt = "({})".format(self.column_margin) \
                    if previous_file else str(int(self.margin/2))
                column_margin = input(prompt+"--> ")

                if len(column_margin) == 0 and previous_file:
                    break
                elif len(column_margin) == 0:
                    self.column_margin = int(self.margin/2)
                    break
                elif len(column_margin) != 0:
                    try:
                        self.column_margin = int(column_margin)
                    except ValueError:
                        print("Column margin width should be an integer ",
                            "value.")
                    else:
                        break

            purge_cache = False
            while True:
                print("Use blackframe detection to crop video?")
                print("Choose YES (default) to trim video based on ",
                    "fade-through-blacks present in most Project ",
                    "CARS replays.")
                print("Choose NO to manually enter, in seconds, the ",
                    "start and stop time of the video.")
                use_blackframe = input("[Y/n]--> ")
                if len(use_blackframe) == 0 or \
                        str.lower(use_blackframe) == 'y':
                    use_blackframe = True
                    break
                elif str.lower(use_blackframe) == 'n':
                    use_blackframe = False
                    break

            if use_blackframe:
                while True:
                    print("Enter blackframe detection threshold.")
                    print("This sets how dark the screen must be to ",
                        "be recognized as a fade.")
                    prompt = "({})".format(self.video_threshold) \
                        if previous_file else "1"
                    video_threshold = input(prompt+"--> ")

                    if len(video_threshold) == 0 and previous_file:
                        break;
                    elif len(video_threshold) == 0:
                        self.video_threshold = 1
                        purge_cache = True
                        break
                    elif len(video_threshold) != 0:
                        try:
                            self.video_threshold = int(video_threshold)
                            purge_cache = True
                        except ValueError:
                            print("Blackframe detection threshold should ",
                                "be an integer value.")
                        else:
                            break
                
                while True:
                    print("Enter blackframe gap time.")
                    print("This sets the minimum time between ",
                        "blackframes to be considered separate events")
                    prompt = "({})".format(self.video_gaptime) \
                        if previous_file else "1"
                    video_gaptime = input(prompt+"--> ")

                    if len(video_gaptime) == 0 and previous_file:
                        break;
                    elif len(video_gaptime) == 0:
                        self.video_gaptime = 1
                        purge_cache = True
                        break
                    elif len(video_gaptime):
                        try:
                            self.video_gaptime = int(video_gaptime)
                            purge_cache = True
                        except ValueError:
                            print("Blackframe gap time should be an ",
                                "integer value.")
                        else:
                            break

            while True:
                if use_blackframe:
                    print("Enter number of scenes to skip at the ",
                        "start of the video.")
                else:
                    print("Enter the start time of the video.")

                prompt = "({})".format(self.video_skipstart \
                    if previous_file else "1" if use_blackframe \
                                     else "0.0" )
                video_skipstart = input(prompt+"--> ")

                if len(video_skipstart) == 0 and previous_file:
                    break
                elif len(video_skipstart) == 0:
                    self.video_skipstart = 1 if use_blackframe else 0.0
                    purge_cache = True
                    break
                elif len(video_skipstart) != 0 and use_blackframe:
                    try:
                        self.video_skipstart = int(video_skipstart)
                        purge_cache = True
                        break
                    except ValueError:
                        print("Number of scenes to skip should be an ",
                            "integer value.")
                elif len(video_skipstart) != 0 and not use_blackframe:
                    try:
                        video_skipstart = float(video_skipstart)
                        if video_skipstart >= 0.0:
                            self.video_skipstart = float(video_skipstart)
                            purge_cache = True
                            break
                        else:
                            raise ValueError
                    except ValueError:
                        print("Start time should be greater than ",
                            "zero.")

            while True:
                if use_blackframe:
                    print("Enter number of scenes to skip at the ",
                        "end of the video.")
                else:
                    print("Enter the ending time of the video.")

                duration = mpy.VideoFileClip(self.source_video).duration
                prompt = "({})".format(self.video_skipend \
                    if previous_file else "1" if use_blackframe \
                                     else str(duration))
                video_skipend = input(prompt+"--> ")

                if len(video_skipend) == 0 and previous_file:
                    break
                elif len(video_skipend) == 0:
                    self.video_skipend = 1 if use_blackframe \
                        else duration
                    purge_cache = True
                    break
                elif len(video_skipend) != 0 and use_blackframe:
                    try:
                        self.video_skipend = int(video_skipend)
                        purge_cache = True
                        break
                    except ValueError:
                        print("Number of scenes to skip should be an ",
                            "integer value.")
                elif len(video_skipend) != 0 and not use_blackframe:
                    try:
                        video_skipend = float(video_skipend)
                        if video_skipend <= duration:
                            self.video_skipend = float(video_skipend)
                            purge_cache = True
                            break
                        else:
                            raise ValueError
                    except ValueError:
                        print("Start time should be less than the ",
                            "video duration of {}.".format(duration))

            while True:
                print("Enter file to use as a cache for video data.")
                prompt = "({})".format(self.video_cache \
                    if previous_file else "file.cache")
                video_cache = input(prompt+"--> ")

                if len(video_cache) == 0 and previous_file:
                    break
                elif os.path.isdir(os.path.realpath(video_cache)):
                    try:
                        if video_cache[-1] != os.sep:
                            video_cache += os.sep
                    except IndexError:
                        video_cache = os.path.realpath(os.curdir)+os.sep
                    video_cache += "file.cache"
                    self.video_cache = video_cache
                    purge_cache = True
                    break
                elif os.path.isdir(os.path.split(os.path.realpath(
                        video_cache))[0]):
                    self.video_cache = video_cache
                    purge_cache = True
                    break
                else:
                    print("Location invalid. Please try again.")
                    print("Directories must be created before ",
                        "running script.")

            #TODO: Move to module-specific configuration
            while True:
                print("Enter heading color.")
                print("Color should be enetered as three integers, ",
                    "separated by commas, representing Red, Green, ",
                    "and Blue values.")
                prompt = "({}, {}, {})".format(*self.heading_color) \
                    if previous_file else ""
                heading_color = input(prompt+"--> ")
                
                if len(heading_color) == 0 and previous_file:
                    break
                else:
                    try:
                        heading_color = [int(x)
                            for x in heading_color.split(',')]
                        if all([x >= 0 and x <= 255 \
                                for x in heading_color]):
                            self.heading_color = heading_color
                            break
                        else:
                            raise ValueError
                    except ValueError:
                        print("Invalid color value.")

            while True:
                print("Enter background for title and results ",
                    "screens.")
                print("Enter -1 for none.")
                prompt = "({})".format(self.backdrop) \
                    if previous_file else ""
                backdrop = input(prompt+"--> ")

                if len(backdrop) == 0 and previous_file:
                    break;
                elif backdrop == "-1":
                    self.backdrop = ""
                    break
                elif os.path.isfile(os.path.realpath(backdrop)):
                    self.backdrop = backdrop
                    break
                else:
                    print("Not a file. Please try again.")

            while True:
                print("Enter logo for title and results ",
                    "screens.")
                print("Enter -1 for none.")
                prompt = "({})".format(self.logo) \
                    if previous_file else ""
                logo = input(prompt+"--> ")

                if len(logo) == 0 and previous_file:
                    break
                elif logo == "-1":
                    self.logo = ""
                    break
                elif os.path.isfile(os.path.realpath(logo)):
                    self.logo = logo
                    break
                else:
                    print("Not a file. Please try again.")

            if len(self.logo):
                while True:
                    print("Enter height for logo.")
                    prompt = "({})".format(self.logo_height \
                        if previous_file else "150")
                    logo_height = input(prompt+"--> ")

                    if len(logo_height) == 0 and previous_file:
                        break
                    elif len(logo_height) == 0:
                        self.logo_height = 150
                        break
                    elif len(logo_height) != 0:
                        try:
                            self.logo_height = int(logo_height)
                        except ValueError:
                            print("Logo height should be an integer ",
                                "value.")
                        else:
                            break

                while True:
                    print("Enter width for logo.")
                    prompt = "({})".format(self.logo_width \
                        if previous_file else str(self.logo_height))
                    logo_width = input(prompt+"--> ")

                    if len(logo_width) == 0 and previous_file:
                        break
                    elif len(logo_width) == 0:
                        self.logo_width = self.logo_height
                        break
                    elif len(logo_width) != 0:
                        try:
                            self.logo_width = int(logo_width)
                        except ValueError:
                            print("Logo width should be an integer ",
                                "value.")
                        else:
                            break
            else:
                self.logo_height = 0
                self.logo_width = 0

            while True:
                print("Enter a series logo for title and results ",
                    "screens.")
                print("Enter -1 for none.")
                prompt = "({})".format(self.series_logo) \
                    if previous_file else ""
                series_logo = input(prompt+"--> ")

                if len(series_logo) == 0 and previous_file:
                    break
                elif series_logo == "-1":
                    self.series_logo = ""
                    break
                elif os.path.isfile(os.path.realpath(series_logo)):
                    self.series_logo = series_logo
                    break
                else:
                    print("Not a file. Please try again.")

            while True:
                print("Show series champion screen?")
                prompt = "[y/N]"
                show_champion = input(prompt+"--> ")

                if len(show_champion) == 0 or \
                     str.lower(show_champion) == 'n':
                    self.show_champion = False
                    break
                elif str.lower(show_champion) == 'y':
                    self.show_champion = True
                    break

            while True:
                print("Enter main heading text.")
                print("Enter -1 for none.")
                prompt = "({})".format(self.heading_text) \
                    if previous_file else ""
                heading_text = input(prompt+"--> ")

                if len(heading_text) == 0 and previous_file:
                    break
                elif heading_text == "-1":
                    self.heading_text = ""
                    break
                elif len(heading_text):
                    self.heading_text = heading_text
                    break

            while True:
                print("Enter subheading text.")
                print("Enter -1 for none.")
                prompt = "({})".format(self.subheading_text) \
                    if previous_file else ""
                subheading_text = input(prompt+"--> ")

                if len(subheading_text) == 0 and previous_file:
                    break
                elif subheading_text == "-1":
                    self.subheading_text = ""
                    break
                elif len(subheading_text):
                    self.subheading_text = subheading_text
                    break

            point_structure = list()
            while True:
                print("Enter bonus points for fastest lap.")
                prompt = "({})".format(str(self.point_structure[0]) \
                    if previous_file else "0")
                bonus_point = input(prompt+"--> ")

                if len(bonus_point) == 0 and previous_file:
                    point_structure.insert(0, 
                        int(self.point_structure[0]))
                    break
                elif len(bonus_point) == 0:
                    point_structure.insert(0, int(0))
                    break
                else:
                    try:
                        point_structure.insert(0, int(bonus_point))
                        break
                    except ValueError:
                        print("Points should be integer values.")

            while True:
                position = len(point_structure)
                print("Enter 0 to finish points structure.")
                if previous_file:
                    print("Enter -1 to use previous values for ",
                        "remianing positions.")
                print("Enter points scored for finish poisition ",
                    "{}".format(position))
                try:
                    prompt = "({})".format(str(
                        self.point_structure[position])) \
                        if previous_file else ""
                except IndexError:
                    prompt = ""

                new_point = input(prompt+"--> ")
                if new_point == "0":
                    break
                elif new_point == "-1" and previous_file:
                    point_structure = self.__finish_array(point_structure, self.point_structure)
                    break
                elif len(new_point) == 0 and previous_file:
                    try:
                        if self.point_structure[position] == 0:
                            break
                        else:
                            point_structure.insert(position,
                                int(self.point_structure[position]))
                    except IndexError:
                        print("No previous value for this position. ",
                            "Enter 0 to end points structure.")
                else:
                    try:
                        point_structure.insert(position, int(new_point))
                    except ValueError:
                        print("Points should be integer values.")
            self.point_structure = point_structure

            print("Parsing telemetry data for driver information.")
            print("Please wait...")

            self.__get_participants(self.source_telemetry, "tele.csv")

            last_car = None
            last_team = None
            last_points = None
            use_last_car = False
            use_last_team = False
            use_last_points = False

            while True:
                print("Include team data for drivers?")
                prompt = "[Y/n]"
                show_team = input(prompt+"--> ")

                if len(show_team) == 0 or \
                        str.lower(show_team) == 'y':
                    break
                elif str.lower(show_team) == 'n':
                    last_team = ""
                    use_last_team = True
                    break
            
            if not previous_file:
                self.participant_config = dict()

            for participant in self.participants:
                print("Entering data for {}.".format(participant))
                if not previous_file:
                    self.participant_config[participant] = {'display': None, 'car': None, 'team': None, 'points': None}

                while True:
                    print("Enter display name override for {}.".format(participant))
                    prompt = "({})".format(self.participant_config[participant]['display'] \
                        if previous_file else participant)
                    display_name = input(prompt+"--> ")

                    if len(display_name) == 0 and previous_file:
                        break
                    elif len(display_name) == 0:
                        self.participant_config[participant]['display'] = participant
                        break
                    else:
                        self.participant_config[participant]['display'] = display_name
                        break

                while True:
                    print("Enter abbreviated name override for {}.".format(participant))
                    print("(Used by some modules for space saving.)")
                    prompt = "({})".format(self.participant_config[participant]['short_display'] \
                        if previous_file else participant.split(" ")[0][0]+". "+participant.split(" ")[-1] if len(participant.split(" ")) > 1 else participant)
                    short_display_name = input(prompt+"--> ")

                    if len(short_display_name) == 0 and previous_file:
                        break
                    elif len(short_display_name) == 0:
                        self.participant_config[participant]['short_display'] = participant.split(" ")[0][0]+". "+participant.split(" ")[-1]
                        break
                    else:
                        self.participant_config[participant]['short_display'] = short_display_name
                        break

                if use_last_car:
                    self.participant_config[participant]['car'] = last_car
                else:
                    while True:
                        print("Enter car for {}.".format(participant))
                        if last_car:
                            print("Enter -1 to use {} for remaining drivers.".format(last_car))
                        prompt = "({})".format(self.participant_config[participant]['car'] \
                            if previous_file else last_car if last_car else "")
                        car = input(prompt+"--> ")

                        if len(car) == 0 and previous_file:
                            break
                        elif len(car) == 0 and last_car:
                            self.participant_config[participant]['car'] = last_car<commit_msg>Incorrect short name default assignment corrected.<commit_after>"""
Provides the Configuration object for creating and modifying
configuration files for the Project CARS Replay Enhancer.
"""

from collections import OrderedDict
import csv
import re
import os
import json
from os.path import commonprefix
from glob import glob
from natsort import natsorted
from struct import unpack

import moviepy.editor as mpy
from tqdm import tqdm

class Configuration:
    """
    Creates a Configuration that is written to a JSON file for the
    Project CARS Replay Enhancer
    """

    def __init__(self, previous_file=None):
        self.font = None
        self.heading_font = None
        self.heading_color = None

        self.backdrop = None
        self.logo = None
        self.logo_height = None
        self.logo_width = None
        self.series_logo = None

        self.show_champion = None

        self.heading_text = None
        self.subheading_text = None

        self.margin = None
        self.column_margin = None

        self.source_video = None
        self.source_telemetry = None
        self.telemetry_file = None
        self.output_video = None

        self.car_data = None
        self.team_data = None
        self.points = None

        self.point_structure = None

        self.video_threshold = None
        self.video_gaptime = None
        self.video_skipstart = None
        self.video_skipend = None
        self.video_cache = None

        self.sync_racestart = None

        self.participant_config = None

        self.previous_file = previous_file
        if previous_file:
            self.config_file = os.path.realpath(previous_file)
            self.__load_configuration(previous_file)

    def new_configuration(self):
        previous_file = self.previous_file

        print("Beginning configuration. Press CTRL+C at any time to",
            "abort.")

        try:
            self.sync_racestart = 0.0

            while True:
                print("Enter destination file for configuration.")
                print(".json file extension will be added ",
                    "automatically.")
                print("CAUTION: Existing file contents will be ",
                    "overwritten.")
                prompt = "({})".format(self.config_file) \
                    if previous_file else ""
                config_file = input(prompt+"--> ")

                if len(config_file) == 0 and previous_file:
                    break
                elif os.path.isdir(os.path.split(
                        os.path.realpath(config_file))[0]):
                    self.config_file = config_file+".json"
                    break
                else:
                    print("Configuration file location invalid. ",
                        "Please try again.")
                    print("Directories must be created before ",
                        "running script.")

            while True:
                print("Enter source video file.")
                prompt = "({})".format(self.source_video) \
                    if previous_file else ""
                source_video = input(prompt+"--> ")

                if len(source_video) == 0 and previous_file:
                    break
                elif os.path.isfile(os.path.realpath(source_video)):
                    self.source_video = source_video
                    break
                else:
                    print("Not a file. Please try again.")

            while True:
                print("Enter source telemetry directory.")
                prompt = "({})".format(self.source_telemetry) \
                    if previous_file else ""
                source_telemetry = input(prompt+"--> ")

                if len(source_telemetry) == 0 and previous_file:
                    break
                elif os.path.isdir(os.path.realpath(source_telemetry)):
                    if source_telemetry[-1] != os.sep:
                        self.source_telemetry = source_telemetry+os.sep
                    else:
                        self.source_telemetry = source_telemetry
                    break
                else:
                    print("Not a directory. Please try again.")

            while True:
                print("Enter output video file.")
                prompt = "({})".format(self.output_video) \
                    if previous_file else ""
                output_video = input(prompt+"--> ")

                if len(output_video) == 0 and previous_file:
                    break;
                elif os.path.isdir(os.path.split(
                        os.path.realpath(output_video))[0]):
                    self.output_video = output_video
                    break
                else:
                    print("Configuration file location invalid. ",
                        "Please try again.")
                    print("Directories must be created before ",
                        "running script.")

            while True:
                print("Enter path to font.")
                prompt = "({})".format(self.font) \
                    if previous_file else ""
                font = input(prompt+"--> ")

                if len(font) == 0 and previous_file:
                    break
                elif os.path.isfile(os.path.realpath(font)):
                    self.font = font
                    break
                else:
                    print("Not a file. Please try again.")

            while True:
                print("Enter size of font.")
                prompt = "({})".format(self.font_size) \
                    if previous_file else "15"
                font_size = input(prompt+"--> ")

                if len(font_size) == 0 and previous_file:
                    break
                elif len(font_size) == 0:
                    self.font_size = 15
                    break
                elif len(font_size) != 0:
                    try:
                        self.font_size = int(font_size)
                    except ValueError:
                        print("Font size should be an integer value.")
                    else:
                        break

            while True:
                print("Enter path to heading font.")
                prompt = "({})".format(self.heading_font) \
                    if previous_file else ""
                heading_font = input(prompt+"--> ")

                if len(heading_font) == 0 and previous_file:
                    break
                elif os.path.isfile(os.path.realpath(heading_font)):
                    self.heading_font = heading_font
                    break
                else:
                    print("Not a file. Please try again.")

            while True:
                print("Enter size of heading font.")
                prompt = "({})".format(self.heading_font_size) \
                    if previous_file else str(int(self.font_size/0.75))
                heading_font_size = input(prompt+"--> ")

                if len(heading_font_size) == 0 and previous_file:
                    break
                elif len(heading_font_size) == 0:
                    self.heading_font_size = int(self.font_size/0.75)
                    break
                elif len(heading_font_size) != 0:
                    try:
                        self.heading_font_size = int(heading_font_size)
                    except ValueError:
                        print("Heading font size should be an integer ",
                            "value.")
                    else:
                        break

            while True:
                print("Enter margin width.")
                prompt = "({})".format(self.margin) \
                    if previous_file else str(self.heading_font_size)
                margin = input(prompt+"--> ")

                if len(margin) == 0 and previous_file:
                    break
                elif len(margin) == 0:
                    self.margin = self.heading_font_size
                    break
                elif len(margin) != 0:
                    try:
                        self.margin = int(margin)
                    except ValueError:
                        print("Margin width should be an integer value")
                    else:
                        break

            while True:
                print("Enter column margin width.")
                prompt = "({})".format(self.column_margin) \
                    if previous_file else str(int(self.margin/2))
                column_margin = input(prompt+"--> ")

                if len(column_margin) == 0 and previous_file:
                    break
                elif len(column_margin) == 0:
                    self.column_margin = int(self.margin/2)
                    break
                elif len(column_margin) != 0:
                    try:
                        self.column_margin = int(column_margin)
                    except ValueError:
                        print("Column margin width should be an integer ",
                            "value.")
                    else:
                        break

            purge_cache = False
            while True:
                print("Use blackframe detection to crop video?")
                print("Choose YES (default) to trim video based on ",
                    "fade-through-blacks present in most Project ",
                    "CARS replays.")
                print("Choose NO to manually enter, in seconds, the ",
                    "start and stop time of the video.")
                use_blackframe = input("[Y/n]--> ")
                if len(use_blackframe) == 0 or \
                        str.lower(use_blackframe) == 'y':
                    use_blackframe = True
                    break
                elif str.lower(use_blackframe) == 'n':
                    use_blackframe = False
                    break

            if use_blackframe:
                while True:
                    print("Enter blackframe detection threshold.")
                    print("This sets how dark the screen must be to ",
                        "be recognized as a fade.")
                    prompt = "({})".format(self.video_threshold) \
                        if previous_file else "1"
                    video_threshold = input(prompt+"--> ")

                    if len(video_threshold) == 0 and previous_file:
                        break;
                    elif len(video_threshold) == 0:
                        self.video_threshold = 1
                        purge_cache = True
                        break
                    elif len(video_threshold) != 0:
                        try:
                            self.video_threshold = int(video_threshold)
                            purge_cache = True
                        except ValueError:
                            print("Blackframe detection threshold should ",
                                "be an integer value.")
                        else:
                            break
                
                while True:
                    print("Enter blackframe gap time.")
                    print("This sets the minimum time between ",
                        "blackframes to be considered separate events")
                    prompt = "({})".format(self.video_gaptime) \
                        if previous_file else "1"
                    video_gaptime = input(prompt+"--> ")

                    if len(video_gaptime) == 0 and previous_file:
                        break;
                    elif len(video_gaptime) == 0:
                        self.video_gaptime = 1
                        purge_cache = True
                        break
                    elif len(video_gaptime):
                        try:
                            self.video_gaptime = int(video_gaptime)
                            purge_cache = True
                        except ValueError:
                            print("Blackframe gap time should be an ",
                                "integer value.")
                        else:
                            break

            while True:
                if use_blackframe:
                    print("Enter number of scenes to skip at the ",
                        "start of the video.")
                else:
                    print("Enter the start time of the video.")

                prompt = "({})".format(self.video_skipstart \
                    if previous_file else "1" if use_blackframe \
                                     else "0.0" )
                video_skipstart = input(prompt+"--> ")

                if len(video_skipstart) == 0 and previous_file:
                    break
                elif len(video_skipstart) == 0:
                    self.video_skipstart = 1 if use_blackframe else 0.0
                    purge_cache = True
                    break
                elif len(video_skipstart) != 0 and use_blackframe:
                    try:
                        self.video_skipstart = int(video_skipstart)
                        purge_cache = True
                        break
                    except ValueError:
                        print("Number of scenes to skip should be an ",
                            "integer value.")
                elif len(video_skipstart) != 0 and not use_blackframe:
                    try:
                        video_skipstart = float(video_skipstart)
                        if video_skipstart >= 0.0:
                            self.video_skipstart = float(video_skipstart)
                            purge_cache = True
                            break
                        else:
                            raise ValueError
                    except ValueError:
                        print("Start time should be greater than ",
                            "zero.")

            while True:
                if use_blackframe:
                    print("Enter number of scenes to skip at the ",
                        "end of the video.")
                else:
                    print("Enter the ending time of the video.")

                duration = mpy.VideoFileClip(self.source_video).duration
                prompt = "({})".format(self.video_skipend \
                    if previous_file else "1" if use_blackframe \
                                     else str(duration))
                video_skipend = input(prompt+"--> ")

                if len(video_skipend) == 0 and previous_file:
                    break
                elif len(video_skipend) == 0:
                    self.video_skipend = 1 if use_blackframe \
                        else duration
                    purge_cache = True
                    break
                elif len(video_skipend) != 0 and use_blackframe:
                    try:
                        self.video_skipend = int(video_skipend)
                        purge_cache = True
                        break
                    except ValueError:
                        print("Number of scenes to skip should be an ",
                            "integer value.")
                elif len(video_skipend) != 0 and not use_blackframe:
                    try:
                        video_skipend = float(video_skipend)
                        if video_skipend <= duration:
                            self.video_skipend = float(video_skipend)
                            purge_cache = True
                            break
                        else:
                            raise ValueError
                    except ValueError:
                        print("Start time should be less than the ",
                            "video duration of {}.".format(duration))

            while True:
                print("Enter file to use as a cache for video data.")
                prompt = "({})".format(self.video_cache \
                    if previous_file else "file.cache")
                video_cache = input(prompt+"--> ")

                if len(video_cache) == 0 and previous_file:
                    break
                elif os.path.isdir(os.path.realpath(video_cache)):
                    try:
                        if video_cache[-1] != os.sep:
                            video_cache += os.sep
                    except IndexError:
                        video_cache = os.path.realpath(os.curdir)+os.sep
                    video_cache += "file.cache"
                    self.video_cache = video_cache
                    purge_cache = True
                    break
                elif os.path.isdir(os.path.split(os.path.realpath(
                        video_cache))[0]):
                    self.video_cache = video_cache
                    purge_cache = True
                    break
                else:
                    print("Location invalid. Please try again.")
                    print("Directories must be created before ",
                        "running script.")

            #TODO: Move to module-specific configuration
            while True:
                print("Enter heading color.")
                print("Color should be enetered as three integers, ",
                    "separated by commas, representing Red, Green, ",
                    "and Blue values.")
                prompt = "({}, {}, {})".format(*self.heading_color) \
                    if previous_file else ""
                heading_color = input(prompt+"--> ")
                
                if len(heading_color) == 0 and previous_file:
                    break
                else:
                    try:
                        heading_color = [int(x)
                            for x in heading_color.split(',')]
                        if all([x >= 0 and x <= 255 \
                                for x in heading_color]):
                            self.heading_color = heading_color
                            break
                        else:
                            raise ValueError
                    except ValueError:
                        print("Invalid color value.")

            while True:
                print("Enter background for title and results ",
                    "screens.")
                print("Enter -1 for none.")
                prompt = "({})".format(self.backdrop) \
                    if previous_file else ""
                backdrop = input(prompt+"--> ")

                if len(backdrop) == 0 and previous_file:
                    break;
                elif backdrop == "-1":
                    self.backdrop = ""
                    break
                elif os.path.isfile(os.path.realpath(backdrop)):
                    self.backdrop = backdrop
                    break
                else:
                    print("Not a file. Please try again.")

            while True:
                print("Enter logo for title and results ",
                    "screens.")
                print("Enter -1 for none.")
                prompt = "({})".format(self.logo) \
                    if previous_file else ""
                logo = input(prompt+"--> ")

                if len(logo) == 0 and previous_file:
                    break
                elif logo == "-1":
                    self.logo = ""
                    break
                elif os.path.isfile(os.path.realpath(logo)):
                    self.logo = logo
                    break
                else:
                    print("Not a file. Please try again.")

            if len(self.logo):
                while True:
                    print("Enter height for logo.")
                    prompt = "({})".format(self.logo_height \
                        if previous_file else "150")
                    logo_height = input(prompt+"--> ")

                    if len(logo_height) == 0 and previous_file:
                        break
                    elif len(logo_height) == 0:
                        self.logo_height = 150
                        break
                    elif len(logo_height) != 0:
                        try:
                            self.logo_height = int(logo_height)
                        except ValueError:
                            print("Logo height should be an integer ",
                                "value.")
                        else:
                            break

                while True:
                    print("Enter width for logo.")
                    prompt = "({})".format(self.logo_width \
                        if previous_file else str(self.logo_height))
                    logo_width = input(prompt+"--> ")

                    if len(logo_width) == 0 and previous_file:
                        break
                    elif len(logo_width) == 0:
                        self.logo_width = self.logo_height
                        break
                    elif len(logo_width) != 0:
                        try:
                            self.logo_width = int(logo_width)
                        except ValueError:
                            print("Logo width should be an integer ",
                                "value.")
                        else:
                            break
            else:
                self.logo_height = 0
                self.logo_width = 0

            while True:
                print("Enter a series logo for title and results ",
                    "screens.")
                print("Enter -1 for none.")
                prompt = "({})".format(self.series_logo) \
                    if previous_file else ""
                series_logo = input(prompt+"--> ")

                if len(series_logo) == 0 and previous_file:
                    break
                elif series_logo == "-1":
                    self.series_logo = ""
                    break
                elif os.path.isfile(os.path.realpath(series_logo)):
                    self.series_logo = series_logo
                    break
                else:
                    print("Not a file. Please try again.")

            while True:
                print("Show series champion screen?")
                prompt = "[y/N]"
                show_champion = input(prompt+"--> ")

                if len(show_champion) == 0 or \
                     str.lower(show_champion) == 'n':
                    self.show_champion = False
                    break
                elif str.lower(show_champion) == 'y':
                    self.show_champion = True
                    break

            while True:
                print("Enter main heading text.")
                print("Enter -1 for none.")
                prompt = "({})".format(self.heading_text) \
                    if previous_file else ""
                heading_text = input(prompt+"--> ")

                if len(heading_text) == 0 and previous_file:
                    break
                elif heading_text == "-1":
                    self.heading_text = ""
                    break
                elif len(heading_text):
                    self.heading_text = heading_text
                    break

            while True:
                print("Enter subheading text.")
                print("Enter -1 for none.")
                prompt = "({})".format(self.subheading_text) \
                    if previous_file else ""
                subheading_text = input(prompt+"--> ")

                if len(subheading_text) == 0 and previous_file:
                    break
                elif subheading_text == "-1":
                    self.subheading_text = ""
                    break
                elif len(subheading_text):
                    self.subheading_text = subheading_text
                    break

            point_structure = list()
            while True:
                print("Enter bonus points for fastest lap.")
                prompt = "({})".format(str(self.point_structure[0]) \
                    if previous_file else "0")
                bonus_point = input(prompt+"--> ")

                if len(bonus_point) == 0 and previous_file:
                    point_structure.insert(0, 
                        int(self.point_structure[0]))
                    break
                elif len(bonus_point) == 0:
                    point_structure.insert(0, int(0))
                    break
                else:
                    try:
                        point_structure.insert(0, int(bonus_point))
                        break
                    except ValueError:
                        print("Points should be integer values.")

            while True:
                position = len(point_structure)
                print("Enter 0 to finish points structure.")
                if previous_file:
                    print("Enter -1 to use previous values for ",
                        "remianing positions.")
                print("Enter points scored for finish poisition ",
                    "{}".format(position))
                try:
                    prompt = "({})".format(str(
                        self.point_structure[position])) \
                        if previous_file else ""
                except IndexError:
                    prompt = ""

                new_point = input(prompt+"--> ")
                if new_point == "0":
                    break
                elif new_point == "-1" and previous_file:
                    point_structure = self.__finish_array(point_structure, self.point_structure)
                    break
                elif len(new_point) == 0 and previous_file:
                    try:
                        if self.point_structure[position] == 0:
                            break
                        else:
                            point_structure.insert(position,
                                int(self.point_structure[position]))
                    except IndexError:
                        print("No previous value for this position. ",
                            "Enter 0 to end points structure.")
                else:
                    try:
                        point_structure.insert(position, int(new_point))
                    except ValueError:
                        print("Points should be integer values.")
            self.point_structure = point_structure

            print("Parsing telemetry data for driver information.")
            print("Please wait...")

            self.__get_participants(self.source_telemetry, "tele.csv")

            last_car = None
            last_team = None
            last_points = None
            use_last_car = False
            use_last_team = False
            use_last_points = False

            while True:
                print("Include team data for drivers?")
                prompt = "[Y/n]"
                show_team = input(prompt+"--> ")

                if len(show_team) == 0 or \
                        str.lower(show_team) == 'y':
                    break
                elif str.lower(show_team) == 'n':
                    last_team = ""
                    use_last_team = True
                    break
            
            if not previous_file:
                self.participant_config = dict()

            for participant in self.participants:
                print("Entering data for {}.".format(participant))
                if not previous_file:
                    self.participant_config[participant] = {'display': None, 'car': None, 'team': None, 'points': None}

                while True:
                    print("Enter display name override for {}.".format(participant))
                    prompt = "({})".format(self.participant_config[participant]['display'] \
                        if previous_file else participant)
                    display_name = input(prompt+"--> ")

                    if len(display_name) == 0 and previous_file:
                        break
                    elif len(display_name) == 0:
                        self.participant_config[participant]['display'] = participant
                        break
                    else:
                        self.participant_config[participant]['display'] = display_name
                        break

                while True:
                    print("Enter abbreviated name override for {}.".format(participant))
                    print("(Used by some modules for space saving.)")
                    prompt = "({})".format(self.participant_config[participant]['short_display'] \
                        if previous_file else participant.split(" ")[0][0]+". "+participant.split(" ")[-1] if len(participant.split(" ")) > 1 else participant)
                    short_display_name = input(prompt+"--> ")

                    if len(short_display_name) == 0 and previous_file:
                        break
                    elif len(short_display_name) == 0:
                        self.participant_config[participant]['short_display'] = participant.split(" ")[0][0]+". "+participant.split(" ")[-1] if len(participant.split(" ")) > 1 else participant
                        break
                    else:
                        self.participant_config[participant]['short_display'] = short_display_name
                        break

                if use_last_car:
                    self.participant_config[participant]['car'] = last_car
                else:
                    while True:
                        print("Enter car for {}.".format(participant))
                        if last_car:
                            print("Enter -1 to use {} for remaining drivers.".format(last_car))
                        prompt = "({})".format(self.participant_config[participant]['car'] \
                            if previous_file else last_car if last_car else "")
                        car = input(prompt+"--> ")

                        if len(car) == 0 and previous_file:
                            break
                        elif len(car) == 0 and last_car:
                            self.participant_config[participant]['car'] = last_car
{'fraction_non_alphanumeric': 0.08195084613208646, 'fraction_numerical': 0.004409537913706175, 'mean_word_length': 1.0354953429297207, 'pattern_counts': {'":': 12, '<': 7, '<?xml version=': 0, '>': 72, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3777073', 'n_tokens_mistral': 14307, 'n_tokens_neox': 12842, 'n_words': 3477}