
package jp.riken.brain.ni.samuraigraph.application;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.PrintJob;
import java.awt.Toolkit;
import java.awt.print.PrinterJob;
import java.io.File;
import java.util.Properties;

import javax.print.PrintService;
import javax.swing.JOptionPane;

import jp.riken.brain.ni.samuraigraph.base.SGDialog;
import jp.riken.brain.ni.samuraigraph.base.SGIConstants;
import jp.riken.brain.ni.samuraigraph.base.SGIImageExportManager;
import jp.riken.brain.ni.samuraigraph.base.SGUtility;

import org.freehep.util.export.ExportDialog;


/**
 * A class used to preview, print and export an image.
 */
public class SGImageExportManager
	implements SGIImageExportManager, SGIConstants
{

	/**
	 * 
	 */
	public static final String DEFAULT_EXPORT_FILE_NAME = "export";
	
	
	/**
	 * 
	 */
	public static final String DEFAULT_TITLE_NAME = "Export view as ...";


	/**
	 * An export dialog.
	 */
	private static final ExportDialog mExportDialog = new ExportDialog();


	/**
	 * A Color object set to the background of the preview dialog.
	 */
	private Color mBackgroundColor = Color.WHITE;


	/**
	 * 
	 */
	private String mBaseDirectoryName = null;


	/**
	 * 
	 */
	private String mExportFileName = DEFAULT_EXPORT_FILE_NAME;


	/**
	 * Default constructor.
	 *
	 */
	public SGImageExportManager()
	{
	}


	/**
	 * Export as image the target object.
	 * @param target - target object for export
	 * @param owner - owner object
	 * @param w - width of image
	 * @param h - height of image
	 * @return true:succeeded, false:failed
	 */
	public boolean export(
		Component target, Frame owner, final int w, final int h )
	{
		String title = "Export as Image";

		// preview
		if( this.preview(
			target, owner, w, h, w, h,
			title, SGDialog.OK_BUTTON_TEXT, SGDialog.CANCEL_BUTTON_TEXT
			) == CANCEL
		)
		{
			return true;
		}

//		while( true )
//		{
//			mExportDialog.showExportDialog
//			(
//				owner,
//				"Export view as ...",
//				target,
//				"export"
//			);
//			final int type = mExportDialog.getOptionType();
//			if( type==ExportDialog.CANCEL_OPTION )
//			{
//				return true;
//			}
//
//			final int ret = this.preview(
//				target, owner, w, h,
//				w, h, title );
//			if( ret == OK )
//			{
//				break;
//			}
//			else if( ret == CANCEL )
//			{
//				continue;
//			}
//		}


		if( this.mBaseDirectoryName==null )
		{
			return false;
		}

		ExportDialog ed = mExportDialog;
		String key = ExportDialog.class.getName() +".SaveAsFile";
		String baseDir = this.mBaseDirectoryName;

		{
			String path = ed.getUserProperties().getProperty(key);
			if( path!=null )
			{
				String parent = new File(path).getParent();
//				String name = path.substring( parent.length() + 1 );
				String pathNew = baseDir + FILE_SEPARATOR + this.mExportFileName;
				// + FILE_SEPARATOR + name;
//System.out.println(parent);
//System.out.println(name);
//System.out.println(pathNew);
				ed.setUserProperty( key, pathNew );
			}
		}


		// In Windows platform, modify to export image
		// in "My Documents" directory by default
		String defFile = baseDir + FILE_SEPARATOR + this.mExportFileName;
//System.out.println(defFile);
//System.out.println();
		// show the modal export dialog
		ed.showExportDialog
		(
			owner,
			DEFAULT_TITLE_NAME,
			target,
			defFile
		);


		// get current directory
		Properties p = ed.getUserProperties();
		String path = p.getProperty(key);
		if( path!=null )
		{
			String parent = new File( path ).getParent();
			String name = path.substring( parent.length() + 1 );
			this.setBaseDirectory( parent );
			this.mExportFileName = name;
		}

		return true;
	}


	/**
	 * 
	 * @param dir
	 */
	public void setBaseDirectory( String dir )
	{
		this.mBaseDirectoryName = new String(dir);
	}


	/**
	 * 
	 * @return
	 */
	public String getBaseDirectory()
	{
		return this.mBaseDirectoryName;
	}



	/**
	 * The OK button is pressed.
	 */
	public static final int OK = 0;

	/**
	 * The Cancel button is pressed or the window is closed.
	 */
	public static final int CANCEL = 1;


	/**
	 * Preview image of the target object.
	 * @param target - target object for export
	 * @param owner - owner object
	 * @param w - width of image
	 * @param h - height of image
	 * @return status
	 */
	private int preview(
		Component target, Frame owner,
		final int imageWidth, final int imageHeight,
		final int paperWidth, final int paperHeight,
		final String title, final String textOK, final String textCancel )
	{
		// create and show a modal preview dialog
		SGPreviewDialog dg = this.createPreviewDialog(
			target, owner, imageWidth, imageHeight, paperWidth, paperHeight,
			title, true );
		dg.setOKButtonText( textOK );
		dg.setCancelButtonText( textCancel );
		dg.setVisible(true);

		final int ret = dg.getCloseOption();
		if( ret==SGDialog.CANCEL_OPTION )
		{
			return CANCEL;
		}
		
		return OK;
	}



	/**
	 * Print image of the target object.
	 * @param target - target object for export
	 * @param owner - owner object
	 * @param w - width of image
	 * @param h - height of image
	 * @return true:succeeded, false:failed
	 */
	public boolean print( Component target, Frame owner, int w, int h )
	{
		
		// get available printers
		PrintService[] pArray = PrinterJob.lookupPrintServices();
		if( pArray.length==0 )
		{
			SGUtility.showMessageDialog(
				owner, "No printer is available.", "Error",
				JOptionPane.ERROR_MESSAGE
			);
			return false;
		}


		// create attributes objects
//		JobAttributes ja
//			= new JobAttributes(
//				1,
//				JobAttributes.DefaultSelectionType.ALL,
//				JobAttributes.DestinationType.PRINTER,
//				JobAttributes.DialogType.NATIVE,
//				null,
//				Integer.MAX_VALUE,
//				1,
//				JobAttributes.MultipleDocumentHandlingType.SEPARATE_DOCUMENTS_UNCOLLATED_COPIES,
//				new int[][]{ new int[]{ 1, 1 } },
//				null,
//				JobAttributes.SidesType.ONE_SIDED
//			);
//
//		PageAttributes pa
//			= new PageAttributes(
//				PageAttributes.ColorType.MONOCHROME,
//				PageAttributes.MediaType.A4,
//				PageAttributes.OrientationRequestedType.PORTRAIT,
//				PageAttributes.OriginType.PHYSICAL,
//				PageAttributes.PrintQualityType.HIGH,
//				new int[]{ 72, 72, 3 }
//			);


		//
		// preview
		//

		String title = "Print as Image";
		PrintJob job = null;
//		while( true )
		{
			job = Toolkit.getDefaultToolkit().getPrintJob(
				owner, "", null, null );
			if( job==null )
			{
				// returned value is equal to null when the print job is canceled
				return true;
			}

			Dimension paperSize = job.getPageDimension();
			final int ret = this.preview(
				target, owner, w, h,
				paperSize.width, paperSize.height,
				title,
				"Print",
				SGWizardDialog.CANCEL_BUTTON_TEXT );

			if( ret==OK )
			{
//				break;
			}
			else if( ret==CANCEL )
			{
				return true;
			}
		}


		//
		// print
		//

		// get a Graphics object to print
		Graphics g = job.getGraphics();

		// print objects
		target.printAll(g);

		//dispose a graphic object
		g.dispose();

		// end the print job
		job.end();

		return true;
	}



	/**
	 * Create a preview dilaog.
	 * @param target - target object for export
	 * @param owner - owner object
	 * @param w - width of image
	 * @param h - height of image
	 * @param modal - whether the preview dialog is modal
	 * @return true:succeeded, false:failed
	 */
	private SGPreviewDialog createPreviewDialog(
		Component target, Frame owner,
		final int imageWidth, final int imageHeight,
		final int paperWidth, final int paperHeight,
		final String title,
		final boolean modal )
	{
		SGPreviewDialog dg = new SGPreviewDialog( owner, title, modal );
		dg.pack();

		dg.setLocation( owner.getLocation() );
		dg.setTargetObject(
			target, imageWidth, imageHeight, paperWidth, paperHeight,
			this.mBackgroundColor );

		return dg;		
	}


	/**
	 * @return
	 */
	public Color getBackgroundColor()
	{
		return this.mBackgroundColor;
	}

	/**
	 * @param color
	 */
	public void setBackgroundColor( Color color )
	{
		if( color==null )
		{
			return;
		}
		this.mBackgroundColor = color;
	}

}

