#!/usr/bin/env python

import glob
import os
import re
import sys
import shutil
import importlib
import imp

from efidir.config import *
from efidir.sws import *
from efidir.utils import listimage, envi

def which(program):
    import os
    def is_exe(fpath):
        return os.path.isfile(fpath) and os.access(fpath, os.X_OK)

    fpath, fname = os.path.split(program)
    if fpath:
        if is_exe(program):
            return program
    else:
        for path in os.environ["PATH"].split(os.pathsep):
            path = path.strip('"')
            exe_file = os.path.join(path, program)
            if is_exe(exe_file):
                return exe_file

    return None


def usage():
    print "usage:"
    print "      " + sys.argv[0] + " parameterFile"
    print ""
    print "      paramFile: input parameters file"
    print ""
    print "          parameters file format:"
    print "                   # 0. parameters"
    print "                   inputDir = \"PATH TO INPUT IMAGES\""
    print "                   inputExt = \"IMAGE EXTENSION\""
    print "                   ratio = \"RATIO\" # ratio value to resize imges cf convert command. This ratio is not apply on thumbnails sizes"
    print ""
    print "                   # 0.1 Thumbnail sizes on resized images"
    print ""
    print "                   row        = [ROW OF 1st THUM,    ROW OF 2nd THUM,    ...]"
    print "                   column     = [COL OF 1st THUM,    COL OF 2nd THUM,    ...]"
    print "                   nb_rows    = [NB ROW OF 1st THUM, NB ROW OF 2nd THUM, ...]"
    print "                   nb_columns = [NB COL OF 1st THUM, NB COL OF 2nd THUM, ...]"
    print ""
    print "                   # 0.2 Maximum displacement in pixel for correlation of registration step"
    print "                   max_deplacement = MAXIMUM PIXEL DEPLACEMENT FOR REGISTRATION"
    print ""
    print "                   # 0.3 Define the indice of the master image for registation"
    print "                   master_image = 0"
    print ""
    print "                   # 0.4 Time laps interval for correlation of displacement step."
    print "                   time_laps_min=1"
    print "                   time_laps_max=4"
    print "                   time_laps_step=1"
    print ""

# check the number of argument"
if len(sys.argv) < 2:
    print "Not enough arguments"
    print "" 
    usage()
    sys.exit()
elif len(sys.argv) > 2:
    print "Not many arguments"
    print "" 
    usage()
    sys.exit()

# 0. Init

# 0.1 get parameters
main_dir = "."
inputParam = sys.argv[1]
nom_images = []
inputFileOfInputFiles = "images.list"

execfile(inputParam)

# 0.2 Target list to be built
targets = []


# 0.3 Get the list of input image
nom_images = listimage.genListImage(inputDir, inputExt, inputFileOfInputFiles)
nbr_images = len(nom_images)
nbr_imagette = len(row)


# 1. Resize image
 
resize_dir = inputDir+"/resized"+str(ratio)

for nPath in nom_images:
	n = os.path.basename(nPath)

        outputs = [resize_dir+"/"+n]
	inputs = [nPath]
	commands = [
		"convert "
		        +" "+ inputs[0]
                        +"  -verbose"
                        +"  -resize "+ str(ratio) +"%"
                        +"  -quality 100%"
                        +"  -comment \"proud made by EFIDIR chain\""
                        +" "+ outputs[0]
		]
        targets.append(target_create(commands, inputs, outputs))

# 2. Convert image JPG to gris image
grey_dir = inputDir+"/grey"

for nPath in nom_images:
	n = os.path.basename(nPath) 

	outputs = [grey_dir+"/"+n+".png"]
	inputs = [resize_dir+"/"+n]
	commands = [
		"convert "
		        +" "+  inputs[0]
                        +"  -verbose"
                        +"  -colorspace Gray"
                        +"  -comment \"proud made by EFIDIR chain\""
                        +" "+  outputs[0]
		]
        targets.append(target_create(commands, inputs, outputs))

# 3. Convert datatype in float
float_dir = inputDir+"/float"

for nPath in nom_images: 
	n = os.path.basename(nPath)

	outputs = [float_dir+"/"+n+".png.float",
                   float_dir+"/"+n+".png.float.hdr"]
	
 	inputs = [grey_dir+"/"+n+".png"]
 		
 	
 	commands = [
 		EFIDIR_PREFIX+"/bin/convert_datatype "
                        +"  --input "+inputs[0]		 
		        +"  --output "+outputs[0]		
		        +"  --output_datatype 4 "	 
	
		]
	targets.append(target_create(commands, inputs, outputs))


