"""
This is a component of a larger project [Cat-A-Logger](https://github.com/screamatthewind/cat-a-logger) on github   
See this [Short Slide Presentation](https://github.com/screamatthewind/cat-a-logger/blob/main/Slide%20Presentation%20-%20Short.pdf)
"""
# Input data files are available in the "../input/" directory.
# For example, running this (by clicking run or pressing Shift+Enter) will list the files in the input directory

# from subprocess import check_output
# print(check_output(["ls", "../input"]).decode("utf8"))
INPUT_BACKGROUND_FILES = '../input/stanford-background-dataset/images'
INPUT_FOREGROUND_FILES = '../input/augmented-cats-and-dogs'

OUTPUT_DATASET_ID = 'random-backgrounds-for-cats-and-dogs'
OUTPUT_DATASET_NAME = 'Random Backgrounds for Cats and Dogs'
OUTPUT_PATH = './output'

# kaggle_secrets not supported by Google Cloud Platform for Kaggle(Beta) at this time
# from kaggle_secrets import UserSecretsClient
# user_secrets = UserSecretsClient()
#API_TOKEN = user_secrets.get_secret("Crop Cats and Cogs YOLOv3")

USER_ID = 'KAGGLE-USERNAME' # use your own username
API_TOKEN = 'KAGGLE-API-TOKEN' # use your own kaggle api key

# same size is used in Augment Cats and Dogs
MIN_SCALE = 0.2
MAX_SCALE = 0.5

run_limit = 100
import os
if not os.path.exists(OUTPUT_PATH):
    os.makedirs(OUTPUT_PATH)
import cv2
import numpy as np

# scale image by scale_factor, keep aspect ratio
def scale_image(image, scale_factor):
    
    image = np.array(image)
    image = cv2.resize(image, (0,0), fx=scale_factor, fy=scale_factor)

    image = Image.fromarray(image)
    
    return image
import random
from PIL import Image, ImageDraw, ImageOps
import matplotlib.pyplot as plt

background_path, background_dir, background_files = next(os.walk(INPUT_BACKGROUND_FILES))
foreground_path, foreground_dir, foreground_files = next(os.walk(INPUT_FOREGROUND_FILES))

for i in range(run_limit):

    random_background_image_num = random.randrange(len(background_files))
    random_foreground_image_num = random.randrange(len(foreground_files))

    background_image_filename = background_path + '/' + background_files[random_background_image_num]
    foreground_image_filename = foreground_path + '/' + foreground_files[random_foreground_image_num]

    background_image = Image.open(background_image_filename)
    foreground_image = Image.open(foreground_image_filename)

    if 'neg' in foreground_image_filename:
        background_image = ImageOps.grayscale(background_image)
        background_image = ImageOps.invert(background_image)
                
    elif 'bw' in foreground_image_filename:
        background_image = ImageOps.grayscale(background_image)

    # composite randomly scaled forground image at random position on random background image
    scale_factor = random.uniform(MIN_SCALE, MAX_SCALE)
    foreground_image = scale_image(foreground_image, scale_factor)

    # paste foreground image onto background image at random position
    foreground_image_width, foreground_image_height = foreground_image.size
    background_image_width, background_image_height = background_image.size

    x_max_pos = background_image_width - foreground_image_height
    y_max_pos = background_image_height - foreground_image_height
    
    x_pos_factor = random.uniform(0, 1)
    y_pos_factor = random.uniform(0, 1)
    
    x_new_pos = int(x_max_pos * x_pos_factor)
    y_new_pos = int(y_max_pos * y_pos_factor)
    
    background_image = background_image.convert('RGBA') # make images have same number of color channels
    background_image.paste(foreground_image, (x_new_pos, y_new_pos), foreground_image) # 3rd parm is mask

    # draw bounding box 
    draw = ImageDraw.Draw(background_image)
    draw.rectangle(((x_new_pos, y_new_pos), (x_new_pos + foreground_image_width, y_new_pos + foreground_image_height)), outline=(255, 0, 0), width = 3)

    # save composite image
    filename = os.path.basename(foreground_image_filename)
    fname, ext = os.path.splitext(filename) 

    background_image = background_image.convert('RGB') 
    background_image.save(OUTPUT_PATH + '/' + fname  + '-final.jpg', 'jpeg')
    
    # plt.imshow(background_image)   
    # plt.show()
    
    # plt.imshow(foreground_image)   
    # plt.show()
! python -m pip install --index-url https://test.pypi.org/simple/ --no-deps kaggle_uploader-screamatthewind
# Google Cloud Plaform for Kaggle(Beta) does not support /usr/lib modules at this time 
# Save Output Dataset

import time
import os

from kaggle_uploader import kaggle_uploader 

print("Saving Images")
start_time = time.time()

# kaggle_secrets are not supported by Google Cloud Platform for Kaggle(Beta) at this time
# from kaggle_secrets import UserSecretsClient
# user_secrets = UserSecretsClient()
# api_secret = user_secrets.get_secret("Crop Cats and Cogs YOLOv3")

kaggle_uploader.resources = []
kaggle_uploader.init_on_kaggle(USER_ID, API_TOKEN)
kaggle_uploader.base_path = OUTPUT_PATH
kaggle_uploader.title = OUTPUT_DATASET_NAME
kaggle_uploader.dataset_id = OUTPUT_DATASET_ID
kaggle_uploader.user_id = USER_ID

for filename in os.listdir(kaggle_uploader.base_path):
    kaggle_uploader.add_resource(filename, filename)
    
kaggle_uploader.update("new version")

run_time = time.time()-start_time
print('Done Saving Images - Total Time: {:.1f}'.format(run_time) + ' Secs')

# If you get an error during update, it is typically because of an invalid api key, bad username, 
# or the dataset does not exist.  This code does not create datasets.  It updates existing ones