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

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Vector;

import javax.swing.JFileChooser;
import javax.swing.filechooser.FileFilter;

import lu.tudor.santec.gecamed.core.gui.MainFrame;
import lu.tudor.santec.gecamed.reporting.ejb.entity.beans.Report;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import au.com.bytecode.opencsv.CSVWriter;

public class ReportExporter 
{
	/* ======================================== */
	// 		MEMBERS
	/* ======================================== */
	
	/** the logger Object for this class */
	private static Logger logger = Logger.getLogger(ReportExporter.class.getName());
	
	private static JFileChooser	fileChooser;
	
	private static DateFormat	dateFormatter	= new SimpleDateFormat("dd/MM/yyyy");
	
	
	
	/* ======================================== */
	// 		CLASS BODY
	/* ======================================== */
	
	public void export (Report report)
	{
		Vector<Vector<Object>>	data		= report.getData();
		File					csvFile;
		FileWriter				fileWriter;
		CSVWriter				csvWriter	= null;
		List<String[]>			lines;
		String[]				line;
		int						index;
		Object					cellObject;
		String					cellContent;
		
		
		try
		{
			// format the data into the format the CSV writer wants to have
			lines	= new ArrayList<String[]>(data.size());
			for (Vector<Object> row : data)
			{
				line	= new String[row.size()];
				
				for (index = 0; index < line.length; index++)
				{
					// convert the value to text
					cellObject	= row.get(index);
					
					if (cellObject == null)  
						cellContent	= "";
					else if (!Locale.getDefault().equals(Locale.US) && cellObject instanceof Number)
						cellContent	= String.valueOf(cellObject).replace('.', ',');
					else if (cellObject instanceof Calendar)
						cellContent	= dateFormatter.format(((Calendar)cellObject).getTime());
					else if (cellObject instanceof Date)
						cellContent	= dateFormatter.format((Date)cellObject);
					else {
						cellContent	= String.valueOf(cellObject);						
					}
					line[index]	= cellContent;
				}
				
				lines.add(line);
			}
			
			// let the user select the file to save
			csvFile		= chooseCSVFile(report.getName());
			if (csvFile == null)
				return;
			fileWriter	= new FileWriter(csvFile);
			
			// configure the CSV file
			csvWriter	= new CSVWriter(fileWriter, 
					';', 
					CSVWriter.DEFAULT_QUOTE_CHARACTER, 
					CSVWriter.DEFAULT_ESCAPE_CHARACTER, 
					System.getProperty("line.separator"));
			
			// WRITE ...
			csvWriter.writeAll(lines);
		}
		catch (IOException e)
		{
			logger.log(Level.ERROR, e.getMessage(), e);
		}
		finally
		{
			// close the stream to the file
			try
			{
				if (csvWriter != null) csvWriter.close();
			}
			catch (IOException e)
			{
				logger.log(Level.ERROR, e.getMessage(), e);
			}
		}
	}
	
	
	/**
	 * Uses a JFileChooser to let the user select the CSV file.
	 * 
	 * @return the CSV file
	 */
	private static File chooseCSVFile (String reportName)
	{
		StringBuilder	selectedFile;
		int		option;
		
		
		if (fileChooser == null)
		{
			fileChooser	= new JFileChooser();
			fileChooser.setFileFilter(new FileFilter()
			{
				
				@Override
				public String getDescription()
				{
					return ".csv";
				}
				
				
				@Override
				public boolean accept(File pathname)
				{
					return pathname.isDirectory() 
							|| pathname.getName().toLowerCase().endsWith(".csv");
				}
			});
			fileChooser.setMultiSelectionEnabled(false);
		}
		
		selectedFile	= new StringBuilder(fileChooser.getCurrentDirectory().getAbsolutePath())
				.append(File.separator)
				.append(reportName)
				.append(".csv");
		fileChooser.setSelectedFile(new File(selectedFile.toString()));
		
		option	= fileChooser.showSaveDialog(MainFrame.getInstance());
		if (option == JFileChooser.APPROVE_OPTION)
			 return fileChooser.getSelectedFile();
		else return null;
	}
}