# 4 Crop imagette
# 4.1 Generate tasks
thumbnail_dir="thumb/thumb"
for noImagette in range(nbr_imagette):
	for nPath in nom_images: 
		n = os.path.basename(nPath)
	
		outputs = [thumbnail_dir+str(noImagette)+"/"+n+".png.float.crop",
			   thumbnail_dir+str(noImagette)+"/"+n+".png.float.crop.hdr"]
	
		inputs = [float_dir+"/"+n+".png.float",
			  float_dir+"/"+n+".png.float.hdr"]
 		
 	
		commands = [
			EFIDIR_PREFIX+"/bin/crop "
			+"  --input "+inputs[0]	 
			+"  --output "+outputs[0]	
			+"  --row "+str(row[noImagette])
			+"  --column "+str(column[noImagette]) 
			+"  --nb_rows "+str(nb_rows[noImagette])
			+"  --nb_columns "+str(nb_columns[noImagette])
			]
		targets.append(target_create(commands, inputs, outputs))




# 4.2 Run all tasks of chain
chain = chain_create("init_data.mk", targets)
chain_run(chain)
targets = []

# 4.3 Generate all image list for crop
for noImagette in range(nbr_imagette):
	listimage.genListImage(thumbnail_dir+str(noImagette)+"/", ".crop", "images.float.crop.list")


# 5. Dist_corr
thumb_disp_dir = "thumb_disp/thumb"

window_search_nb_rows = nb_rows[:]
window_search_nb_columns = nb_columns[:]
window_nb_rows = []
window_nb_columns = []

for i, no in enumerate(window_search_nb_rows):
	window_nb_rows.append(window_search_nb_rows[i]-2*max_deplacement)
	window_nb_columns.append(window_search_nb_columns[i]-2*max_deplacement)





for noImagette in range(nbr_imagette):

	nbrMaster = 0
	inputs = [thumbnail_dir+str(noImagette)+"/images.float.crop.list"]
 		
	f = open(inputs[0])

	for noMaster, l in enumerate(f):
		nbrMaster+=1

		outputs = [thumb_disp_dir+str(noImagette)+"_master_"+str(noMaster)+"/images.float.crop.list.corr"]

		commands = [
			EFIDIR_PREFIX+"/bin/dist_corr_series "                        
			+"  --input_file_name "+inputs[0]		 
			+"  --output_suffix .corr" 
			+"  --output_dir "+thumb_disp_dir+str(noImagette)+"_master_"+str(noMaster)	
			+"  --no_master "+str(noMaster)
			+"  --window_nb_rows "+str(window_nb_rows[noImagette])
			+"  --window_nb_columns "+str(window_nb_columns[noImagette])	 
			+"  --window_search_nb_rows "+str(window_search_nb_rows[noImagette])	 
			+"  --window_search_nb_columns "+str(window_search_nb_columns[noImagette])
			+"  --sub_pixel 3"	 
			+"  --intercorrelation_mode 0"
			]
		targets.append(target_create(commands, inputs, outputs))

	f.close()



# 6.1. cal_slc dx
print nbrMaster

for noImagette in range(nbr_imagette):
	for noMaster in range(nbrMaster):
            thumb_disp_dx_dir = thumb_disp_dir+str(noImagette)+"_master_"+str(noMaster)+"/dx"

            inputs = [thumb_disp_dir+str(noImagette)+"_master_"+str(noMaster)+"/images.float.crop.list.corr "]

            outputs = [thumb_disp_dx_dir+"/images.float.crop.list.corr.dx"]
 	
            commands = [
			EFIDIR_PREFIX+"/bin/cal_slc_series "
			+"  --input "+inputs[0] 
			+"  --output_suffix .dx" 
		        +"  --output_dir "+thumb_disp_dx_dir
		        +"  --processing 4" 
	
			]

            targets.append(target_create(commands, inputs, outputs))

# 6.2. cal_slc dy

for noImagette in range(nbr_imagette):
	for noMaster in range(nbrMaster):
            thumb_disp_dy_dir = thumb_disp_dir+str(noImagette)+"_master_"+str(noMaster)+"/dy"

            inputs = [thumb_disp_dir+str(noImagette)+"_master_"+str(noMaster)+"/images.float.crop.list.corr "]

            outputs = [thumb_disp_dy_dir+"/images.float.crop.list.corr.dy "]	
 	
            commands = [
                    EFIDIR_PREFIX+"/bin/cal_slc_series "
                    +"  --input "+inputs[0] 
                    +"  --output_suffix .dy" 
                    +"  --output_dir "+thumb_disp_dy_dir
                    +"  --processing 5" 
                    
                    ]

            targets.append(target_create(commands, inputs, outputs))


