import ij.*;
import ij.plugin.ImagesToStack;
import ij.plugin.*;

import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.JOptionPane;

import com.drew.imaging.ImageMetadataReader;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;

import net.coobird.thumbnailator.*;

import atg.taglib.json.util.JSONException;
import atg.taglib.json.util.JSONObject;

public class Google_Search implements PlugIn{

    private static URL url;
    private static URLConnection connection;

    /**
     * This method take's an string tags search and open connection with
     * googleapis.
     * 
     */

    private static void settings(String tags) throws IOException {
        String space = "%20";
        String newString = "";
        for (int i = 0; i < tags.length(); i++) {
            if (tags.charAt(i) != ' ')
                newString += tags.charAt(i);
            else
                newString += space;
        }

        url = new URL(
                "https://ajax.googleapis.com/ajax/services/search/images?v=1.0&q="
                        + newString + "&rsz=8");
        connection = url.openConnection();
    }

    /**
     * Create JSON flow and return a single string
     * 
     */
    public static JSONObject parseJSON() {
        JSONObject json = null;
        try {
            json = new JSONObject(createString(connection).toString());
        } catch (IOException error) {
            System.out.println("Error return JSONfile \n System.exit(0)");
            System.exit(0);
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return json;
    }

    /**
     * Create the stringbuilder that contain the query of response ajax services
     */
    public static StringBuilder createString(URLConnection connection)
            throws IOException {
        String line;
        StringBuilder builder = new StringBuilder();
        BufferedReader reader = new BufferedReader(new InputStreamReader(
                connection.getInputStream()));
        while ((line = reader.readLine()) != null) {
            builder.append(line);
        }
        return builder;
    }

    public static void addUrlImage(ArrayList<String> imageUrl, int index,
            JSONObject json) {
        try {
            imageUrl.add(index,
                    json.getJSONObject("responseData").getJSONArray("results")
                            .getJSONObject(index).getString("url"));
        } catch (JSONException error) {
            System.out.println("Error return JSONfile \n System.exit(0)");
        }
    }

    /**
     * this method return the format of image
     */

    public static String getFormat(ArrayList<String> imageUrl, int index) {
        String format = imageUrl
                .get(index)
                .toString()
                .substring(imageUrl.get(index).toString().length() - 3,
                        imageUrl.get(index).toString().length());
        return format;
    }

    /**
     * this method return the name of image
     */

    public static String getName(ArrayList<String> imageUrl, int index) {
        String name = imageUrl.get(index).substring(7,
                imageUrl.get(index).toString().length() - 4);
        return name;
    }

    /**
     * this method show the single image
     */

    public static void showThisImage(ArrayList<String> imageUrl, int index) {
        ImagePlus newImage = null;
        if (imageUrl != null)
            newImage = new ImagePlus(imageUrl.get(index));
        newImage.show();
    }

    /**
     *          Apache License Version 2.0, 
     * January 2004 http://www.apache.org/licenses/
     * http://imagej.nih.gov/ij/plugins/exif-reader.html
     * 
     * 
     */

    public static String getMetadata(String path) {
        File file = new File(path);
        StringBuilder sb = new StringBuilder();
        try {
            Metadata metadata = ImageMetadataReader.readMetadata(file);
            for (Directory dir : metadata.getDirectories()) {
                for (Tag tag : dir.getTags()) {
                    sb.append(tag);
                    sb.append("\n");
                }
            }
        } catch (Exception e) {
            String msg = e.getMessage();
            if (msg == null)
                msg = "" + e;
            return "Error: " + msg + "\n" + path;
        }
        String metadata = sb.toString();
        if (metadata != null)
            metadata = metadata.replace(" - ", ":\t");
        return metadata;
    }

    /**
     * @throws MalformedURLException
     * @throws IOException
     * 
     *             Read image from url, and save it in the local directory
     *             return reference file.
     */

    private static File writeImage(String imageUrl, String format, int index)
            throws MalformedURLException, IOException {
        File file = new File("tempFile" + "." + format);
        BufferedImage image = null;
        try {
            image = ImageIO.read(new URL(imageUrl));
        } catch (Exception e) {
            System.out.println("Not read image");
        }
        if (image != null) {
            ImageIO.write(image, format, file);
            Thumbnails.of(image).size(150, 150).outputFormat("jpg")
                    .toFile("thumbnail." + "tempFile" + index);
        }
        return file;
    }

    /**
     * to respect the information the image is delete
     */

    private static void deleteImage(File file) throws IOException {
        if (file != null)
            file.delete();
    }
    
    public void run(String arg0) {
        String log = "LogGSearch.txt";
        File write = new File(log);
        File deleteFile = null;

        BufferedWriter bufferWrite = null;
        try {
            bufferWrite = new BufferedWriter(new FileWriter(write));
        } catch (IOException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }

        try {
            String key;
            int numberImage = 0;

            key = JOptionPane
                    .showInputDialog("Enter the word associated at the image ");
            numberImage = Integer
                    .parseInt(JOptionPane
                            .showInputDialog("There for image to select: insert number image (1-8) "));
            settings(key);

            /**
             * By a JSON instance is possible estraxct an single image or eight
             * image. This images are selected by ajax googlesapis services.
             * 
             */
            JSONObject json = parseJSON();
            ArrayList<String> imageUrl = new ArrayList<String>(numberImage);

            IJ.showMessage("Ricerca Iniziata");

            if (json != null)
                for (int index = 0; index < numberImage; index++) {

                    /**
                     * add element in array
                     */
                    addUrlImage(imageUrl, index, json);
                    System.out.println("imageURL "
                            + imageUrl.get(index).toString() + "\n");

                    /**
                     * Determinate the format of image
                     */
                    String format = getFormat(imageUrl, index);

                    /**
                     * File name generate
                     */
                    String name = getName(imageUrl, index);
                    System.out.println(name);

                    /**
                     * Show image
                     * 
                     */
                    showThisImage(imageUrl, index);

                    /**
                     * The fase of operation 1. Save image. 2. 
                     * information, the include metadata and references of
                     * image. 3. Delete image.
                     */

                    if (imageUrl.get(index) != null) {
                        deleteFile = writeImage(imageUrl.get(index), format,
                                index);
                    }

                    /**
                    * Generate LogGSearch.txt file, including metadata information of image. and
                    * return the path of file.
                    * to respect the information the image is delete
                    */
                    bufferWrite.write("References Site "
                            + imageUrl.get(index).toString() + "\n"
                            + getMetadata("tempFile" + "." + format));

                    deleteImage(deleteFile);
                }
            IJ.showMessage("Ricerca Terminata");
            IJ.showMessage("Log generator " + write.getAbsolutePath());
            ImagesToStack stackImage = new ImagesToStack();
            stackImage.run("Image stack");
            bufferWrite.close();

        } catch (Exception e) {
            JOptionPane.showMessageDialog(null, e.getMessage(), "Failure",
                    JOptionPane.ERROR_MESSAGE);
            try {
                bufferWrite.close();
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            e.printStackTrace();
        }
    }
}
