if False:

    #%%

    options = SuspiciousDetectionOptions()
    options.bRenderHtml = False
    options.imageBase = r'd:\wildlife_data\tigerblobs'
    options.outputBase = r'd:\temp\suspiciousDetections'

    options.debugMaxDir = -1
    options.debugMaxRenderDir = -1
    options.debugMaxRenderDetection = -1
    options.debugMaxRenderInstance = -1

    inputCsvFilename = r'D:\temp\tigers_20190308_all_output.csv'
    outputCsvFilename = matlab_porting_tools.insert_before_extension(
        inputCsvFilename, 'filtered')

    suspiciousDetectionResults = findSuspiciousDetections(
        inputCsvFilename, outputCsvFilename, options)

#%% Command-line driver


# Copy all fields from a Namespace (i.e., the output from parse_args) to an object.
#
# Skips fields starting with _.  Does not check existence in the target object.
def argsToObject(args, obj):

    for n, v in inspect.getmembers(args):
        if not n.startswith('_'):
            # print('Setting {} to {}'.format(n,v))
def write_html_image_list(filename=None, images=None, options={}):

    # returns an options struct

    if 'fHtml' not in options:
        options['fHtml'] = -1

    if 'makeRelative' not in options:
        options['makeRelative'] = 0

    if 'headerHtml' not in options:
        options['headerHtml'] = ''

    if 'trailerHtml' not in options:
        options['trailerHtml'] = ''

    if 'defaultTextStyle' not in options:
        options['defaultTextStyle'] = \
        "font-family:calibri,verdana,arial;font-weight:bold;font-size:150%;text-align:left;margin:0px;"

    if 'defaultImageStyle' not in options:
        options['defaultImageStyle'] = \
        "margin:0px;margin-top:5px;margin-bottom:5px;"

    # Possibly split the html output for figures into multiple files; Chrome gets sad with
    # thousands of images in a single tab.
    if 'maxFiguresPerHtmlFile' not in options:
        options['maxFiguresPerHtmlFile'] = math.inf

    if filename == None:
        return options

    # images may be a list of images or a list of image/style/title dictionaries,
    # enforce that it's the latter to simplify downstream code
    for iImage, imageInfo in enumerate(images):
        if isinstance(imageInfo, str):
            imageInfo = {
                'filename': imageInfo,
                'imageStyle': '',
                'title': '',
                'textStyle': ''
            }
        if 'filename' not in imageInfo:
            imageInfo['filename'] = ''
        if 'imageStyle' not in imageInfo:
            imageInfo['imageStyle'] = options['defaultImageStyle']
        if 'title' not in imageInfo:
            imageInfo['title'] = ''
        if 'textStyle' not in imageInfo:
            textStyle = options['defaultTextStyle']
            imageInfo['textStyle'] = options['defaultTextStyle']
        images[iImage] = imageInfo

    # Remove leading directory information from filenames if requested
    if options['makeRelative'] == 1:

        for iImage in range(0, len(images)):
            _, n, e = mpt.fileparts(images[iImage]['filename'])
            images[iImage]['filename'] = n + e

    elif options['makeRelative'] == 2:

        baseDir, _, _ = mpt.fileparts(filename)
        if len(baseDir) > 1 and baseDir[-1] != '\\':
            baseDir = baseDir + '\\'

        for iImage in range(0, len(images)):
            fn = images[iImage]['filename']
            fn = fn.replace(baseDir, '')
            images[iImage]['filename'] = fn

    nImages = len(images)

    # If we need to break this up into multiple files...
    if nImages > options['maxFiguresPerHtmlFile']:

        # You can't supply your own file handle in this case
        if options['fHtml'] != -1:
            raise ValueError(
                'You can'
                't supply your own file handle if we have to page the image set'
            )

        figureFileStartingIndices = list(
            range(0, nImages, options['maxFiguresPerHtmlFile']))

        assert len(figureFileStartingIndices) > 1

        # Open the meta-output file
        fMeta = open(filename, 'w')

        # Write header stuff
        fMeta.write('<html><body>\n')
        fMeta.write(options['headerHtml'])
        fMeta.write('<table border = 0 cellpadding = 2>\n')

        for startingIndex in figureFileStartingIndices:

            iStart = startingIndex
            iEnd = startingIndex + options['maxFiguresPerHtmlFile'] - 1
            if iEnd >= nImages:
                iEnd = nImages - 1

            trailer = 'image_{:05d}_{:05d}'.format(iStart, iEnd)
            localFiguresHtmlFilename = mpt.insert_before_extension(
                filename, trailer)
            fMeta.write('<tr><td>\n')
            fMeta.write(
                '<p style="padding-bottom:0px;margin-bottom:0px;text-align:left;font-family:'
                'segoe ui'
                ',calibri,arial;font-size:100%;text-decoration:none;font-weight:bold;">'
            )
            fMeta.write(
                '<a href="{}">Figures for images {} through {}</a></p></td></tr>\n'
                .format(localFiguresHtmlFilename, iStart, iEnd))

            localImages = images[iStart:iEnd + 1]

            localOptions = options.copy()
            localOptions['headerHtml'] = ''
            localOptions['trailerHtml'] = ''

            # Make a recursive call for this image set
            write_html_image_list(localFiguresHtmlFilename, localImages,
                                  localOptions)

        # ...for each page of images

        fMeta.write('</table></body>\n')
        fMeta.write(options['trailerHtml'])
        fMeta.write('</html>\n')
        fMeta.close()

        return options

    # ...if we have to make multiple sub-pages

    bCleanupFile = False

    if options['fHtml'] == -1:
        bCleanupFile = True
        fHtml = open(filename, 'w')
    else:
        fHtml = options['fHtml']

    fHtml.write('<html><body>\n')

    fHtml.write(options['headerHtml'])

    # Write out images
    for iImage, image in enumerate(images):

        title = image['title']
        imageStyle = image['imageStyle']
        textStyle = image['textStyle']
        filename = image['filename']

        # Remove unicode characters
        title = title.encode('ascii', 'ignore').decode('ascii')
        filename = filename.encode('ascii', 'ignore').decode('ascii')

        if len(title) > 0:
            fHtml.write(
                    '<p style="{}">{}</p>\n'\
                    .format(textStyle,title))

        fHtml.write('<img src="{}" style="{}">\n'.format(filename, imageStyle))

        if iImage != len(images) - 1:
            fHtml.write('<br/>')

    # ...for each image we need to write

    fHtml.write(options['trailerHtml'])

    fHtml.write('</body></html>\n')

    if bCleanupFile:
        fHtml.close()
    
    # Write output  
    # write_api_results(detectionResults,outputFilename)
    detectionResults.to_csv(outputFilename,index=False,quoting=csv.QUOTE_MINIMAL)
        
    return detectionResults


#%% Interactive driver
                
if False:

    #%%   
    
    inputFilename = r"D:\temp\demo_images\snapshot_serengeti\detections.csv"
    outputFilename = mpt.insert_before_extension(inputFilename,'for_timelapse')
    
    options = TimelapsePrepOptions()
    options.prepend = ''
    options.replacement = 'snapshot_serengeti'
    options.query = r'd:\temp\demo_images\snapshot_serengeti'
    options.nRows = None 
    options.removeClassLabel = True
        
    detectionResults = prepare_api_output_for_timelapse(inputFilename,outputFilename,options)
    print('Done, found {} matches'.format(len(detectionResults)))

    
#%% Command-line driver (** outdated **)

import argparse