/*
 * 作成日: 2004/12/31
 */
package hiro.yoshioka.image;

import hiro.yoshioka.extract.ImageArchiveManager;
import hiro.yoshioka.extract.ArchiveManager.EntryInfo;

import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.zip.ZipEntry;

import javax.imageio.ImageIO;

/**
 * @author jomora
 */
public class ThumbnailFactory {

	private ThumbnailFactory() {
	}

	/**
	 * サムネイル画像を作成する。 元画像のアスペクト比を保持したまま、指定したサイズに収める。
	 * 元画像がサポートされている画像フォーマットでなかった場合には、 例外が発生するので注意が必要。
	 * 事前にisSupportedImageFormat()でチェックしておきたい。
	 * 
	 * @param inStrm
	 *            元の画像
	 * @param outStrm
	 *            サムネイル画像
	 * @param maxThumbWidth
	 *            サムネイル画像の最大幅
	 * @param maxThumbHeight
	 *            サムネイル画像の最大高さ
	 * @throws IOException
	 *             画像の取得や生成に失敗した場合に発生する。
	 */
	public static void createThumbnail(InputStream inStrm,
			OutputStream outStrm, int maxThumbWidth, int maxThumbHeight)
			throws IOException {
		// 元画像
		BufferedImage image = ImageIO.read(inStrm);
		if (image == null) {
			throw new IOException("Can't read the original image.");
		}

		// 元画像の幅
		int width = image.getWidth();
		// 元画像の高さ
		int height = image.getHeight();

		// 幅の縮小倍率
		double widthRate = (double) maxThumbWidth / width;
		// 高さの縮小倍率
		double heightRate = (double) maxThumbHeight / height;

		// サムネイルの縮小倍率（初期化）
		double rate = 1;

		// 幅、高さのうち、小さい方の倍率を有効にする
		if (widthRate > heightRate) {
			rate = heightRate;
		} else {
			rate = widthRate;
		}
		// 拡大はしない
		if (rate > 1) {
			rate = 1;
		}

		BufferedImage shrinkImage = new BufferedImage(
				(int) (image.getWidth() * rate),
				(int) (image.getHeight() * rate), image.getType());
		AffineTransformOp atOp = new AffineTransformOp(AffineTransform
				.getScaleInstance(rate, rate), null);

		atOp.filter(image, shrinkImage);
		ImageIO.write(shrinkImage, "jpg", outStrm);
	}

	/**
	 * 読み込みサポートされている画像フォーマットかどうかチェックします。 サポートされている場合はtrue, そうでない場合はfalseを返します。
	 * 
	 * @param extension
	 *            画像ファイルの拡張子（例；jpg, JPEG, pNgなど）
	 * @return サポートされている場合はtrue, そうでない場合はfalse.
	 */
	public static boolean isSupportedReaderFormat(String extension) {
		String[] readerNames = ImageIO.getReaderFormatNames();
		for (int i = 0; i < readerNames.length; i++) {
			System.out.println(readerNames[i]);
			if (readerNames[i].equalsIgnoreCase(extension)) {
				return true;
			}
		}
		return false;
	}

	public static void main(String[] args) {
		int maxWidth = 35;
		int maxHeight = 35;

		isSupportedReaderFormat("");

		// 元画像
		ImageArchiveManager obj = new ImageArchiveManager();
		EntryInfo ei = null;
		try {
			ei = obj.lookupEntrys(new File("C:/tmp/aa.zip"));
		} catch (FileNotFoundException e1) {
			// TODO 自動生成された catch ブロック
			e1.printStackTrace();
		} catch (IOException e1) {
			// TODO 自動生成された catch ブロック
			e1.printStackTrace();
		}
		ZipEntry[] zs = ei.getZipEntries();
		for (int i = 0; i < zs.length; i++) {
			System.out.println("  " + zs[i].getName() + "/"
					+ zs[i].getCompressedSize() + "/" + zs[i].getSize());
			InputStream fiStrm = null;
			FileOutputStream foStrm = null;
			try {
				fiStrm = ei.getInputStream(zs[i]);
				foStrm = new FileOutputStream(new File(
						"C:/tmp/resources/thumbnail", ei
								.getWithOutExtentionName(zs[i])
								+ ".jpg"));

				ThumbnailFactory.createThumbnail(fiStrm, foStrm, maxWidth,
						maxHeight);

			} catch (IOException e) {
				e.printStackTrace();
			} finally {
				if (fiStrm != null) {
					try {
						fiStrm.close();
					} catch (Exception e) {
						// Do Nothing
					}
				}
				if (foStrm != null) {
					try {
						foStrm.close();
					} catch (Exception e) {
						// Do Nothing
					}
				}
			}
		}
		ei.dispose();
	}

}
