# MlxWriter
# Written by Will Zaylor, explanations added by Connor Lough


def MlxWriter(sourceFileName, targetFileName, maxValue):
    """
    This function reads the source mlx file, and it substitutes the desired values into a new mlx file.

    This function will read the source file, and call "helper functions" to modify the file.
    Each helper function will be written to modify specific lines from the source file.
    This framework is being used because other functions can be written to call (or not call) different sets of helper
    functions to make different types of mlx files.

    :param sourceFileName: string, The file name of the mlx file that will be modified
    :param targetFileName: string, The file name of the mlx file that is being written
    :param maxValue: float, maximum voxel side length/ max distance, specific to .stl file
    :return: None
    """

    # Open and read the source file. Define the contents of the file as a list of strings with the 'readlines' function.
    # Each entry in the list is one line from the file.
    with open(sourceFileName, mode='r') as fl:
        lines = fl.readlines()

    # Modify the max value of the RichAbsPerc parameter from the source mlx file
    lines = _modifyRichAbsPercParam(lines, maxVal=maxValue)

    # Write the modified lines to the target file
    with open(targetFileName, mode='w') as fl:
        fl.writelines(lines)
    return


def _modifyRichAbsPercParam(lines, value=0.5, minVal=0.0, maxVal=200.0):
    """
    This helper function finds the RichAbsPerc line in the given lines.

    This function will search for '<Param type="RichAbsPerc"' in the lines.
    If '<Param type="RichAbsPerc"' is found in a line, then the value, min and max values will be modified with the
    given values.
    If this is not found, then this function will throw an error

    :param lines: list, A list of strings. It is assumed that this list of strings
    :param value: float, default 0.5, The desired value that will be written after the 'value=' part of <Param type="RichAbsPerc" value="0.5" min="0" name="voxSize" max="200.00"/>
    :param minVal: float, default 0.0, The desired value that will be written after the 'min=' part of <Param type="RichAbsPerc" value="0.5" min="0" name="voxSize" max="200.00"/>
    :param maxVal: float, default 200.0, The desired value that will be written after the 'max=' part of <Param type="RichAbsPerc" value="0.5" min="0" name="voxSize" max="200.00"/>
    :return: list, The list that was input with a modified <Param type="RichAbsPerc"... line
    """

    # Iterate over every entry the given list.
    for i in range(len(lines)):
        # If '<Param type="RichAbsPerc"' is in the line, assume that this is the line that is being modified.
        if '<Param type="RichAbsPerc"' in lines[i]:
            lines[i] = '  <Param type="RichAbsPerc" value="{}" min="{}" name="voxSize" max="{}"/>\n'.format(value, minVal, maxVal)
            # return lines because we have modified the one line that we want to modify. This will break the loop
            return lines

    # If we have iterated over all of the lines and not found the desired line, throw a value error
    raise ValueError('the _modifyRichAbsPercParam did not find <Param type="RichAbsPerc" in the input "lines"')
    return


def _test():
    MlxWriter('MeshLab_FBB_Smooth_1.mlx', 'test.mlx', 4)
    return

if __name__ == '__main__':
    _test()