/* $Id: PrintData.java,v 1.1 2007/10/19 08:19:34 nito Exp $
 * 
 * Copyright (c)ARGO 21, Corporation. 2004.  All rights reserved.
 * 
 * This file is part of Nautica Workflow.
 * 
 *  Nautica Workflow is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 * 
 *  Nautica Workflow is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with Nautica Workflow; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *  
 */
package jp.co.argo21.nautica.tool.wfd.print;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.print.PageFormat;
import java.awt.print.Pageable;
import java.awt.print.Printable;
import java.awt.print.PrinterException;

import jp.co.argo21.nautica.tool.wfd.ProcessFlowView;

/**
 * 印刷データを実現する。
 * 
 * @author  Norihiro Itoh(ARGO 21 Corp.)
 * @version $Revision: 1.1 $
 * @since   Nautica Workflow 1.0
 */
public class PrintData implements Pageable
{
	/** ページフォーマット */
	private PageFormat format;
	/** 描画対象ビュー */
	private ProcessFlowView view;

	/**
	 * 印刷用データを生成する。
	 * 
	 * @param view 印刷対象のビュー
	 */
	public PrintData(ProcessFlowView view)
	{
		this.format = new PageFormat();
		this.view = view;
	}

	/**
	 * ページフォーマットを設定する。
	 * 
	 * @param format ページフォーマット
	 */
	public void setFormat(PageFormat format)
	{
		this.format = format;
	}

	/**
	 * 印刷のページ数を返す。
	 * 
	 * @return ページ
	 * @see java.awt.print.Pageable#getNumberOfPages()
	 */
	public int getNumberOfPages()
	{
		return 1;
	}

	/**
	 * 指定されたページのフォーマットを返す。
	 * 
	 * @param pageIndex ページ
	 * @return フォーマット
	 * @throws java.lang.IndexOutOfBoundsException
	 * @see java.awt.print.Pageable#getPageFormat(int)
	 */
	public PageFormat getPageFormat(int pageIndex)
	throws IndexOutOfBoundsException
	{
		return format;
	}

	/**
	 * 指定されたページの印刷データを返す。
	 * 
	 * @param pageIndex ページ
	 * @return 印刷データ
	 * @throws java.lang.IndexOutOfBoundsException
	 * @see java.awt.print.Pageable#getPrintable(int)
	 */
	public Printable getPrintable(int pageIndex)
	throws IndexOutOfBoundsException
	{
		return new FlowPage();
	}
	
	/**
	 * フローイメージ印刷データ生成用。
	 */
	class FlowPage implements Printable
	{
		/**
		 * フローイメージを描画する。
		 * 
		 * @param	g				ページが描画されるコンテキスト
		 * @param	format			描画されるページのサイズと印刷方向
		 * @param	pageIndex		描画されるページのゼロから始まるインデックス
		 * @return	ページの描画に成功した場合はPAGE_EXISTS、
		 *			pageIndex で指定されたページが存在しない場合はNO_SUCH_PAGE
		 * @throws java.awt.print.PrinterException
		 * @see java.awt.print.Printable#print(java.awt.Graphics, java.awt.print.PageFormat, int)
		 */
		public int print(Graphics g, PageFormat format, int pageIndex)
		throws PrinterException
		{
			Dimension psize = view.getPreferredSize();
			boolean needToRotate = false;
			if (psize.width > psize.height) needToRotate = true;

			double xScale = format.getImageableWidth() / psize.width;
			double yScale = format.getImageableHeight() / psize.height;
			if (needToRotate) {
				xScale = format.getImageableHeight() / psize.width;
				yScale = format.getImageableWidth() / psize.height;
			}
			double scale = 1.0;

			if (xScale < yScale) scale = xScale;
			else scale = yScale;

			Graphics2D g2 = (Graphics2D)g;

			AffineTransform tr = g2.getTransform();
			if (needToRotate) {
				g2.translate(0, format.getHeight());
				g2.rotate(Math.toRadians(-90));
			}

			g2.translate(format.getImageableX(), format.getImageableY());
			g2.scale(scale, scale);

			view.paintView(g2);

			g2.setTransform(tr);
			return PAGE_EXISTS;
		}
	}
}
