package org.richfaces.realworld.util;

import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageInputStream;

//TODO nick - delete this class
public class test {
//    private static String directory = "E:\\realworldnew\\web\\src\\main\\webapp\\WEB-INF\\Upload\\Viking\\15";
    private static String directory = "E:\\temp\\out_images\\";

    public static void main(String[] args) throws IOException {
        if (args.length > 0 && args[0] != null) {
            directory = args[0];
        }

        File file = new File(directory);
        writeFiles(file, "_small80", 80);
        writeFiles(file, "_small120", 120);
        writeFiles(file, "_small160", 160);
        writeFiles(file, "_small200", 200);
        writeFiles(file, "_mini", 150);
        writeFiles(file, "_medium", 600);
    }                                         

    private static void writeFiles(File file, String pattern, int size) {
        if (file.isDirectory()) {
            for (File subFile : file.listFiles()){
                writeFiles(subFile, pattern, size);
            }
        } else if (file.isFile()) {
            final String s = file.getName().toLowerCase();
            if (s.endsWith(".jpg") && !s.endsWith("_mini.jpg") && !s.endsWith("_medium.jpg")
                    && !s.endsWith("_small80.jpg") && !s.endsWith("_small120.jpg")
                    && !s.endsWith("_small160.jpg") && !s.endsWith("_small200.jpg")) {
                System.out.println("processing file >> " + file.getPath());
                writeOneImage(file.getParent(), pattern, size, s);
            }
        } else {
            throw new IllegalArgumentException("Unknow file type");
        }
    }

    private static void writeOneImage(String directory, String pattern, int size, String s) {
        BufferedImage bsrc;
        try {
            bsrc = bitmapToImage(directory + "\\" + s, "JPG");
        } catch (IOException e1) {
            e1.printStackTrace();
            return;
        }

        int i = bsrc.getWidth() > bsrc.getHeight() ? bsrc.getWidth() : bsrc.getHeight();
        double d = ((double) size) / i;
        Double yy = d * bsrc.getWidth();
        int width = yy.intValue();
        yy = d * bsrc.getHeight();
        int height = yy.intValue();
        BufferedImage bdest = getScaledInstance(bsrc, width, height, RenderingHints.VALUE_INTERPOLATION_BICUBIC, true);
        String dest = transformPath(directory + "\\" + s, pattern);

        try {
            imageToBitmap(bdest, dest, "JPG");
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    private static String transformPath(String target, String substitute) {
        String begin = target.substring(0, target.lastIndexOf("."));
        String end = target.substring(target.lastIndexOf("."));
        return begin + substitute + end;
    }

/*    private static void generateTags() {
        try {
            BufferedWriter out = new BufferedWriter(new FileWriter("C:\\1114.txt"));
            //String a ="INSERT INTO comments(comment_id, date, message, image_comment_id, from_user_id) VALUES ("+commentId+", '1985-01-08', 'Hello I am user',"+ imageId+", 2);\n"+ "INSERT INTO comments(comment_id, date, message, image_comment_id, from_user_id) VALUES ("+commentId2+", '1985-01-08', 'Hello I am user2',"+ imageId+", 3);\n";

            //out.write("INSERT INTO IMAGES_METATAGS(CI_IMAGE_ID, CI_METATAG_ID) VALUES("+"1"+"," +"1"+ ");\n");
            for (int i = 2; i < 84; i++) {
                String imageId = (new Integer(i)).toString();
                String commentId = (new Integer(i * 2 - 1)).toString();
                String commentId2 = (new Integer(i * 2)).toString();
                out.append("INSERT INTO comments(comment_id, date, message, image_comment_id, from_user_id) VALUES (" + commentId + ", '1985-01-08', 'Hello I am user'," + imageId + ", 2);\n" + "INSERT INTO comments(comment_id, date, message, image_comment_id, from_user_id) VALUES (" + commentId2 + ", '1985-01-08', 'Hello I am user2'," + imageId + ", 3);\n");
            }
            out.close();
        } catch (IOException e) {
            // Do nothing.
        }

    }*/

    public static BufferedImage bitmapToImage(String data, String format) throws IOException {
        InputStream inb = new FileInputStream(data);
        ImageReader rdr = ImageIO.getImageReadersByFormatName(format).next();
        ImageInputStream imageInput = ImageIO.createImageInputStream(inb);
        rdr.setInput(imageInput);
        BufferedImage image = rdr.read(0);
        inb.close();
        return image;
    }

    public static void imageToBitmap(BufferedImage image, String data, String format) throws IOException {
        OutputStream inb = new FileOutputStream(data);
        ImageWriter wrt = ImageIO.getImageWritersByFormatName(format).next();
        ImageInputStream imageInput = ImageIO.createImageOutputStream(inb);
        wrt.setOutput(imageInput);
        wrt.write(image);
        inb.close();
    }

    /**
     * Convenience method that returns a scaled instance of the
     * provided {@code BufferedImage}.
     *
     * @param img           the original image to be scaled
     * @param targetWidth   the desired width of the scaled instance,
     *                      in pixels
     * @param targetHeight  the desired height of the scaled instance,
     *                      in pixels
     * @param hint          one of the rendering hints that corresponds to
     *                      {@code RenderingHints.KEY_INTERPOLATION} (e.g.
     *                      {@code RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR},
     *                      {@code RenderingHints.VALUE_INTERPOLATION_BILINEAR},
     *                      {@code RenderingHints.VALUE_INTERPOLATION_BICUBIC})
     * @param higherQuality if true, this method will use a multi-step
     *                      scaling technique that provides higher quality than the usual
     *                      one-step technique (only useful in downscaling cases, where
     *                      {@code targetWidth} or {@code targetHeight} is
     *                      smaller than the original dimensions, and generally only when
     *                      the {@code BILINEAR} hint is specified)
     * @return a scaled version of the original {@code BufferedImage}
     */
    public static BufferedImage getScaledInstance(BufferedImage img,
                                                  int targetWidth,
                                                  int targetHeight,
                                                  Object hint,
                                                  boolean higherQuality) {
        int type = (img.getTransparency() == Transparency.OPAQUE) ?
                BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
        BufferedImage ret = img;
        int w, h;
        if (higherQuality) {
            // Use multi-step technique: start with original size, then
            // scale down in multiple passes with drawImage()
            // until the target size is reached
            w = img.getWidth();
            h = img.getHeight();
        } else {
            // Use one-step technique: scale directly from original
            // size to target size with a single drawImage() call
            w = targetWidth;
            h = targetHeight;
        }

        do {
            if (higherQuality && w > targetWidth) {
                w /= 2;
                if (w < targetWidth) {
                    w = targetWidth;
                }
            }

            if (higherQuality && h > targetHeight) {
                h /= 2;
                if (h < targetHeight) {
                    h = targetHeight;
                }
            }

            BufferedImage tmp = new BufferedImage(w, h, type);
            Graphics2D g2 = tmp.createGraphics();
            g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
            g2.drawImage(ret, 0, 0, w, h, null);
            g2.dispose();

            ret = tmp;
        } while (w != targetWidth || h != targetHeight);

        return ret;
    }
}
