#######################################################
##              Emulate Fudaa-LSPIV                  ##
#######################################################
#Description: THis is a script to emulate Fudaa. It was originally written by Jerome Le Coz and is being modified by James Bomhof 
#The script emulates Fudaa processing and it is hoped to be used for batch processing from fixed camera sites

#clear variable list
rm(list=ls())

#load required libraries
library(ini)
library(stringr)

#Import the configuration file
Fparams <- read.ini("C:/ImageVelocimetry/01DHX04_NorthRiver/FudaaBatch/FudaaBatchConfig.ini")



############# set up file structures ##################
#set the working directory
setwd(Fparams$Paths$working.path)


#you should have already manually processed a video in Fudaa. Unzip the saved Fudaa file and you will see a folder called 'output.dir'
#copy the output.dir to the working directory. This folder contains the configuration files created when you processed a video on the Fudaa GUI
tmppath <- file.path(Fparams$Paths$exe.folder,"outputs.dir.") #note the extra '.' is necessary for windows to create a folder with a '.' in it
unlink(tmppath, recursive=TRUE)
dir.create(tmppath)
file.copy(from = Fparams$Paths$Fudaa.outputs.dir,
          to = Fparams$Paths$exe.folder, recursive = TRUE)


#Now do the same thing for the transects directory
tmppath <- file.path(Fparams$Paths$exe.folder,"transects") #note the extra '.' is necessary for windows to create a folder with a '.' in it
unlink(tmppath, recursive=TRUE)
dir.create(tmppath)
file.copy(from = Fparams$Paths$Fudaa.transects,
          to = Fparams$Paths$exe.folder, recursive = TRUE)


#get the list of videos to process
listofvideos <- list.files(Fparams$Paths$video.folder.path, pattern = '*.mp4')

#load the csv of corresponding water levels
stagecsv = read.csv(Fparams$Paths$stage.path)

#Set EXE folder to working directory
setwd(file.path(Fparams$Paths$working.path, Fparams$Paths$exe.folder))

#set timestep in the PIV_param.dat file
timeinterval = 1/as.numeric(Fparams$ImageExtract$framerate) * as.numeric(Fparams$ImageExtract$framestep)

PIVfile <- file.path("outputs.dir", "PIV_Param.dat")
PIVparam <- readLines(PIVfile)
PIVparam[9] <- round(timeinterval,digits = 15)
writeLines(PIVparam, con = PIVfile)