# 7.  crop black area of distcorr imagette
black_area_columns = []
black_area_rows = []
area_nb_columns = nb_columns[:]
area_nb_rows = nb_rows[:]
for i, no in enumerate(window_search_nb_columns):
	black_area_columns.append((window_search_nb_columns[i]-1)/2)
	black_area_rows.append((window_search_nb_rows[i]-1)/2)
	area_nb_columns[i]=nb_columns[i]-2*black_area_columns[i]
	area_nb_rows[i]=nb_rows[i]-2*black_area_rows[i]




for noImagette in range(nbr_imagette):
    # 7.1 Crop imagette 1 dx 
    for noMaster in range(nbrMaster):
        thumb_disp_dx_dir = thumb_disp_dir+str(noImagette)+"_master_"+str(noMaster)+"/dx"
	
	outputs = [thumb_disp_dx_dir+"/crop/images.float.crop.list.corr.dx.crop"]
	
	inputs = [thumb_disp_dx_dir+"/images.float.crop.list.corr.dx "]
 		
 	
	commands = [
  		EFIDIR_PREFIX+"/bin/crop_series "
                          +"  --input "+inputs[0]	 
		          +"  --output_suffix .crop"
		          +"  --output_dir "+thumb_disp_dx_dir+"/crop/"
                          +"  --row "+str(black_area_rows[noImagette])
                          +"  --column "+str(black_area_columns[noImagette])
                          +"  --nb_rows "+str(area_nb_rows[noImagette])
                          +"  --nb_columns "+str(area_nb_columns[noImagette]),
		EFIDIR_PREFIX+"/bin/statistics_series "
		          +"  --input "+outputs[0]
		]
	targets.append(target_create(commands, inputs, outputs))

    # 7.2 Crop imagette 1 dy
    for noMaster in range(nbrMaster):
        thumb_disp_dy_dir = thumb_disp_dir+str(noImagette)+"_master_"+str(noMaster)+"/dy"
	
	outputs = [thumb_disp_dy_dir+"/crop/images.float.crop.list.corr.dy.crop"]
	
	inputs = [thumb_disp_dy_dir+"/images.float.crop.list.corr.dy"]
 		
 	
	commands = [
  		EFIDIR_PREFIX+"/bin/crop_series "
                          +"  --input "+inputs[0]	 
		          +"  --output_suffix .crop"
		          +"  --output_dir "+thumb_disp_dy_dir+"/crop/"
                          +"  --row "+str(black_area_rows[noImagette])
                          +"  --column "+str(black_area_columns[noImagette])
                          +"  --nb_rows "+str(area_nb_rows[noImagette])
                          +"  --nb_columns "+str(area_nb_columns[noImagette]),
		EFIDIR_PREFIX+"/bin/statistics_series "
		          +"  --input "+outputs[0]
		]
	targets.append(target_create(commands, inputs, outputs))


chain = chain_create("Chamonix.mk", targets)
chain_save(chain, "compute_thumb_displacement.mk")
chain_run(chain)
#sys.exit(0)
targets = []


# 8. get master image

execfile(which("get_master_image_from_set_of_displacements"))

# 9. compute POIs

POIsX = []
POIsY = []

for noImagette in range(nbr_imagette):
	POIsX.append([])
	POIsY.append([])
	for i in range(nbr_images):
		POIsX[noImagette].append(0)
 		POIsY[noImagette].append(0)
	


for noImagette in range(nbr_imagette):
	POIsX[noImagette][master_image] = column[noImagette]+nb_columns[noImagette]/2
	POIsY[noImagette][master_image] = row[noImagette]+nb_rows[noImagette]/2


for noImagette in range(nbr_imagette):
        thumb_disp_dx_dir = thumb_disp_dir+str(noImagette)+"_master_"+str(master_image)+"/dx"

	f = open(thumb_disp_dx_dir+"/crop/images.float.crop.list.corr.dx.crop", "r")
	i=0
	for name in f:
		if(i==master_image):
			i=i+1
		hdr=envi.readHDR(thumb_disp_dx_dir+"/crop/"+name.rstrip("\n")+".hdr")
		POIsX[noImagette][i] = POIsX[noImagette][master_image] + float(hdr["EFIDIR_average_band_0"][1:][:-1])
		i=i+1


for noImagette in range(nbr_imagette):
        thumb_disp_dy_dir = thumb_disp_dir+str(noImagette)+"_master_"+str(master_image)+"/dy"

	f = open(thumb_disp_dy_dir+"/crop/images.float.crop.list.corr.dy.crop", "r")
	i=0
	for name in f:
		if(i==master_image):
			i=i+1
		hdr=envi.readHDR(thumb_disp_dy_dir+"/crop/"+name.rstrip("\n")+".hdr")
		POIsY[noImagette][i] = POIsY[noImagette][master_image] + float(hdr["EFIDIR_average_band_0"][1:][:-1])
		i=i+1

