/*
 * Copyright (c) 2009 The openGion Project.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
 * either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package org.opengion.hayabusa.servlet;

import org.opengion.fukurou.util.Closer ;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.Iterator;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriter;
import javax.imageio.stream.ImageOutputStream;

import java.io.File;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletConfig;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletOutputStream;


/**
 * 画像イメージに、文字列を動的に合成作成する、サーブレットです。
 *
 * 画像イメージを読取り、そこに、引数のテキスト文字列を合成します。
 * 元は、googleMap のマーカーに、マーカー番号を合成する為に作られました。
 *
 * 一般的なサーブレットと同様に、デプロイメント・ディスクリプタ WEB-INF/web.xml に、
 * servlet 要素と そのマッピング(servlet-mapping)を定義する必要があります。
 *
 *     &lt;servlet&gt;
 *         &lt;servlet-name&gt;makeImage&lt;/servlet-name&gt;
 *         &lt;servlet-class&gt;org.opengion.hayabusa.servlet.MakeImage&lt;/servlet-class&gt;
 *     &lt;/servlet&gt;
 *
 *     &lt;servlet-mapping&gt;
 *         &lt;servlet-name&gt;makeImage&lt;/servlet-name&gt;
 *         &lt;url-pattern&gt;/jsp/makeImage&lt;/url-pattern&gt;
 *     &lt;/servlet-mapping&gt;
 *
 * 一般には、http://サーバー:ポート/システムID/jsp/makeImage?text=番号
 * 形式のURL でアクセスします。
 *
 * @og.rev 3.8.1.1 (2005/11/21) 新規追加
 * @og.group その他機能
 *
 * @version  0.9.0  2000/10/17
 * @author   Kazuhiko Hasegawa
 * @since    JDK1.1,
 */
public class MakeImage extends HttpServlet {
	private static final long serialVersionUID = 400020050131L ;

	private static final String FORM_NAME = "png" ;	// jpg,BMP,bmp,JPG,wbmp,jpeg,png,PNG,JPEG,WBMP,GIF,gif
	private String imageFile = null;

	/**
	 * GET メソッドが呼ばれたときに実行します。
	 *
	 * 処理は、doPost へ振りなおしています。
	 *
	 * @param	request	HttpServletRequestオブジェクト
	 * @param	response	HttpServletResponseオブジェクト
	 *
	 * @og.rev 3.8.1.2 (2005/12/19) 半角カナ-全角カナ変換機能の追加
	 *
	 * @throws ServletException サーブレット関係のエラーが発生した場合、throw されます。
	 * @throws IOException 入出力エラーが発生したとき
	 */
	@Override
	public void doGet( final HttpServletRequest request, final HttpServletResponse response )
							throws ServletException, IOException {
		doPost( request,response );
	}

	/**
	 * POST メソッドが呼ばれたときに実行します。
	 *
	 * @param	request	HttpServletRequestオブジェクト
	 * @param	response	HttpServletResponseオブジェクト
	 *
	 * @throws ServletException サーブレット関係のエラーが発生した場合、throw されます。
	 * @throws IOException 入出力エラーが発生したとき
	 */
	@Override
	public void doPost( final HttpServletRequest request, final HttpServletResponse response )
							throws ServletException, IOException {

		String text = request.getParameter( "text" );

		// contentTypeを出力
		response.setContentType( "image/" + FORM_NAME );

		ServletOutputStream out = null;
		try {
			out = response.getOutputStream();
			BufferedImage img = createImage( text );
	//		JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
	//		encoder.encode( img );
	//		out.flush();

			Iterator<ImageWriter> ite = ImageIO.getImageWritersByFormatName( FORM_NAME );	// 4.3.3.6 (2008/11/15) Generics警告対応
			ImageWriter writer = ite.next();												// 4.3.3.6 (2008/11/15) Generics警告対応
			ImageOutputStream ios = ImageIO.createImageOutputStream( out );
			writer.setOutput( ios );
			writer.write( img );
			out.flush();
			ios.close();

	//		ImageIO.write( img,FORM_NAME,new File( "G:/webapps/gf/jsp/GF7010/test" + FORM_NAME ) );
		}
		finally {
			Closer.ioClose( out );		// 4.0.0 (2006/01/31) close 処理時の IOException を無視
		}
	}

	/**
	 * イメージの合成処理を行います。
	 *
	 * @param	text	合成するテキスト
	 *
	 * @return	イメージの合成されたBufferedImageオブジェクト
	 * @throws IOException 入出力エラーが発生したとき
	 */
	private BufferedImage createImage( final String text ) throws IOException {
		// イメージの作成
	//	BufferedImage image = new BufferedImage(25, 25, BufferedImage.TYPE_INT_ARGB);

		BufferedImage image = ImageIO.read( new File( imageFile ) );
		Graphics2D gph = (Graphics2D)image.getGraphics();

		int xsp = (text.length() == 1) ? 8 : 2 ;

	//	gph.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
	//						 RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
	//	gph.setColor(new Color(255,255,255));
	//	gph.fillRect(0,0,25,25);
		gph.setFont(new Font("Serif", Font.BOLD, 14));
		gph.setColor(new Color(0,0,255));
		gph.drawString(text, xsp, 15);
	//	gph.setColor(new Color(0,255,0));
	//	gph.drawOval(2,2,22,22);

		gph.dispose();

		return image;
	}

	/**
	 * Servlet の 初期値設定を行います。
	 *
	 * WEB-INF/web.xml ファイルで、&lt;servlet&gt; タグ内で初期値設定を行います。
	 * &lt;init-param&gt;
	 *     &lt;param-name&gt;imageFile&lt;/param-name&gt;
	 *     &lt;param-value&gt;G:/webapps/gf/jsp/GF7010/mark.png&lt;/param-value&gt;
	 * &lt;/init-param&gt;
	 *
	 * @param	config	ServletConfigオブジェクト
	 */
	@Override
	public void init( final ServletConfig config ) throws ServletException {
		super.init( config );

//		ServletConfig config = getServletConfig();

		imageFile = config.getInitParameter("imageFile");
	}

	/**
	 * PNGイメージの透過色指定を行います。
	 *
	 * 引数のファイル(PNG)を読取り、白色を透過色に変換後、セーブします。
	 * ただし、PNG形式で透過をサポートしているのは、IE7,Firefox,opera 等で、
	 * IE6 は未サポート(グレーになる)です。
	 *
	 * Usage: java org.opengion.hayabusa.servlet.MakeImage IN_FILE OUT_FILE
	 *
	 * @param	args	コマンド引数配列
	 * @throws IOException 入出力エラーが発生したとき
	 */
	public static void main( final String[] args ) throws IOException {

		BufferedImage org = ImageIO.read( new File( args[0] ) );

		int wd = org.getWidth();
		int ht = org.getHeight();
		BufferedImage dst = new BufferedImage(wd, ht, BufferedImage.TYPE_INT_ARGB);
		for(int y=0; y<ht; y++) {
			for(int x=0; x<wd; x++) {
				if(org.getRGB(x, y) == 0xFFFFFFFF) {	//白
					dst.setRGB(x, y, 0);	//透明
				}
				else {
					dst.setRGB(x, y, org.getRGB(x, y));
				}
			}
		}
		ImageIO.write( dst,"png",new File( args[1] ) );
	}
}