######## Start loop here #########################
s <- 1
i <-1
for (i in s:length(listofvideos)){
  #first copy the backup file to the working file (this
  #doesn't need to be done the first time in the loop, hence the try statement)
  try(
    file.copy(from = "outputs.dir/PIV_parambackup.dat",
              to = "outputs.dir/PIV_param.dat", overwrite = TRUE)
  )
  
  print(i)
  
  #first clear directories
  #list of Fudaa required folders, these will be created in the same level as the exes
  listoffolders <- c('img_pgm', 'img_transf', 'vel_filter', 'vel_scal', 'vel_raw')
  #clear and create new folders
  for (f in listoffolders){
    unlink(f, recursive = TRUE)
    dir.create(f)
  }
  
  #Define video and corresponding stage
  vid <- listofvideos[i]
  print(paste('Processing Video:', vid))
  stage <- stagecsv[match(vid,stagecsv$VideoName),2]
  
  #set the stage in the h.dat file
  hfile <- file.path("outputs.dir", "h.dat")
  hparam <- readLines(hfile)
  hparam[1] <- round(stage, 4)
  writeLines(hparam, hfile)
  
  
  
  ############# Run Fudaa Process #########################
  #Step 1: Process a video with the Fudaa GUI. This will generate the required files, specifically the configuration files in 'outputs.dir'. 
  # Extract and copy these files to the 'outputs.dir' directory in you working folder.
  #compute the coefficients of the orthorectification matrix (file coeff.dat) from h.dat and GRP.dat
  system2("./ortho_plan.exe", stdout = "", wait = TRUE)
  
  
  #Step 2:Extract the images from the video and place them in the folder 'img_pgm', label them in the format 'image000X.png'
  
  #Step 2a - use ffmpeg to extract images in pgm format
  #ffmpeg outputs PGM P5 formt (binary)
  system2("./ffmpeg.exe", args = c("-i", file.path(Fparams$Paths$video.folder.path,vid),
                                   "-vf", sprintf("framestep=%02d", as.numeric(Fparams$ImageExtract$framestep)),
                                   "-ss", as.numeric(Fparams$ImageExtract$starttime),
                                   "-to", as.numeric(Fparams$ImageExtract$endtime),
                                   "-hide_banner -loglevel panic ",
                                   "./img_pgm/image%4d.pgm"), stdout = FALSE, wait = TRUE)
  
  Nimages <- length(list.files("img_pgm"))
  
  #Step2b - use convert from imagemagick to convert binary pgm format (P5) to ascii pgm (P2) 
  # download from https://imagemagick.org/script/download.php#windows
  # the magick executable must be configured on the windows system environment variables (this is done by default during installation)
  
  
  #Step 3: convert and orthorectify the images
  #trasnsf_a.exe orthorectifies an image with the name "./img_pgm/image1.pgm"
  #input image is required to be in pgm ascii format (P2)
  #ffmpeg output images are pgm binary format (P5), hence use imagemagick to convert
  #the magick executable must be configured on the windows system environment variables (this is done by default during installation)
  
  
  ### Run orthorectif (first image) ###
  
  
  #rename and convert the first image to 'image1.pgm' (ascii), this is the input required for the transf_a program
  system2("magick", args = c("./img_pgm/image0001.pgm",
                             "-compress", "none",
                             "./img_pgm/image1.pgm"), stdout = NULL, wait = TRUE)
  
  #run the program, it outputs to a folder called 'img_transf' under the filename 'image1_transf.pgm'
  #Note - this is where I get errors and can't continue
  system2("./transf_a.exe", stdout = FALSE, wait = TRUE)
  
  #rename the file to 'image0001_transf.pgm'
  file.copy("./img_transf/image1_transf.pgm","./img_transf/image0001_transf.pgm", overwrite=TRUE)
  
  #initiate progress bar
  pb = txtProgressBar(min = 0, max = Nimages, initial = 0, style = 3) 
  
  #### Run orthorectif on images and use PIV on image pair s###
  for (j in 2:Nimages){
    setTxtProgressBar(pb,j)
    
    #convert image
    system2("magick", args = c(sprintf("./img_pgm/image%04d.pgm", j),
                               "-compress", "none",
                               "./img_pgm/image1.pgm"), stdout = "", wait = TRUE)
    #orthorectify image
    system2("./transf_a.exe", stdout = "", wait = TRUE)
    file.copy("./img_transf/image1_transf.pgm",sprintf("./img_transf/image%04d_transf.pgm", j), overwrite=TRUE)
    
    ### Run PIV ####
    #image 1
    file.copy(sprintf("./img_transf/image%04d_transf.pgm", j-1), "./img_transf/image1_transf.pgm", overwrite = TRUE)
    #image 2
    file.copy(sprintf("./img_transf/image%04d_transf.pgm", j), "./img_transf/image2_transf.pgm", overwrite = TRUE)
    #run executable
    system2("./PIV.exe", stdout = "", wait = TRUE)
    #copy data to new file
    file.copy("./vel_raw/piv.dat",sprintf("./vel_raw/piv%04d.dat", j-1), overwrite=TRUE)
  }
  
  
  # # write file list_avg.dat
  # Open the connection
  con <- file("./outputs.dir/list_avg.dat","w")
  list_avg <- NULL
  for (k in 2:Nimages){
    list_avg <- rbind(list_avg,sprintf("piv%04d.dat", k-1))
  }
  write.table(list_avg,con, sep="\t",row.names=F,col.names=F,quote=F)
  # # close the connection
  close(con)
  
  ### filter
  system2("./filter.exe", stdout = "", wait = TRUE)
  # 
  # ### moy_ec
  system2("./moy_ec.exe", stdout = "", wait = TRUE)
  # 
  
  #copy transects and compute
  #first do a backup of the PIV param file
  file.copy(from = "outputs.dir/PIV_param.dat",
            to = "outputs.dir/PIV_parambackup.dat")
  
  #in the transects folder, remove any result files
  unlink(file.path("transects",list.files("transects", pattern = "\\.res_dat$")))
  
  transectstoprocess <- list.files("transects", pattern = "\\.bth_dat$")
  

  #loop through each transect and compute Q
  for(j in seq_along(transectstoprocess)){
    t <- transectstoprocess[j]
    
    #copy the transect file over to the outputs.dir (working directory)
    file.copy(from = file.path("transects",t),
              to = "outputs.dir/bathy.dat", overwrite = TRUE)
    
    #copy the transect parameter file to the outputs.dir (working directory)
    parfile <- str_replace(t,"bth","par")
    file.copy(from = file.path("transects",parfile),
              to = "outputs.dir/PIV_param.dat",overwrite = TRUE)
    
    #compute velocities along cross section
    system2("./bathy_compute.exe", stdout = "", wait = TRUE)
    
    # ### Q_compute
    system2("./Q_compute.exe", stdout = "", wait = TRUE)
    # 
    # # Write results 
    resultfile <- str_replace(vid,".mp4", paste0("_transect_",j, ".txt"))
    file.copy("./outputs.dir/Discharge.dat",file.path(Fparams$Paths$save.path,resultfile), overwrite=TRUE)
    
  }

}
