//**************************************************************************
//
//      CSE 585 Project #2
//      By Anirudh Modi (anirudh@bart.aero.psu.edu) on 4/10/2000-Mon
//       & Shin Chin (scc136@psu.edu)
//       & Ming Ni (ni@cse.psu.edu)
//
//**************************************************************************
#include <iostream.h>
#include <fstream.h>
#include <stdio.h>
#include <stdlib.h>     // for atoi()
#include <string.h>
#include <math.h>
#include <time.h>
#include "utils.h"
#include "image.h"
#include "matrix.h"
#include "edgeflow.h"
#include "edgedetect.h"
#include "region.h"
//**************************************************************************
int debugflag = 0;
int textureflag = 1;
int intensityflag = 1;
//**************************************************************************
int main (int argc, char *argv[])
{
if (argc < 2)
        {
         cerr << endl;
         cerr << "Syntax: " << argv[0] << " <image-file-in-any-standard-format> [optional-arguments]" << endl;
         cerr << endl;
         cerr << "  Available optional arguments:" << endl;
         cerr << "\t-d <debug-flag>\t\t\t(Possible values: 0 or 1)" << endl;
         cerr << "\t-t <texture-flag>\t\t(Possible values: 0 or 1)" << endl;
         cerr << "\t-i <intensity-flag>\t\t(Possible values: 0 or 1)" << endl;
         cerr << "\t-s <sigma-value>\t\t(Suggested values: 1-5)" << endl;
         cerr << "\t-n <number-of-orientations>\t(Suggested values: 4-10)" << endl;
         cerr << "\t-thr <threshold-for-edge-flow>\t(Suggested value: 0.004)" << endl;
         cerr << "\t-m <min-boundary-size>\t\t(Possible values: 5-20)" << endl;
         cerr << endl;
         exit(-1);
        }

// Default values of sigma and numorient
double sigma = 2.0;
int numorient = 8;
double threshold = 4.0e-3;
int min_bndry_size = 10;

if (int index = parseArg(argc, argv, "-s"))
        sigma = atof(argv[index]);

if (int index = parseArg(argc, argv, "-n"))
        numorient = atoi(argv[index]);

if (int index = parseArg(argc, argv, "-d"))
        debugflag = atoi(argv[index]);

if (int index = parseArg(argc, argv, "-t"))
        textureflag = atoi(argv[index]);

if (int index = parseArg(argc, argv, "-i"))
        intensityflag = atoi(argv[index]);

if (int index = parseArg(argc, argv, "-thr"))
        threshold = atof(argv[index]);

if (int index = parseArg(argc, argv, "-m"))
        min_bndry_size = atoi(argv[index]);

cout << endl << "Progam BEGINS." << endl;
cout << endl;
cout << "Computation of TEXTURE edgeflow is " << printOnOff(textureflag) << "." << endl;
cout << "Computation of INTENSITY edgeflow is " << printOnOff(intensityflag) << "." << endl;
cout << "Debugging is " << printOnOff(debugflag) << "." << endl;
cout << endl;
cout << "Sigma (in pixels) = " << sigma << endl;
cout << "Number of orientations = " << numorient << endl;
cout << "Threshold for edge-flow detection = " << threshold << endl;
cout << endl;

time_t begin_time, end_time;
time(&begin_time);

GrayImage image, iR, iG, iB;
int RGBflag = 0;

if (image.isRGB(argv[1]))
        {
         image.ReadRGBimageFromFile2(argv[1], &iR, &iG, &iB);   // Read the image file
         RGBflag = 1;
        }
else
        {
         image.ReadFromFile2(argv[1]);
         iR = image;
         iG = image;
         iB = image;
        }

cout << endl;

char *name = ExtractName(argv[1]);
char filename[50];

sprintf(filename, "%s.dat", name);
FileCopy(argv[1], filename);

int height = image.height;
int width = image.width;

Matrix imgR(height, width), imgG(height, width), imgB(height, width);
iR.WriteToMatrix(&imgR);
iG.WriteToMatrix(&imgG);
iB.WriteToMatrix(&imgB);

Matrix Fr(height, width), Fi(height, width);
ComputeEdgeFlowVector(&Fr, &Fi, imgR, imgG, imgB, numorient, sigma);

sprintf(filename, "%s_R.mat", name);
Fr.WriteToFile(filename);
sprintf(filename, "%s_I.mat", name);
Fi.WriteToFile(filename);

sprintf(filename, "%s_R.dat", name);
Fr.WriteImage(filename);
sprintf(filename, "%s_I.dat", name);
Fi.WriteImage(filename);

Matrix Edge(height, width);
GrayImage EdgeImage;

DetectEdge(&Edge, Fr, Fi);
Edge.Threshold(threshold);
EdgeImage.ReadFromMatrix(Edge);
EdgeImage.RemoveLonelyPixels();

/*
makeRegions(EdgeImage, min_bndry_size);
writeAllRegions(&EdgeImage);
EdgeImage.ThresholdWhite(1);
*/

sprintf(filename, "%s.edge", name);
EdgeImage.DilationNxN(3);
EdgeImage.WriteToFile(filename, "gif");

sprintf(filename, "%s.final", name);
if (RGBflag)
        {
         GrayImage fR, fG, fB;
         fR.Init(height, width, 255);
         fG.Init(height, width, 255);
         fB.Init(height, width, 255);
         Combine2Images(iR, EdgeImage, &fR);
         Combine2Images(iG, EdgeImage, &fG);
         Combine2Images(iB, EdgeImage, &fB);
         WriteToRGBFile(filename, "gif", fR, fG, fB);
        }
else
        {
         GrayImage finalImage;
         finalImage.Init(height, width, 255);
         Combine2Images(image, EdgeImage, &finalImage);
         finalImage.WriteToFile(filename, "gif");
        }

Complex2Polar(&Fr,&Fi);
sprintf(filename, "%s_M.dat", name);
Fr.WriteImage(filename);
sprintf(filename, "%s_P.dat", name);
Fi.WriteImage(filename);

time(&end_time);
cout << endl << "Progam ENDS." << endl;

cout << "Total time consumed = " << (double) (end_time - begin_time) 
        << " sec" << endl;
cout.flush();
}
//**************************************************************************