package lu.tudor.santec.gecamed.formeditor.gui.view.dialog;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;

import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;

import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.widgets.NamedComponent;
import lu.tudor.santec.gecamed.formeditor.gui.FormEditorModule;
import lu.tudor.santec.gecamed.formeditor.gui.FormWidgets;
import lu.tudor.santec.gecamed.formeditor.gui.component.EditableComponent;
import lu.tudor.santec.gecamed.formeditor.gui.component.EditableDateChooser;
import lu.tudor.santec.gecamed.formeditor.gui.component.EditableNumericTextField;
import lu.tudor.santec.gecamed.formeditor.gui.model.ComboBoxElement;
import lu.tudor.santec.i18n.Translatrix;

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

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

public class FormEditorCSVImportDialog extends CSVImportDialog {
	
	private HashMap<Integer, String> patternMap = new HashMap<Integer, String>();
	
	/** the logger Object for this class */
	private static Logger logger = Logger.getLogger(FormEditorCSVImportDialog.class.getName());
	

	public FormEditorCSVImportDialog(Component parent) {
		super(parent, Translatrix.getTranslationString("formeditor.importCsvFile"), 
				Translatrix.getTranslationString("formeditor.importFormsDescription"));
	}
	
	public FormEditorCSVImportDialog (Component parent, String title, String description) {
		super(parent, title, description);
	}

	@Override
	protected boolean checkMapping () {
		/* ======================================== */
		if (!super.isFileLoaded()) {
			warningLabel.setText("");
			
			return false;
		}
		
		HashMap<ComboBoxElement<?>, Integer> testMap = new HashMap<ComboBoxElement<?>, Integer>();
		
		boolean isCreationDateSet = false;
		
		for (Integer col : columnMap.keySet()) {
			ComboBoxElement<?> elem = columnMap.get(col);
			
			if (elem == null 
					|| elem.getTranslation() == null
					|| elem.getTranslation().equals("")) {
				continue;
			}
			
			Integer i = testMap.put(elem, col);
			
			if (i != null) {
				this.warningLabel.setText(
						Translatrix.getTranslationString("formeditor.duplicateEntry")
								.replace("$a", String.valueOf(i+1))
								.replace("$b", String.valueOf(col+1)));
				return false;
			}
			
			if (!isCreationDateSet && elem.toString().equals(EditableComponent.CREATION_DATE_REF)) {
				isCreationDateSet = true;
			}
		}
		
		if (!isCreationDateSet) {
			this.warningLabel.setText(Translatrix.getTranslationString("formeditor.creationDateNotMapped"));
		} else {
			this.warningLabel.setText("");
		}
		
		return isCreationDateSet;
		/* ======================================== */
	}
	

	
	protected JPanel createSettingsPanelForClass (Class<?> type, final int selectedColumn) {
		JPanel p = new JPanel();
		p.setOpaque(false);
		
		Object typeInstance;
		try {
			typeInstance = type.newInstance();
		} catch (Exception e) {
			return p;
		}
		
		if (typeInstance instanceof Date
				|| typeInstance instanceof EditableDateChooser) {
			/* ---------------------------------------- */
			final JComboBox box = new JComboBox(DEFAULT_DATE_PATTERN);
			box.setEditable(true);
			String pattern = patternMap.get(selectedColumn);
			if (pattern == null) {
				box.setSelectedIndex(0);
				patternMap.put(selectedColumn, (String)box.getSelectedItem());
			} else {
				box.setSelectedItem(pattern);
			}
			
			box.addActionListener(new ActionListener() {
				
				public void actionPerformed(ActionEvent e) {
					String pattern = (String)box.getSelectedItem();
					patternMap.put(selectedColumn, pattern);
				}
			});
			
			JLabel infoLabel = new JLabel(GECAMedModule.getScaledIcon(GECAMedIconNames.INFO, 30));
			
			
			// set the tool tip for the infoLabel
			StringBuffer html = new StringBuffer();
			BufferedReader reader = null;
			try {
				// read the HTML-file that contains the description
				reader = new BufferedReader(new FileReader(
						FormWidgets.getFile(FormEditorModule.class, "datePattern.html")));
//						new File(FormEditorModule.class.getResource("resources").getPath() +
//								FormWidgets.FOLDER_SEPARATOR + "datePattern.html")));
				
				String line;
				while ((line = reader.readLine()) != null) {
					html.append(line);
				}
				
			} catch (Exception e) {
				logger.log(Level.ERROR, e.getMessage(), e);
				
				html.append("formeditor.descriptionNotAvailable");
			}
			finally
			{
				try
				{
					if (reader != null) reader.close();
				}
				catch (IOException e)
				{
					logger.log(Level.ERROR, e.getMessage(), e);
				}
			}
			
			
			infoLabel.setToolTipText(html.toString());
			
			p.setLayout(new FormLayout("p, 3px, p", "p"));
			p.add(new NamedComponent(
					Translatrix.getTranslationString("formeditor.datePattern"),
					box), new CellConstraints(1, 1));
			p.add(infoLabel, new CellConstraints(3, 1, 
					CellConstraints.LEFT, CellConstraints.CENTER));
			/* ---------------------------------------- */
		}
		
		return p;
	}
	
	
	
	protected Object stringToObject (String value, int column) throws Exception {
		/* ======================================== */
		ComboBoxElement<Class<?>> item = columnMap.get(column);
		
		if (item == null) {
			return null;
		}
//		String key = item.getTranslation();
		Class<?> clazz = (Class<?>) item.getValue();
		
		
		if (clazz == null) {
			clazz = String.class;
		}
		
		Object clazzInstance;
		try {
			clazzInstance = clazz.newInstance();
		} catch (Exception e) {
			clazzInstance = "";
		}
		
		Object o = value;
		if (clazzInstance instanceof Date
				|| clazzInstance instanceof EditableDateChooser) {
			// a date:
			String pattern = this.patternMap.get(column);
			DateFormat format = new SimpleDateFormat(pattern);
			o = format.parse(value);
		} else if (clazzInstance instanceof Number
				|| clazzInstance instanceof EditableNumericTextField) {
			// a number:
			o = Double.parseDouble(value.replace(",", "."));
		}
		
		return o;
		/* ======================================== */
	}
}
