package lu.tudor.santec.gecamed.reporting.gui.creator;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.font.TextAttribute;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import java.util.Map;
import java.util.Vector;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumnModel;
import javax.swing.table.TableModel;

import lu.tudor.santec.gecamed.core.gui.GECAMedColors;
import lu.tudor.santec.gecamed.core.gui.widgets.GECAMedBaseDialogImpl;
import lu.tudor.santec.gecamed.reporting.ejb.entity.beans.Report;
import lu.tudor.santec.gecamed.reporting.gui.ReportModule;
import lu.tudor.santec.i18n.Translatrix;

public class ReportTable extends GECAMedBaseDialogImpl implements TableCellRenderer
{
	/* ======================================== */
	// 		CONSTANTS
	/* ======================================== */
	
	private static final long	serialVersionUID	= 1L;
	
	
	
	/* ======================================== */
	// 		MEMBERS
	/* ======================================== */
	
	private static DateFormat	dateFormatter	= new SimpleDateFormat("yyyy-MM-dd");
	
	
	private JTable		table;
	
	private ActionEvent	copyEvent;
	
	
	
	/* ======================================== */
	// 		CONSTRUCTORS
	/* ======================================== */
	
	public ReportTable()
	{
		super(ReportModule.getInstance()
						.getReportList()
						.getCreatorDialog(),
				"", OK_BUTTON_MODE);
		
		JScrollPane			scroller;
		JButton				button;
		
		
		setResizingOptions(RESIZING_NONE);
		
		table		= new JTable();
		table.getTableHeader().setResizingAllowed(true);
		table.getColumnModel().setColumnSelectionAllowed(true);
		table.setOpaque(false);
		table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
		copyEvent	= new ActionEvent(table, ActionEvent.ACTION_PERFORMED, "copy");
		
		scroller	= new JScrollPane(table);
		scroller.setOpaque(false);
		scroller.getViewport().setOpaque(false);
		scroller.getVerticalScrollBar().setUnitIncrement(16);
		
		mainPanel.setLayout(new BorderLayout());
		mainPanel.add(scroller, BorderLayout.CENTER);
		
		// add copy all button
		button		= new JButton(new AbstractAction(
				"", ReportModule.getButtonIcon("copy_all.png"))
		{
			private static final long	serialVersionUID	= 1L;
			
			public void actionPerformed(ActionEvent e)
			{
				ListSelectionModel	selectionModel	= table.getSelectionModel();
				int					minSelection	= selectionModel.getMinSelectionIndex();
				int					maxSelection	= selectionModel.getMaxSelectionIndex();
				int					anchorSelection	= selectionModel.getAnchorSelectionIndex();
				
				table.selectAll();
				copyTableSelection();
				
				selectionModel.setSelectionInterval(minSelection, maxSelection);
				selectionModel.setAnchorSelectionIndex(anchorSelection);
			}
		});
		button.setToolTipText(Translatrix.getTranslationString("ReportModule.ReportTable.copyAll"));
		button.setPreferredSize(new Dimension(40, 40));
		super.addButton(button);
		
		// add copy data button
		button		= new JButton(new AbstractAction(
				"", ReportModule.getButtonIcon("copy_data.png"))
		{
			private static final long	serialVersionUID	= 1L;
			
			public void actionPerformed(ActionEvent e)
			{
				ListSelectionModel	selectionModel;
				int					minSelection;
				int					maxSelection;
				int					anchorSelection;
				
				
				if (table.getRowCount() > 0)
				{
					selectionModel	= table.getSelectionModel();
					minSelection	= selectionModel.getMinSelectionIndex();
					maxSelection	= selectionModel.getMaxSelectionIndex();
					anchorSelection	= selectionModel.getAnchorSelectionIndex();
					
					selectionModel.setSelectionInterval(1, table.getRowCount()-1);
					copyTableSelection();
					
					selectionModel.setSelectionInterval(minSelection, maxSelection);
					selectionModel.setAnchorSelectionIndex(anchorSelection);
				}
			}
		});
		button.setToolTipText(Translatrix.getTranslationString("ReportModule.ReportTable.copyData"));
		button.setPreferredSize(new Dimension(40, 40));
		super.addButton(button);
		
		// add copy selection button
		button		= new JButton(new AbstractAction(
				"", ReportModule.getButtonIcon("copy_selected.png"))
		{
			private static final long	serialVersionUID	= 1L;
			
			public void actionPerformed(ActionEvent e)
			{
				copyTableSelection();
			}
		});
		button.setToolTipText(Translatrix.getTranslationString("ReportModule.ReportTable.copySelected"));
		button.setPreferredSize(new Dimension(40, 40));
		super.addButton(button);
	}
	
	
	public void showTable (Report report)
	{
		Vector<Vector<String>>	data	= dataToString(report.getData());
		Vector<String>		headline;
		TableModel			model;
//		int					headerSize;
		TableColumnModel	columnModel;
		
		// prepare table header
		headline	= data.get(0);
		
		model		= new DefaultTableModel(data, headline);
		table.setModel(model);
		// leave the header information in the first row, but hide them
		table.setRowHeight(0, 1);
		
		columnModel	= table.getColumnModel();
		for (int index = 0; index < columnModel.getColumnCount(); index++)
			columnModel.getColumn(index).setCellRenderer(this);
		
		setTitle(Translatrix.getTranslationString("ReportModule.ReportTable.headline", 
				new String[] { report.getName() }));
		
		this.pack();
		this.centerWindowOnOwner();
		this.setVisible(true);
	}
	
	
	@SuppressWarnings("unchecked")
	public Component getTableCellRendererComponent(JTable table, Object value, 
			boolean isSelected, boolean hasFocus, int row, int column)
	{
		Map<TextAttribute, Object>	attributes;
		JLabel	label	= new JLabel();
		Color	color;
		
		
		label.setOpaque(true);
		
		// convert the value to text
		if (value instanceof Number)
			label.setText(String.valueOf(value).replace('.', ','));
		else if (value instanceof Calendar)
			label.setText(dateFormatter.format(((Calendar)value).getTime()));
		else if (value instanceof Date)
			label.setText(dateFormatter.format((Date)value));
		else label.setText(String.valueOf(value));
		
		// set the background
		if (isSelected)
			color	= table.getSelectionBackground();
		else if (row % 2 == 0)
			color	= GECAMedColors.c_OddLineBackground;
		else 
			color	= GECAMedColors.c_EvenLineBackground;
		label.setBackground(color);
		
		if (hasFocus)
			 label.setBorder(BorderFactory.createLineBorder(Color.BLACK));
		else label.setBorder(BorderFactory.createEmptyBorder());
		
		// design the headline
		attributes	= (Map<TextAttribute, Object>) label.getFont().getAttributes();
		attributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_EXTRABOLD);
		label.setFont(new Font(attributes));
		
