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

import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ComponentEvent;
import java.awt.geom.Line2D;
import java.awt.geom.Rectangle2D;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.EtchedBorder;

import jp.riken.brain.ni.samuraigraph.base.SGDialog;


/**
 * Preview dialog on exporting to the files.
 */
public final class SGPreviewDialog extends SGDialog
{

	/**
	 * 
	 */
	private JButton mOKButton = new JButton( OK_BUTTON_TEXT );


	/**
	 * 
	 */
	private JButton mCancelButton = new JButton( CANCEL_BUTTON_TEXT );


	/**
	 * A scroll pane object.
	 */
	private JScrollPane mScrollPane;


	/**
	 * The color of paper.
	 */
	private Color mPaperColor;
	
	
	/**
	 * Default width of this dialog.
	 */
	public static final int DEFAULT_WIDTH = 600;


	/**
	 * Default height of this dialog.
	 */
	public static final int DEFAULT_HEIGHT = 500;


	/**
	 * Temporary size of this dialog.
	 */
	private static int mTempWidth = DEFAULT_WIDTH;
	private static int mTempHeight = DEFAULT_HEIGHT;

	

	/**
	 * 
	 */
	public SGPreviewDialog()
	{
		super();
		this.initComponents();
	}


	/**
	 * 
	 */
	public SGPreviewDialog(
		final Dialog owner, final String title, final boolean modal )
	{
		super( owner, title, modal );
		this.initComponents();
	}


	/**
	 * 
	 */
	public SGPreviewDialog(
		final Frame owner, final String title, final boolean modal )
	{
		super( owner, title, modal );
		this.initComponents();
	}



	/**
	 * 
	 */
	private void initComponents()
	{
		// create the button panel
		JPanel buttonPanel = new JPanel();
		buttonPanel.add( this.mOKButton );
		buttonPanel.add( this.mCancelButton );
		buttonPanel.setBorder( new EtchedBorder( EtchedBorder.RAISED ) );
		this.getContentPane().add( buttonPanel, BorderLayout.NORTH );

		// set action listener
		this.mOKButton.addActionListener( this );
		this.mCancelButton.addActionListener( this );

		this.setVisible(false);
		this.setResizable(true);
	}



	/**
	 * Paint scroll bars and the corner after painted subcomponents.
	 */
	public void paint( Graphics g )
	{
		super.paint(g);

		JScrollPane sPane = this.mScrollPane;
		if( sPane!=null )
		{
			sPane.getHorizontalScrollBar().repaint();
			sPane.getVerticalScrollBar().repaint();

			Component corner = sPane.getCorner( JScrollPane.LOWER_RIGHT_CORNER );
			if( corner!=null )
			{
				corner.repaint();
			}
		}

	}



	/**
	 * 
	 * @param target
	 * @param imageWidth
	 * @param imageHeight
	 * @param paperWidth
	 * @param paperHeight
	 * @param cl
	 * @return
	 */
	public boolean setTargetObject(
		Component target,
		final int imageWidth,
		final int imageHeight,
		final int paperWidth,
		final int paperHeight,
		final Color cl )
	{

		// remove the old component
		if( this.mScrollPane!=null )
		{
			this.getContentPane().remove( this.mScrollPane );
		}

		// paper panel
		PaperPanel pp = new PaperPanel(
			cl, new Rectangle( 0, 0, imageWidth, imageHeight )
		);
		pp.add( target );
		pp.setPreferredSize( new Dimension( paperWidth, paperHeight ) );

		// background panel
		BackgroundPanel bp = new BackgroundPanel( pp );
		bp.add( pp );

		// add to the scroll pane
		JPanel p = new JPanel();
		p.add( bp );
		this.mScrollPane = new JScrollPane( p );
		this.mScrollPane.setBorder( null );

		// add corner
		JPanel corner = new JPanel();
		corner.setOpaque(true);
		corner.setBackground( this.getBackground() );
		this.mScrollPane.setCorner( JScrollPane.LOWER_RIGHT_CORNER, corner );

		// add to the content pane
		this.getContentPane().add( this.mScrollPane, BorderLayout.CENTER );

		// set the size
		this.setSize( mTempWidth, mTempHeight );

		return true;
	}



	/**
	 * 
	 * @param text
	 */
	public void setOKButtonText( final String text )
	{
		this.mOKButton.setText( new String(text) );
	}



	/**
	 * 
	 * @param text
	 */
	public void setCancelButtonText( final String text )
	{
		this.mCancelButton.setText( new String(text) );
	}


	/**
	 * 
	 */
	public void actionPerformed( ActionEvent e )
	{
		String command = e.getActionCommand();
		if( command.equals( this.mOKButton.getText() ) )
		{
			this.setCloseOption( OK_OPTION );
			this.setVisible(false);
		}
		else if( command.equals( this.mCancelButton.getText() ) )
		{
			this.setCloseOption( CANCEL_OPTION );
			this.setVisible(false);
		}
	}



	/**
	 * 
	 */
	public void componentResized(final ComponentEvent e)
	{
		super.componentResized(e);

		Component com = e.getComponent();
		mTempWidth = com.getWidth();
		mTempHeight = com.getHeight();

		this.repaint();
	}



	/**
	 * A panel to draw the paper.
	 */
	private static class PaperPanel extends JPanel
	{
		private Rectangle mRect;
		private Color mColor;

		public PaperPanel( Color cl, Rectangle rect )
		{
			super();
			this.init();
			this.mColor = cl;
			this.mRect = rect;
		}

		private void init()
		{
			this.setLayout(null);
			this.setOpaque( true );
			this.setBackground( Color.WHITE );
		}

		public void paintComponent( Graphics g )
		{
			super.paintComponent(g);
			
			Graphics2D g2d = (Graphics2D)g;
			if( this.mRect!=null & this.mColor!=null )
			{
				Rectangle2D rect = this.mRect;
				g2d.setPaint( this.mColor );
				g2d.fill( rect );
			}
//			g2d.setPaint( Color.BLACK );
//			g2d.setStroke( new BasicStroke(2) );
//			g2d.draw( new Rectangle(0,0,this.getWidth(),this.getHeight()) );
		}

	}



	/**
	 * A panel to draw the shade of the paper.
	 */
	private static class BackgroundPanel extends JPanel
	{
		private Component mComponent;

		/**
		 * 
		 * @param com
		 */
		public BackgroundPanel( Component com )
		{
			super();
			this.mComponent = com;
		}

		public void paintComponent( Graphics g )
		{
			super.paintComponent(g);
			
			Graphics2D g2d = (Graphics2D)g;
			if( this.mComponent!=null )
			{
				g2d.setPaint( Color.BLACK );

				Rectangle rect = this.mComponent.getBounds();
				final int lineWidth = 4;
				g2d.setStroke( new BasicStroke( lineWidth ) );

				final int x = rect.x + rect.width + lineWidth/2;
				Line2D line0 = new Line2D.Float(
					x, rect.y + 1.5f*lineWidth, x, rect.y + rect.height + lineWidth/2 );
				final int y = rect.y + rect.height + lineWidth/2;
				Line2D line1 = new Line2D.Float(
					rect.x + 1.5f*lineWidth, y, rect.x + rect.width + lineWidth/2, y );
				g2d.draw(line0);
				g2d.draw(line1);

				g2d.setStroke( new BasicStroke(2) );
				g2d.draw(rect);

			}
		}

	}


}

