#!/usr/bin/python

import numpy as np
import scipy.misc
import sys, os

def even_list(array):
    return array[:len(array)/2*2]

def even_frame(frame):
    for axis, length in enumerate(frame.shape):
        if length % 2:
            frame = np.delete(frame, -1, axis)
    return frame

def frame_path(tmpdir, prefix, kind, num):
    return os.path.join(tmpdir, '%s.%s.%05i.png' % (prefix, kind, num))

def save_frame(frame, tmpdir, prefix, kind, num):
    scipy.misc.toimage(frame, cmin=0, cmax=255).save(frame_path(tmpdir, prefix, kind, num))

def load_frame(tmpdir, prefix, kind, num):
    return scipy.misc.imread(frame_path(tmpdir, prefix, kind, num), flatten=True)


if __name__ == "__main__":

    # This would work well as a class.

    prefix = sys.argv[1]
    tmpdir = sys.argv[2]
    fnames = even_list(sys.argv[3:])

    # h264 can only handle even dimensions.

    # It's much simpler to load up the entire movie at once, but that
    # quickly leads to out-of-memory crashes.
    # Our solution here leads to extreme slowness as a result
    # of pathological file open/close behaviour.  The number of file
    # open/close operations is approx num_frames * (width + height),
    # e.g. 24 frames/sec * 10 sec * (480 + 360) = 201,600 file
    # opens and closes for a single movie.

    # For the first frame, a brand new single-row (or col)
    # image is written for the time-swapped views.

    count = 0
    print "frame", count
    first_frame = even_frame(scipy.misc.imread(fnames[0], flatten=True))
    save_frame(first_frame, tmpdir, prefix, 'noswap', count)
    count += 1

    for y in range(first_frame.shape[0]):
        row = first_frame[y:y+1,:]
        save_frame(row, tmpdir, prefix, 'y.swap', y)

    for x in range(first_frame.shape[1]):
        col = first_frame[:,x:x+1]
        save_frame(col, tmpdir, prefix, 'x.swap', x)

    # For subsequent frames, the previous time-swapped
    # view is loaded and appended to.

    for fname in fnames[1:]:
        print "frame", count
        frame = even_frame(scipy.misc.imread(fname, flatten=True))
        save_frame(frame, tmpdir, prefix, 'noswap', count)
        count += 1
        for y in range(frame.shape[0]):
            existing = load_frame(tmpdir, prefix, 'y.swap', y)
            new = np.zeros((existing.shape[0] + 1, existing.shape[1]), int)
            new[:-1,:] = existing
            new[-1:,:] = frame[y:y+1,:]
            save_frame(new, tmpdir, prefix, 'y.swap', y)
        for x in range(frame.shape[1]):
            existing = load_frame(tmpdir, prefix, 'x.swap', x)
            new = np.zeros((existing.shape[0], existing.shape[1] + 1), int)
            new[:,:-1] = existing
            new[:,-1:] = frame[:,x:x+1]
            save_frame(new, tmpdir, prefix, 'x.swap', x)