		return label;
	}
	
	
	private void copyTableSelection ()
	{
//		TransferHandler	th	= table.getTransferHandler();
//		Clipboard		cb;
//		
//		
//		if (th == null)
			table.getActionMap().get(copyEvent.getActionCommand()).actionPerformed(copyEvent);
//		else
//		{
//			cb = Toolkit.getDefaultToolkit().getSystemClipboard();
//			th.exportToClipboard(, cb, TransferHandler.COPY);
//		}
	}
	
	
	private Vector<Vector<String>> dataToString (Vector<Vector<Object>> oData)
	{
		/* 'o' means 'original' and 's' means 'string',
		 * so 'o' is the old data and 's' the new text form data.
		 */
		Vector<Vector<String>>	sData;
		Vector<String>			sLine;
		String					sCell;
		boolean					useDecimalPoint;
		
		
		useDecimalPoint	= Locale.getDefault().getLanguage().equals(Locale.US.getLanguage());
		sData			= new Vector<Vector<String>>();
		
		for (Vector<Object> oLine : oData)
		{
			sLine	= new Vector<String>();
			sData.add(sLine);
			
			for (Object oCell : oLine)
			{
				if (oCell == null)
					sCell	= "";
				else if (oCell instanceof Calendar)
					sCell	= dateFormatter.format(((Calendar)oCell).getTime());
				else if (oCell instanceof Date)
					sCell	= dateFormatter.format((Date)oCell);
				else if (oCell instanceof Number && !useDecimalPoint)
					sCell	= String.valueOf(oCell).replace('.', ',');
				else 
					sCell	= String.valueOf(oCell);
				sLine.add(sCell);
			}
		}
		
		return sData;
	}
}
