# Path: settings.py
# FLAGS = flags.FLAGS
# 
# Path: utils/video.py
# def compute_dense_optical_flow_for_batch(batch, pyr_scale=0.8, levels=15, winsize=5, iterations=10,
#                                poly_n=5, poly_sigma=1.5, flags=0):
#   """
#   Adds an additional (4th) channel containing the result of Farneback optical flow computation to the images in the
#   batch. Since optical flow generally requires motion (i.e. two images), the additional channel of the first
#   image is always zero (black).
# 
#   :param batch: numpy array with shape(1, encoder_length, height, width, num_channels)
#   :param pyr_scale: parameter, specifying the image scale (<1) to build pyramids for each image
#   :param levels: number of pyramid layers including the initial image
#   :param winsize: averaging window size
#   :param iterations: number of iterations the algorithm does at each pyramid level
#   :param poly_n: size of the pixel neighborhood used to find polynomial expansion in each pixel
#   :param poly_sigma: standard deviation of the Gaussian that is used to smooth derivatives used as a basis for the polynomial expansion
#   :param flags: operation flags, see above specification
#   :return: the provided batch with shape (1, encoder_length, height, width, num_channels+1)
#   """
#   assert batch.shape == (1, FLAGS.encoder_length, FLAGS.height, FLAGS.width, 3)
#   num_frames = batch.shape[1]
#   assert num_frames > 0
# 
#   flow_masks_shape = list(batch.shape)
#   flow_masks_shape[4] = 1
#   flow_masks = np.zeros(flow_masks_shape)
#   for i in range(num_frames):
#     # insert the first (black) flow image into new batch (image_prev == image)
#     if i == 0:
#       flow_masks[:, i, :, :,0] = np.zeros((1, FLAGS.height, FLAGS.width))
#     else:
#       image_prev = batch[0, i-1, :, :, :3].copy()
#       image = batch[0, i, :, :, :3].copy()
#       #frame_flow = compute_dense_optical_flow(image_prev, image, pyr_scale=pyr_scale, levels=levels, winsize=winsize,
#       #                                        iterations=iterations, poly_n=poly_n, poly_sigma=poly_sigma, flags=flags)
#       frame_flow = np.zeros((128, 128))
#       flow_masks[:,i,:,:,0] = np.expand_dims(frame_flow, axis=0)
# 
#   batch = np.concatenate((batch,flow_masks),axis=4)
#   return batch


import os
import tensorflow as tf
import re
import random
import datetime as dt
import moviepy.editor as mpy
import pandas as pd
import json
import matplotlib
import numpy as np
import seaborn as sn
import glob as glob
import cv2 as cv2
from tensorflow.python.platform import gfile
from matplotlib import pyplot as plt
from moviepy.editor import VideoFileClip
from PIL import Image
from settings import FLAGS
from .video import compute_dense_optical_flow_for_batch
  """ takes a folder with a gif file, creates sub directory named after the gif file and stores the single frames in it"""
  assert gif_file_path
  dir_name = os.path.basename(gif_file_path)
  new_dir = create_subfolder(os.path.dirname(gif_file_path), os.path.splitext(dir_name)[0])
  clip = mpy.VideoFileClip(gif_file_path).to_RGB()
  clip.write_images_sequence(os.path.join(new_dir, 'generated_clip_frame%03d.png'))


def frames_to_gif_in_dir_tree(root_dir):
  subdirs = get_subdirectory_files(root_dir, depth=2)
  for subdir in subdirs:
    convert_frames_to_gif(subdir, 'action', fps=20, image_type='.png')


def gif_to_frames_in_dir_tree(root_dir):
  subdirs = get_subdirectory_files(root_dir, depth=2)
  for subdir in subdirs:
    convert_gif_to_frames(subdir)


def generate_batch_from_dir(path, suffix="*.png"):
  '''
  :param path: directory path to images
  :param suffix: regex that specifies the file suffix (e.g. "*.png" or "*.jpg")
  :return: numpy array with shape (1, encoder_length, height, width, num_channels)
  '''
  assert os.path.isdir(path), str(path) + "doesn't seem to be a valid path"

  files = file_paths_from_directory(path, suffix)
  assert files and len(files)>0, 'Could not find an image with suffix %s in %s'%(path, suffix)

