package com.emadbarsoum.driver;

import com.emadbarsoum.map.*;
import com.emadbarsoum.mapreduce.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.hadoop.util.ProgramDriver;

/**
 * HVision main entry point: com.emadbarsoum.driver.HVisionDriver
 *
 * The first argument specify which map\reduce job to run, based on this argument
 * we will send the proper map\reduce job to hadoop or locally using ProgramDriver.
 *
 * The remaining arguments are passed to the hadopp job.
 */
public final class HVisionDriver
{
    private static final Logger log = LoggerFactory.getLogger(HVisionDriver.class);

    private HVisionDriver() 
    {
    }

    public static void main(String[] args) throws Throwable
    {
        int exitCode = -1;

        if (args.length < 2)
        {
            showUsage();
            System.exit(2);
        }

        try
        {
            String[] remainingArgs = new String[args.length - 1];
            System.arraycopy(args, 1, remainingArgs, 0, args.length - 1);

            // Non-hadoop tasks
            if (args[0].equals("iseq"))
            {
                com.emadbarsoum.format.SequenceFileFromImages.main(remainingArgs);
            }
            else if (args[0].equals("idump"))
            {
                com.emadbarsoum.format.ImagesFromSequenceFile.main(remainingArgs);
            }
            else if (args[0].equals("isrdump"))
            {
                com.emadbarsoum.format.ImageSearchResultDump.main(remainingArgs);
            }
            else if (args[0].equals("bowtrainer"))
            {
                com.emadbarsoum.tools.BOWTrainer.main(remainingArgs);
            }
            else if (args[0].equals("iseqlab"))
            {
                com.emadbarsoum.tools.SequenceFileFromLabeledImages.main(remainingArgs);
            }
            else if (args[0].equals("svmdump"))
            {
                com.emadbarsoum.tools.SVMModelsFromSequenceFile.main(remainingArgs);
            }
            // Hadoop tasks
            else
            {
                ProgramDriver programDriver = new ProgramDriver();

                // Map only tasks
                programDriver.addClass("gaussian", Gaussian.class, "Map task that blur a set of images using Gaussian filter.");
                programDriver.addClass("median", Median.class, "Map task that blur a set of images using Median filter.");
                programDriver.addClass("thumbnail", Thumbnail.class, "Map task that create thumbnails from a set of images.");
                programDriver.addClass("findfaces", FindFaces.class, "Map task that find all faces in each image.");
                programDriver.addClass("color2gray", Gaussian.class, "Map task that convert a set of colored images to monochrome images.");
                programDriver.addClass("dilate", Dilate.class, "Map task that dilate a set of images.");
                programDriver.addClass("erode", Erode.class, "Map task that erode a set of images.");

                // MapReduce tasks
                programDriver.addClass("imagesearch", ImageSearch.class, "MapReduce task that performs content based image search using various algorithms.");
                programDriver.addClass("facestat", FaceStat.class, "MapReduce task that summarize the number of faces per image.");
                programDriver.addClass("imagesearchtotal", ImageSearchTotalOrder.class, "MapReduce task that performs content based image search using various algorithms. The resulted sequence files can be concatenated.");
                programDriver.addClass("icbowtrain", ImageClassificationBOWTrainer.class, "MapReduce task that performs BOW training using SVM.");

                // Run the task
                programDriver.driver(args);
            }
            exitCode = 0;
        }
        catch (Throwable e)
        {
            e.printStackTrace();
        }

        System.exit(exitCode);
    }

    private static void showUsage()
    {
        System.out.println("Usage: hvision <command> <args>");
    }
}

@@ -872,32 +872,86 @@
   try%0A        %7B%0A
+            long start = System.currentTimeMillis();%0A%0A
             Stri
@@ -3833,32 +3833,642 @@
 ;%0A            %7D%0A
+%0A            long duration = System.currentTimeMillis() - start;%0A%0A            long durationInSeconds = duration / 1000;%0A            long durationInMinutes = durationInSeconds / 60;%0A            long durationInHours = durationInMinutes / 60;%0A            long durationInDays = durationInHours / 24;%0A%0A            System.out.format(%22Time taken: %25d days, %25d hours, %25d minutes, %25d seconds.%5Cn%22,%0A                    durationInDays,%0A                    durationInHours - 24 * durationInDays,%0A                    durationInMinutes - 60 * durationInHours,%0A                    durationInSeconds - 60 * durationInMinutes);%0A%0A
             exit

Print out the time taken to complete the task.