from cv2 import cv2
import numpy as np
import re,os
from glob import glob
from PIL import Image
import matplotlib.pyplot as plt
from shutil import rmtree
import pandas as pd
from natsort import natsorted
import imageio
import moviepy.editor as mp

bp = "E:/1Study/Hiwi/Massvis dataset" # change base path to the directory where you have downloaded the salicon data
curdir = 'E:/1Study/Hiwi/massvis/eyetracking/csv_files/fixationsByVis'
eledir = 'E:/1Study/Hiwi/massvis/dataset/csv_files/targets393_elementLabels/elementLabels/'
origimdir = os.path.join(bp, 'targets')

def highlight_function(x,y,r,imagePath,outPath,imgName):
    # load input image
    img= cv2.imread(imagePath, cv2.IMREAD_UNCHANGED)

    # blur the image_origin to imgBlur
    imgBlur=cv2.blur(img,(15,15))

    # reduce brightness of imgBlur by 40%
    w=imgBlur.shape[1]
    h=imgBlur.shape[0]

    imgBrightness=0.6

    for xi in range(0,w):
        for xj in range(0,h):
            imgBlur[xj,xi,0]=int(imgBlur[xj,xi,0]*imgBrightness)
            imgBlur[xj,xi,1]=int(imgBlur[xj,xi,1]*imgBrightness)
            imgBlur[xj,xi,2]=int(imgBlur[xj,xi,2]*imgBrightness)


    # get size of image
    height, width = img.shape[:2]
    height = int(height)
    width = int(width)

    # generate in-circle-display template
    circleIn = np.zeros((height, width, 1), np.uint8)
    circleIn = cv2.circle(circleIn, (x, y), r, (1), -1)

    # generate out-circle-display template
    circleOut = circleIn.copy()
    circleOut[circleOut == 0] = 2
    circleOut[circleOut == 1] = 0
    circleOut[circleOut == 2] = 1

    # generate imgIn in which only the content in the spotlight circle remains 
    # generate a blank img with the same size of input image 
    imgIn = np.zeros((height, width, 4), np.uint8)
    # copy first 3 channel
    imgIn[:, :, 0] = np.multiply(img[:, :, 0], circleIn[:, :, 0])
    imgIn[:, :, 1] = np.multiply(img[:, :, 1], circleIn[:, :, 0])
    imgIn[:, :, 2] = np.multiply(img[:, :, 2], circleIn[:, :, 0])
    # set non-transparent part of α channel
    circleIn[circleIn == 1] = 255
    imgIn[:, :, 3] = circleIn[:, :, 0]

    # generate imgOut in which only the content outside the spotlight circle remains and be blurred
    imgOut = np.zeros((height, width, 4), np.uint8)
    imgOut[:, :, 0] = np.multiply(imgBlur[:, :, 0], circleOut[:, :, 0])
    imgOut[:, :, 1] = np.multiply(imgBlur[:, :, 1], circleOut[:, :, 0])
    imgOut[:, :, 2] = np.multiply(imgBlur[:, :, 2], circleOut[:, :, 0])
    circleOut[circleOut == 1] = 255
    imgOut[:, :, 3] = circleOut[:, :, 0]

    # generate output image by adding imgIn and imgOut
    imgHighlight = cv2.add(imgIn,imgOut)
    cv2.imwrite(os.path.join(outPath , imgName+'.png'),imgHighlight)

    if(cv2.waitKey(0)==27): 
        cv2.destroyAllWindows()

    return imgHighlight


for curfile in os.listdir(curdir):
    os.makedirs(os.path.join(bp, 'highlight'), exist_ok=True)
    outpath = os.path.join(bp, 'highlight', curfile)
    os.makedirs(outpath, exist_ok=True)
    basepath = os.path.basename(curfile)
    imname, ext = os.path.splitext(basepath)
    print('imname',imname)
        
    allfiles = natsorted(glob(os.path.join(curdir, curfile, 'enc' ,'*.csv')))

    # get the experiment data (csv format) 
    for subcsv in allfiles:
        fixations = pd.read_csv(subcsv, header=None)
        x=[]
        y=[]
        duration=[]
        for row in fixations.iterrows():
            x.append(row[1][1])
            y.append(row[1][2])
            duration.append(row[1][3])

    gif_image=[]

    # generate spotlight gif image
    for i in range(len(x)):

        #adjust the duration parameter so that the spotlight circle won't be too large or too small to display
        dur = duration[i]/3 if duration[i]/3>100 else 100
        dur = dur if dur>100 else 100

        # Make the display time of each spotlight correspond to the observation time of the experimenter
        dur_int=int(duration[i]/50)
        for j in range(dur_int):
            gif_image.append(highlight_function(int(x[i]),int(y[i]),int(dur),os.path.join(origimdir, curfile+'.png'),outpath,imname+'('+str(i+1)+')') )
        print(i)

    # save spotlight gif image 
    imageio.mimsave(os.path.join(outpath,imname+'.gif'), gif_image, fps=100)

# problem!!! : The generated spotlight gif image is too large
# possible solution: convert gif format to webm format. Converting to webm format can significantly reduce the file size 

