package com.idstrust.vicki.bundlecreator;

import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import javax.imageio.ImageIO;

public class ImageBundleBuilder {

	private static final String BUNDLE_FILE_TYPE = "png";

	public static class ImageRect {

		public final int height;

		public final BufferedImage image;

		public int left;

		public final int width;

		public ImageRect(BufferedImage image) {
			this.image = image;
			this.width = image.getWidth();
			this.height = image.getHeight();
		}
	}

	private Map<String, ImageRect> imageNameToImageRectMap = new HashMap<String, ImageRect>();
	
	private File directory;

	public File getDirectory() {
		return directory;
	}

	public void setDirectory(File directory) {
		this.directory = directory;
	}

	public void assimilate(String imageName) {
		ImageRect rect = getMapping(imageName);
		if (rect == null) {
			rect = addImage(imageName);
			putMapping(imageName, rect);
		}
	}

	public ImageRect getMapping(String imageName) {
		return imageNameToImageRectMap.get(imageName);
	}

	public String writeBundledImage(String bundleImageName) {
		BufferedImage bundledImage = drawBundledImage(bundleImageName);

		byte[] imageBytes;

		try {
			ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
			ImageIO.write(bundledImage, BUNDLE_FILE_TYPE, byteOutputStream);
			imageBytes = byteOutputStream.toByteArray();

			OutputStream outStream = new FileOutputStream(new File(directory, bundleImageName));

			outStream.write(imageBytes);
		}
		catch (IOException e) {
			e.printStackTrace();
		}

		return bundleImageName;
	}

	private ImageRect addImage(String imageName) {
		// Fetch the image.
		try {
			File imageFile = new File(directory, imageName);
			BufferedImage image = ImageIO.read(imageFile);
			return new ImageRect(image);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
		
		return null;
	}

	private BufferedImage drawBundledImage(String bundleImageName) {
		StringBuffer styleBuffer = new StringBuffer();
		
		//	ÀÌ¹ÌÁö »çÀÌÁî¸¦ °è»ê
		int nextLeft = 0;
		int maxHeight = 0;
		for (Iterator iter = imageNameToImageRectMap.keySet().iterator(); iter.hasNext();) {
			String key = (String) iter.next();
			ImageRect imageRect = imageNameToImageRectMap.get(key);
			
			//	style sheet ¿¡ Ãß°¡µÉ ºÎºÐ...
			String styleName = key.substring(0, key.lastIndexOf("."));
			styleBuffer
				.append(".").append(styleName).append(" {\n")
				.append("\t").append("background: transparent url( ").append(bundleImageName).append(" ) -").append(nextLeft).append("px 0 no-repeat;\n")
				.append("\t").append("width: ").append(imageRect.width).append("px;\n")
				.append("\t").append("height: ").append(imageRect.height).append("px;\n}\n");
			
			imageRect.left = nextLeft;
			nextLeft += imageRect.width;
			if (imageRect.height > maxHeight) {
				maxHeight = imageRect.height;
			}
		}

		BufferedImage bundledImage = new BufferedImage(nextLeft, maxHeight, BufferedImage.TYPE_INT_ARGB_PRE);
		Graphics2D g2d = bundledImage.createGraphics();

		//	ÀÌ¹ÌÁö¸¦ ±×·ÁÁÜ
		for (Iterator iter = imageNameToImageRectMap.keySet().iterator(); iter.hasNext();) {
			String key = (String) iter.next();
			
			ImageRect imageRect = imageNameToImageRectMap.get(key);
			g2d.drawImage(imageRect.image, imageRect.left, 0, null);
		}
		g2d.dispose();
		
		System.out.println(styleBuffer);

		return bundledImage;
	}

	private void putMapping(String imageName, ImageRect rect) {
		imageNameToImageRectMap.put(imageName, rect);
	}

}
