package kr.co.swh.lecture.opensource.spark.recognition; 

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.ArrayList;

import javax.imageio.ImageIO;

/**
 * <pre>
 * kr.co.swh.spark_ai.recognition
 * ImageParser.java
 *
 * 설명 :	Ref. http://blogs.quovantis.com/image-classification-using-apache-spark-with-linear-svm/
 * 실행 : ImageParser 180x200 C:\Users\tobby48\eclipse-workspace\spark-ai\src\main\resources\faces96\male\ 1 C:\Users\tobby48\eclipse-workspace\spark-ai\src\main\resources\train\
 * 실행 : ImageParser 180x200 C:\Users\tobby48\eclipse-workspace\spark-ai\src\main\resources\faces96\female\ 0 C:\Users\tobby48\eclipse-workspace\spark-ai\src\main\resources\train\
 * 
 * 실행 : ImageParser 180x200 C:\Users\tobby48\eclipse-workspace\spark-ai\src\main\resources\faces96\test\ 2 C:\Users\tobby48\eclipse-workspace\spark-ai\src\main\resources\test\
 * </pre>
 * 
 * @since : 2019. 4. 4.
 * @author : tobby48
 * @version : v1.0
 */
public class ImageParser {

	/**
	 * <pre>
	 * 설명 : 컬러 이미지를 회색 이미지로 변환. 이미지를 구성하는 벡터값을 통해 인식
	 * 변경이력 : 
	 * -----------------------------------------------------------------
	 * 변경일       작성자       변경내용  
	 * ------------ ------------ ---------------------------------------
	 * 2019. 4. 4. tobby48          최초 작성 
	 * -----------------------------------------------------------------
	 * </pre> 
	 * @since : 2019. 4. 4.
	 * @author : tobby48
	 * @param image
	 */ 	
	public static void toGray(BufferedImage image) {
		int width = image.getWidth();
		int height = image.getHeight();
		for(int i=0; i<height; i++){
			for(int j=0; j<width; j++){
				Color c = new Color(image.getRGB(j, i));
				int red = (int)(c.getRed() * 0.21);
				int green = (int)(c.getGreen() * 0.72);
				int blue = (int)(c.getBlue() *0.07);
				int sum = red + green + blue;
				Color newColor = new Color(sum,sum,sum);
				image.setRGB(j,i,newColor.getRGB());
			}
		}
	}

	/**
	 * <pre>
	 * 설명 : 
	 * 변경이력 : 
	 * -----------------------------------------------------------------
	 * 변경일       작성자       변경내용  
	 * ------------ ------------ ---------------------------------------
	 * 2019. 4. 4. tobby48          최초 작성 
	 * -----------------------------------------------------------------
	 * </pre> 
	 * @since : 2019. 4. 4.
	 * @author : tobby48
	 * @param originalImage
	 * @param scaledWidth
	 * @param scaledHeight
	 * @param preserveAlpha
	 * @return
	 */ 	
	public static BufferedImage createResizedCopy(BufferedImage originalImage, int scaledWidth, int scaledHeight, boolean preserveAlpha){
		System.out.println("resizing...");
		int imageType = preserveAlpha ? BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
		BufferedImage scaledBI = new BufferedImage(scaledWidth, scaledHeight, imageType);
		Graphics2D g = scaledBI.createGraphics();
		if (preserveAlpha) {
			g.setComposite(AlphaComposite.Src);
		}
		g.drawImage(originalImage, 0, 0, scaledWidth, scaledHeight, null);
		g.dispose();
		return scaledBI;
	}

	public static void main(String[] args) throws IOException {

		/* args[0] is the pixel to which the image will be converted */
		String[] piexels=args[0].split("x");
		int scaledWidth= Integer.parseInt(piexels[0]);
		int scaledHeight= Integer.parseInt(piexels[1]);
		
		File outputDir = Paths.get(args[3].toString()).toFile();
		outputDir = new File(outputDir, "input-"+args[2]+".csv");
		
		ArrayList<String> paths = new ArrayList<String>();

		/**
		 * 	폴더 및 하위폴더 내의 모든 파일을 ArrayList에 저장
		 */
		Files.walkFileTree(Paths.get(args[1].toString()), new SimpleFileVisitor<Path>() {
			@Override
			public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
				//Files.delete(file);
				paths.add(file.toFile().getAbsolutePath());
				return FileVisitResult.CONTINUE;
			}

			@Override
			public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
				//Files.delete(dir);
				return FileVisitResult.CONTINUE;
			}

		});

		/*
		 * 	1. 각각의 이미지 파일을 프로그램 실행 시 이미지 크기로 변경
		 * 	2. 컬러 이미지를 회색 이미지로 변경
		 * */
		for(String file : paths){
			String extension = "";
			int extIndex = file.indexOf('.');
			extension = file.substring(extIndex+1);
			System.out.println(file+" extension "+ extension);
			File input = new File(file.toString());
			BufferedImage image =createResizedCopy(ImageIO.read(input),scaledWidth,scaledHeight,Boolean.TRUE);
			toGray(image);
			File output = new File(file.toString());
			ImageIO.write(image, extension, output);
		}

		try
		{
			/* args[2] is the Class of the image, Class = Male/Female. Vector will be written into a text file */
			PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(outputDir, true)));

			for(String file : paths){

				File file1 = new File(file.toString());
				BufferedImage img= ImageIO.read(file1);
				if (img == null) continue;
				Raster raster=img.getData();
				int w=raster.getWidth(),h=raster.getHeight();
				out.print(file1.getName() + "|");
				out.print(args[2]+",");
				for (int x=0;x<w;x++)
				{
					for(int y=0;y<h;y++)
					{
						out.print(raster.getSample(x,y,0)+" ");
					}
					out.print(" ");
				}
				out.println("");
			}
			out.close();
		}
		catch (Exception e)
		{
			//exception handling skipped for the reader
		}

	}
}