# Path: settings.py
# FLAGS = flags.FLAGS
# 
# Path: utils/video.py
# def compute_dense_optical_flow_for_batch(batch, pyr_scale=0.8, levels=15, winsize=5, iterations=10,
#                                poly_n=5, poly_sigma=1.5, flags=0):
#   """
#   Adds an additional (4th) channel containing the result of Farneback optical flow computation to the images in the
#   batch. Since optical flow generally requires motion (i.e. two images), the additional channel of the first
#   image is always zero (black).
# 
#   :param batch: numpy array with shape(1, encoder_length, height, width, num_channels)
#   :param pyr_scale: parameter, specifying the image scale (<1) to build pyramids for each image
#   :param levels: number of pyramid layers including the initial image
#   :param winsize: averaging window size
#   :param iterations: number of iterations the algorithm does at each pyramid level
#   :param poly_n: size of the pixel neighborhood used to find polynomial expansion in each pixel
#   :param poly_sigma: standard deviation of the Gaussian that is used to smooth derivatives used as a basis for the polynomial expansion
#   :param flags: operation flags, see above specification
#   :return: the provided batch with shape (1, encoder_length, height, width, num_channels+1)
#   """
#   assert batch.shape == (1, FLAGS.encoder_length, FLAGS.height, FLAGS.width, 3)
#   num_frames = batch.shape[1]
#   assert num_frames > 0
# 
#   flow_masks_shape = list(batch.shape)
#   flow_masks_shape[4] = 1
#   flow_masks = np.zeros(flow_masks_shape)
#   for i in range(num_frames):
#     # insert the first (black) flow image into new batch (image_prev == image)
#     if i == 0:
#       flow_masks[:, i, :, :,0] = np.zeros((1, FLAGS.height, FLAGS.width))
#     else:
#       image_prev = batch[0, i-1, :, :, :3].copy()
#       image = batch[0, i, :, :, :3].copy()
#       #frame_flow = compute_dense_optical_flow(image_prev, image, pyr_scale=pyr_scale, levels=levels, winsize=winsize,
#       #                                        iterations=iterations, poly_n=poly_n, poly_sigma=poly_sigma, flags=flags)
#       frame_flow = np.zeros((128, 128))
#       flow_masks[:,i,:,:,0] = np.expand_dims(frame_flow, axis=0)
# 
#   batch = np.concatenate((batch,flow_masks),axis=4)
#   return batch


# Path: utils/io_handler.py
import os
import tensorflow as tf
import re
import random
import datetime as dt
import moviepy.editor as mpy
import pandas as pd
import json
import matplotlib
import numpy as np
import seaborn as sn
import glob as glob
import cv2 as cv2
from tensorflow.python.platform import gfile
from matplotlib import pyplot as plt
from moviepy.editor import VideoFileClip
from PIL import Image
from settings import FLAGS
from .video import compute_dense_optical_flow_for_batch

  """ takes a folder with a gif file, creates sub directory named after the gif file and stores the single frames in it"""
  assert gif_file_path
  dir_name = os.path.basename(gif_file_path)
  new_dir = create_subfolder(os.path.dirname(gif_file_path), os.path.splitext(dir_name)[0])
  clip = mpy.VideoFileClip(gif_file_path).to_RGB()
  clip.write_images_sequence(os.path.join(new_dir, 'generated_clip_frame%03d.png'))


def frames_to_gif_in_dir_tree(root_dir):
  subdirs = get_subdirectory_files(root_dir, depth=2)
  for subdir in subdirs:
    convert_frames_to_gif(subdir, 'action', fps=20, image_type='.png')


def gif_to_frames_in_dir_tree(root_dir):
  subdirs = get_subdirectory_files(root_dir, depth=2)
  for subdir in subdirs:
    convert_gif_to_frames(subdir)


def generate_batch_from_dir(path, suffix="*.png"):
  '''
  :param path: directory path to images
  :param suffix: regex that specifies the file suffix (e.g. "*.png" or "*.jpg")
  :return: numpy array with shape (1, encoder_length, height, width, num_channels)
  '''
  assert os.path.isdir(path), str(path) + "doesn't seem to be a valid path"

  files = file_paths_from_directory(path, suffix)
  assert files and len(files)>0, 'Could not find an image with suffix %s in %s'%(path, suffix)

  batch = np.zeros((1, FLAGS.encoder_length, FLAGS.height, FLAGS.width, 3), dtype=np.uint8)