print("POIsX: ", POIsX)
print("POIsY: ", POIsY)


#for noImagette in range(nbr_imagette):
#	print noImagette
#	print POIsX[noImagette]

# 10.  image registration

i=0

for nPath in nom_images: 
	n = os.path.basename(nPath)
	if (i!=master_image):
		outputs = ["registration_master_"+str(master_image)+"/"+n+".reg"]#,
			   #"registration_master_"+str(master_image)+"/"+n+".png.hdr"]
	
		inputs = [grey_dir+"/"+os.path.basename(nom_images[master_image])+".png",
			  grey_dir+"/"+n+".png"]

		commands = [
			EFIDIR_PREFIX+"/bin/registration "
                        +"  --master "+inputs[0]		 
		        +"  --slave "+inputs[1]
		        +"  --output "+outputs[0]	 
			+"  --master_POI series["+str(POIsX[0][master_image])+","+str(POIsY[0][master_image])+","
			                   +str(POIsX[1][master_image])+","+str(POIsY[1][master_image])+","
			                   +str(POIsX[2][master_image])+","+str(POIsY[2][master_image])+","
			                   +str(POIsX[3][master_image])+","+str(POIsY[3][master_image])+","
			                   +str(POIsX[4][master_image])+","+str(POIsY[4][master_image])+","
			                   +str(POIsX[5][master_image])+","+str(POIsY[5][master_image])+"]"
			+"  --slave_POI series["+str(POIsX[0][i])+","+str(POIsY[0][i])+","
			                  +str(POIsX[1][i])+","+str(POIsY[1][i])+","
			                  +str(POIsX[2][i])+","+str(POIsY[2][i])+","
			                  +str(POIsX[3][i])+","+str(POIsY[3][i])+","
			                  +str(POIsX[4][i])+","+str(POIsY[4][i])+","
			                  +str(POIsX[5][i])+","+str(POIsY[5][i])+"]"
			+"  --registration_type 2"
			]
		targets.append(target_create(commands, inputs, outputs))
	i=i+1

# 11. convert registered image to float

i=0

for nPath in nom_images: 
	n = os.path.basename(nPath)
	if (i!=master_image):
		inputs = ["registration_master_"+str(master_image)+"/"+n+".reg"]
	
		outputs = ["float_registration_master_"+str(master_image)+"/"+n+".float"]

		commands = [
			EFIDIR_PREFIX+"/bin/convert_datatype "
                              +"  --input "+inputs[0]		 
		              +"  --output "+outputs[0]		
		              +"  --output_datatype 4 "
			]
		targets.append(target_create(commands, inputs, outputs))
	i=i+1

chain = chain_create("Chamonix_init.mk", targets)
chain_run(chain)

shutil.copy(float_dir+"/"+os.path.basename(nom_images[master_image])+".png.float", "float_registration_master_"+str(master_image)+"/"+os.path.basename(nom_images[master_image])+".png.float")
shutil.copy(float_dir+"/"+os.path.basename(nom_images[master_image])+".png.float.hdr", "float_registration_master_"+str(master_image)+"/"+os.path.basename(nom_images[master_image])+".png.float.hdr")

listimage.genListImage("float_registration_master_"+str(master_image)+"/", ".float", "images.list")

targets = []


# 12. compute 2D displacements according time laps

for t in displacement_steps:

    inputs = ["float_registration_master_"+str(master_image)+"/images.list"]
    outputs = ["disp2D_registration_master_"+str(master_image)+"_n_n"+str(t)+"/images.list.corr"]

    commands = [
        EFIDIR_PREFIX+"/bin/dist_corr_series "                        
        +"  --input_file_name "+inputs[0]		 
        +"  --output_suffix .corr" 
        +"  --output_dir disp2D_registration_master_"+str(master_image)+"_n_n"+str(t)+"/"
        +"  --no_master "+str(master_image)
        +"  --window_nb_rows 33"
        +"  --window_nb_columns 33"
        +"  --window_search_nb_rows 53"
        +"  --window_search_nb_columns 53"
        +"  --sub_pixel 3"	 
        +"  --intercorrelation_mode "+str(t)
        ]
    targets.append(target_create(commands, inputs, outputs))



chain = chain_create("Chamonix.mk", targets)
chain_save(chain, "process_region_argentiere_camera.mk")
chain_run(chain)
