/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed 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 Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License (L-GPL)
 * along with GECAMed.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
package lu.tudor.santec.gecamed.core.gui.widgets.print;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.text.NumberFormat;
import java.util.Vector;

import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;

import lu.tudor.santec.gecamed.core.gui.GECAMedColors;
import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.core.gui.utils.SwingWorker;
import lu.tudor.santec.gecamed.usermanagement.gui.settings.UserSettingsPlugin;
import lu.tudor.santec.i18n.Relocalizable;
import lu.tudor.santec.i18n.Translatrix;

import com.l2fprod.common.swing.JButtonBar;

public class PrintPreviewDialog extends JDialog implements ActionListener,
														   Relocalizable
														  
	{
	private Vector <BufferedImage>	m_PreviewPages;
	private BufferedImage			m_PreviewPage;
	
	private JToolBar 				m_ToolBar;
	private JScrollPane 			m_PreviewScroller;
	private JLabel 					m_Preview;
	
	private JLabel 					m_ZoomFactor;
	private JButtonBar 				m_Thumbnails;
	private ButtonGroup				m_ThumbnailGroup;
	
	private JButton 				m_ZoomOutButton;
	private JButton 				m_ZoomInButton;
	private JButton 				m_ZoomOriginalButton;
	private JButton 				m_ZoomFillButton;
	
	private JButton 				m_PrintButton;
	private JButton 				m_PrintCurrentButton;

	private NumberFormat			m_NumberFormat;
	
	private String					m_TitleKey;
	private int						m_CurrentPage;
	private double					m_Zoom;
	private boolean					m_PrintCurrent;

	private SwingWorker				m_ZoomWorker;
	
//---------------------------------------------------------------------------
//***************************************************************************
//* Constants	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

	private static final long serialVersionUID 	= 1L;
	
	private static double c_PageAspectRatio 	= 1.4142;

	private static double c_MaxZoom				= 2;
	
	private static final String c_ZoomOutTip 		= "PrintPreviewDialog.ZoomOutTip";
	private static final String c_ZoomInTip  		= "PrintPreviewDialog.ZoomInTip";
	private static final String c_ZoomOriginalTip 	= "PrintPreviewDialog.ZoomOriginalTip";
	private static final String c_ZoomFillTip       = "PrintPreviewDialog.ZoomFillTip";
	private static final String c_PrintTip			= "PrintPreviewDialog.PrintTip";
	private static final String c_PrintCurrentTip   = "PrintPreviewDialog.PrintCurrentTip";

//---------------------------------------------------------------------------
//***************************************************************************
//* Constructor	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

public PrintPreviewDialog (String p_TitleKey)
	{
	super (MainFrame.getInstance(),Translatrix.getTranslationString (p_TitleKey));
		
	m_TitleKey 		= p_TitleKey;	
	m_NumberFormat = NumberFormat.getInstance();
	
	m_CurrentPage  = -1;
	m_Zoom		   = 0;
	m_PrintCurrent = false;
	
	m_PreviewPages = new Vector <BufferedImage> ();
	
	this.buildDialog();
	}

//---------------------------------------------------------------------------
//***************************************************************************
//* Primitives	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

private void buildDialog ()
	{
	this.setModal(true);
	this.setLayout(new BorderLayout());
	this.getContentPane().setBackground(Color.WHITE);

	m_ToolBar = new JToolBar();
	m_ToolBar.setOpaque(false);
		
	m_PrintCurrentButton = new JButton ();
	m_PrintCurrentButton.setIcon (GECAMedModule.getMediumIcon (GECAMedIconNames.PRINT_1));
	m_PrintCurrentButton.setOpaque(false);
	m_PrintCurrentButton.addActionListener(this);
	m_ToolBar.add (m_PrintCurrentButton);
	
	m_ToolBar.addSeparator();

	m_PrintButton = new JButton ();
	m_PrintButton.setIcon (GECAMedModule.getMediumIcon (GECAMedIconNames.PRINT_ALL));
	m_PrintButton.setOpaque(false);
	m_PrintButton.addActionListener (this);
	m_ToolBar.add (m_PrintButton);
	
	m_ToolBar.addSeparator();
	
	m_ZoomOutButton = new JButton ();
	m_ZoomOutButton.setIcon (GECAMedModule.getMediumIcon (GECAMedIconNames.ZOOMOUT));
	m_ZoomOutButton.setOpaque(false);
	m_ZoomOutButton.addActionListener (this);
	m_ToolBar.add (m_ZoomOutButton);
	
	m_ZoomInButton = new JButton ();
	m_ZoomInButton.setIcon (GECAMedModule.getMediumIcon (GECAMedIconNames.ZOOMIN));
	m_ZoomInButton.setOpaque(false);
	m_ZoomInButton.addActionListener (this);
	m_ToolBar.add (m_ZoomInButton);
	
	m_ZoomOriginalButton = new JButton ();
	m_ZoomOriginalButton.setIcon (GECAMedModule.getMediumIcon (GECAMedIconNames.ZOOM1_1));
	m_ZoomOriginalButton.setOpaque(false);
	m_ZoomOriginalButton.addActionListener (this);
	m_ToolBar.add (m_ZoomOriginalButton);
		
	m_ZoomFillButton = new JButton ();
	m_ZoomFillButton.setIcon (GECAMedModule.getMediumIcon (GECAMedIconNames.ZOOMMAX));
	m_ZoomFillButton.setOpaque(false);
	m_ZoomFillButton.addActionListener (this);
	m_ToolBar.add (m_ZoomFillButton);
		
	m_ToolBar.addSeparator();

	m_ZoomFactor = new JLabel ();
	m_ToolBar.add(m_ZoomFactor);
			
	this.add(m_ToolBar, BorderLayout.NORTH);
		
	m_Preview = new JLabel();
	m_Preview.setHorizontalAlignment(JLabel.CENTER);
	m_Preview.setVerticalAlignment(JLabel.CENTER);
	m_Preview.setBackground(Color.WHITE);
	
	m_PreviewScroller = new JScrollPane(m_Preview);
	m_PreviewScroller.setOpaque(false);
	m_PreviewScroller.getViewport().setOpaque(false);
	m_PreviewScroller.getHorizontalScrollBar().setUnitIncrement(20);
	m_PreviewScroller.getVerticalScrollBar().setUnitIncrement(20); 
	this.add(m_PreviewScroller, BorderLayout.CENTER);
		
	m_Thumbnails = new JButtonBar(JButtonBar.VERTICAL);
	m_Thumbnails.setBackground(GECAMedColors.c_GECAMedBackground);
	this.add(m_Thumbnails, BorderLayout.EAST);
		
	Dimension l_ScreenSize = Toolkit.getDefaultToolkit().getScreenSize();
	int l_Height = l_ScreenSize.height - 80;
	int l_Width = (int) (l_Height / c_PageAspectRatio) + m_Thumbnails.getWidth();

	setLocation(5, 5);
	this.setSize(l_Width, l_Height);
	this.setPreferredSize(new Dimension(l_Width, l_Height));
	
	this.relocalize();
	this.pack();	
	}

//---------------------------------------------------------------------------

protected boolean showPrinterDialog() 
	{
	try {
		return (Boolean)MainFrame.getInstance().userSettings.getValue(UserSettingsPlugin.PRINTER_DIALOG_ENABLED);			
		} 
	catch (Exception p_Exception) 
		{
		}
	return true;
	}

//---------------------------------------------------------------------------

private int getPreviewWidth ()
	{
	if (m_PreviewPage != null) return m_PreviewPage.getWidth();
	else return 1;	
	}

//---------------------------------------------------------------------------

private int getPreviewHeight ()
	{
	if (m_PreviewPage != null) return m_PreviewPage.getHeight();
	else return 1;	
	}

//---------------------------------------------------------------------------

private double zoomOut (double p_Zoom)
	{
	double	l_Smallest;
	
	p_Zoom -= 0.1d;
    
	l_Smallest = this.zoomFill();
    if (p_Zoom < l_Smallest) p_Zoom = l_Smallest;
  	
	return p_Zoom;
	}

//---------------------------------------------------------------------------

private double zoomIn (double p_Zoom)
	{
	p_Zoom += 0.1d;
    if (p_Zoom > c_MaxZoom) p_Zoom = c_MaxZoom;
  	
	return p_Zoom;
	}

//---------------------------------------------------------------------------

private double zoomOriginal ()
	{
	return 1d;	
	}

//---------------------------------------------------------------------------

private double zoomFill ()
	{
	double	l_PreviewWidth;
	double	l_Zoom;
	
	l_PreviewWidth = (double)this.getPreviewWidth();
	
	l_PreviewWidth = (l_PreviewWidth > 0)?l_PreviewWidth:1;	
	l_Zoom = ((double)m_PreviewScroller.getWidth() / l_PreviewWidth) - 0.02d;
		
	return l_Zoom;
	}

//---------------------------------------------------------------------------
//***************************************************************************
//* Swing Worker Thread	                                                    *
//***************************************************************************
//---------------------------------------------------------------------------

Object ZoomWorker ()
	{
	this.zoomImage (m_Zoom);
	return "";
	}

//---------------------------------------------------------------------------

protected void zoomImage (double p_Zoom) 
	{	
	int	l_NewWidth;
	int	l_NewHeight;
		
	if (m_PreviewPage == null) return;
	
	l_NewWidth = (int)(this.getPreviewWidth() * m_Zoom);
	l_NewHeight = (int)(this.getPreviewHeight() * m_Zoom);
	
	m_Preview.setIcon (new ImageIcon (m_PreviewPage.getScaledInstance(l_NewWidth, l_NewHeight, Image.SCALE_FAST)));
	}

//---------------------------------------------------------------------------

private void doZoom ()
	{
	m_ZoomWorker = new SwingWorker() 
	{
	public Object construct() 
		{
		return ZoomWorker ();
		}
	public void start ()
		{
		MainFrame.getInstance().setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
		SwingUtilities.invokeLater(new Runnable() 
			{
			public void run() 
				{
				m_ZoomFactor.setText("zoom: " + m_NumberFormat.format(m_Zoom));
				}
			});
		super.start();
		}
	public void finished ()
		{
		MainFrame.getInstance().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
		}
	public void interrupt ()
		{
		super.interrupt();
		MainFrame.getInstance().setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
		}
	};

	m_ZoomWorker.start ();  	
	}

//---------------------------------------------------------------------------

public void doPrintAll ()
	{
		
	}

//---------------------------------------------------------------------------

public void doPrintCurrent (int p_PageNumber)
	{
		
	}

//---------------------------------------------------------------------------
//***************************************************************************
//* Class Body	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

public void setVisible (boolean p_ShowIt)
	{	
	if ((p_ShowIt) && (m_PreviewPages.size() > 0)) 
		{
		m_CurrentPage = 0;	
		m_PreviewPage = m_PreviewPages.elementAt(m_CurrentPage);
		
		this.doZoom ();	
		}
	
	super.setVisible(p_ShowIt);	
	}

//---------------------------------------------------------------------------

public void setPreviewPages (BufferedImage[] p_Pages)
	{
	ImageIcon		l_Thumbnail;
	JToggleButton	l_ThumbnailButton;
	int				l_CurrentPage;
		
	if ((p_Pages == null) || (p_Pages.length == 0)) 
		{
//		this.clear();
		return;
		}
	
	m_PreviewPage = p_Pages [0];
	m_CurrentPage = 0;
	
	m_PreviewPages.removeAllElements();
	m_Thumbnails.removeAll();
	m_ThumbnailGroup = new ButtonGroup ();
	
	for (l_CurrentPage = 0; l_CurrentPage < p_Pages.length; l_CurrentPage++)
		{
		m_PreviewPages.add (p_Pages [l_CurrentPage]);
			
		l_Thumbnail = new ImageIcon (p_Pages [l_CurrentPage].getScaledInstance(-1, 64, Image.SCALE_SMOOTH));
		
		l_ThumbnailButton = new JToggleButton (Integer.valueOf(l_CurrentPage).toString(),l_Thumbnail,true);
		l_ThumbnailButton.setVerticalTextPosition(SwingConstants.CENTER);
		l_ThumbnailButton.setHorizontalTextPosition(SwingConstants.LEFT);
		l_ThumbnailButton.setSelected((l_CurrentPage == 0));
		l_ThumbnailButton.addActionListener(this);
			
		m_Thumbnails.add (l_ThumbnailButton);
		m_ThumbnailGroup.add (l_ThumbnailButton);
		}
	
	m_Zoom = this.zoomFill();
	}

//---------------------------------------------------------------------------
	
public void actionPerformed (ActionEvent p_Event)
	{
	if (p_Event.getSource().equals(m_ZoomOutButton))
		{
		m_Zoom = this.zoomOut (m_Zoom);	
		this.doZoom();
		}
	else if (p_Event.getSource().equals(m_ZoomInButton))
		{
		m_Zoom = this.zoomIn (m_Zoom);	
		this.doZoom();
		}
	else if (p_Event.getSource().equals(m_ZoomOriginalButton))
		{
		m_Zoom = this.zoomOriginal ();	
		this.doZoom();
		}
	else if (p_Event.getSource().equals(m_ZoomFillButton))
		{
		m_Zoom = this.zoomFill ();	
		this.doZoom();
		}
	else if (p_Event.getSource().equals(m_PrintButton))
		{
		this.doPrintAll ();	
		}
	else if (p_Event.getSource().equals(m_PrintCurrentButton))
		{
		this.doPrintCurrent (m_CurrentPage);	
		}
	else if (p_Event.getSource() instanceof JToggleButton)
		{
		try	{
			m_CurrentPage = Integer.parseInt(p_Event.getActionCommand());
			}
		catch (NumberFormatException p_Exception)
			{
			m_CurrentPage = 0;	
			}
		
		m_PreviewPage = m_PreviewPages.elementAt(m_CurrentPage);
		this.doZoom();
		}
	}

//---------------------------------------------------------------------------

public void relocalize()
	{
	if (m_TitleKey != null)
		this.setTitle(Translatrix.getTranslationString(m_TitleKey));
		
	if (m_ZoomOutButton != null)
		{
		m_ZoomOutButton.setToolTipText (Translatrix.getTranslationString(c_ZoomOutTip));
		}
		
	if (m_ZoomInButton != null)
		{
		m_ZoomInButton.setToolTipText (Translatrix.getTranslationString(c_ZoomInTip));
		}
		
	if (m_ZoomOriginalButton != null)
		{
		m_ZoomOriginalButton.setToolTipText (Translatrix.getTranslationString(c_ZoomOriginalTip));
		}
		
	if (m_ZoomFillButton != null)
		{
		m_ZoomFillButton.setToolTipText (Translatrix.getTranslationString(c_ZoomFillTip));
		}
	
	if (m_PrintButton != null)
		{
		m_PrintButton.setToolTipText (Translatrix.getTranslationString(c_PrintTip));
		}
		
	if (m_PrintCurrentButton != null)
		{
		m_PrintCurrentButton.setToolTipText (Translatrix.getTranslationString(c_PrintCurrentTip));
		}
	}

//---------------------------------------------------------------------------
//***************************************************************************
//* End of Class                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

	}
