#!/usr/bin/env python

from PIL import Image
import numpy as np
import os
import argparse


def parse():
    parser = argparse.ArgumentParser()

    parser.add_argument("-f", "--folder", default=".", help="The folder to load images from")
    parser.add_argument("-o", "--output", default="out.png", help="filename of the resulting image")
    parser.add_argument("-v", "--verbose", action="store_true", help="print more verbose output")
    parser.add_argument("-q", "--quiet", action="store_true", help="Silence all printed output")

    args = parser.parse_args()

    return vars(args)


def flush(args):
    if not args["verbose"] and not args["quiet"]:
        print("", flush=False)


def main():
    args = parse()

    matrices = []
    dimensions = None

    try:
        for item in os.listdir(args["folder"]):
            # We only care about the usual suspects, skip everything else.
            if not any(extention in item for extention in ["png", "jpg", "bmp"]):
                continue

            path = "{}/{}".format(args["folder"], item)

            im = Image.open(path)
            matrices.append(np.array(im).astype(np.uint64))

            # we cannot sum matrices of varying dimensions, this will break
            # us out as soon as we find a problem file
            if not dimensions:
                dimensions = matrices[-1].shape
            elif matrices[-1].shape != dimensions:
                flush(args)
                print("images must all be the same dimensions, and have the same bands E.G.(RGB, RGBA)")
                return

            if not args["quiet"]:
                if args["verbose"]:
                    print("loaded {}".format(path))
                else:
                    print('.', end="", flush=True)
    except TypeError:
        # If the user attempts to cancel the process, we'll jump out of the loop
        # and save the result
        pass

    # break out if there are no images, to avoid division by zero below
    if not len(matrices):
        print("no images found in {}".format(os.path.abspath(args["folder"])))
        return

    # The whole process is useless if there isnt at least two images, break out.
    if len(matrices) <= 1:
        print("not enough images to average")
        return

    flush(args)

    result = sum(matrices) / len(matrices)

    im = Image.fromarray(result.astype(np.uint8))

    if args["verbose"]:
        print("saving {}".format(args["output"]))

    im.save(args["output"])


if __name__ == "__main__":
    main()
