package lu.tudor.santec.gecamed.formeditor.gui.component;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.TransferHandler;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.JTextComponent;

import lu.tudor.santec.gecamed.core.gui.GECAMedIconNames;
import lu.tudor.santec.gecamed.core.gui.GECAMedModule;
import lu.tudor.santec.gecamed.core.gui.utils.GECAMedGuiUtils;
import lu.tudor.santec.gecamed.formeditor.gui.FormWidgets;
import lu.tudor.santec.gecamed.formeditor.gui.controller.EditorPanelController;
import lu.tudor.santec.gecamed.formeditor.gui.controller.FormController;
import lu.tudor.santec.gecamed.formeditor.gui.controller.converter.FormDataConverter;
import lu.tudor.santec.gecamed.formeditor.gui.model.FormModel;
import lu.tudor.santec.i18n.Translatrix;

import org.jdom.Element;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;
import com.toedter.calendar.JDateChooser;
import com.toedter.calendar.JTextFieldDateEditor;

public class EditableDateChooser extends EditableComponent {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	
	public static final int LISTERNER_METHOD_SIZE 	= 3;
	public static final int CARET_UPDATED 			= SUPER_LISTENER_METHOD_SIZE;
	public static final int ACTION_PERFORMED 		= SUPER_LISTENER_METHOD_SIZE+1;
	public static final int PROPERTY_CHANGED 		= SUPER_LISTENER_METHOD_SIZE+2;
	
	public static final String DATE_PREFIX 	= "millis=";
	public static final String TODAY 		= "TODAY";

	private Calendar calendar = new GregorianCalendar();
	private JDateChooser menuDateChooser = GECAMedGuiUtils.getDateChooser(false);
	boolean listenerDisabled = false;
	
	public EditableDateChooser () {
		super();
		// changed back to normal datechooser as other one creates problems
		component = GECAMedGuiUtils.getDateChooser(false);
		((JDateChooser)component).setCalendar(calendar);
//		component.setEnabled(false);
	}
	
	
	@Override
	protected void initType()
	{
		JTextFieldDateEditor dateEditor = getDateEditor();
		dateEditor.setEnabled(false);
		dateEditor.setName(this.getName());
		dateEditor.setTransferHandler(new TransferHandler("name"));
		dateEditor.setDropTarget(null);
		dateEditor.addCaretListener(new CaretListener() {
			
			public void caretUpdate(CaretEvent e) {
				if (!listenerDisabled && !getMenuDateEditor().getText().equals(getDateEditor().getText()))
					try {
						SwingUtilities.invokeLater(new Runnable() {
							public void run() {
								listenerDisabled = true;
								getMenuDateEditor().setText(getDateEditor().getText());		
								listenerDisabled = false;
							}
						});	
					} catch (Exception e2) {
						logger.warn(e2);
					}
			}
		});
		
//		((JDateChooser)component).add(dateEditor);
		dateEditor.addMouseListener(new EditorPanelController(this.model));

		JTextField menuDateEditor = getMenuDateEditor();
		menuDateEditor.setName("MENU date editor");
		menuDateEditor.setEditable(false);
		menuDateEditor.addCaretListener(new CaretListener() {
			
			public void caretUpdate(CaretEvent e) {
				if (!listenerDisabled && !getMenuDateEditor().getText().equals(getDateEditor().getText()))
					try {
						SwingUtilities.invokeLater(new Runnable() {
							public void run() {
								listenerDisabled = true;
								getDateEditor().setText(getMenuDateEditor().getText());
								listenerDisabled = false;
							}
						});						
					} catch (Exception e2) {
						logger.warn(e2);
					}
			}
		});
		
		super.initType();
	}
	
	@Override
	protected void addListenerMethodNames() {
		listenerMethodNames[CARET_UPDATED] 		= "caretUpdated";
		listenerMethodNames[ACTION_PERFORMED] 	= "actionPerformed";
		listenerMethodNames[PROPERTY_CHANGED] 	= "propertyChanged";
	}

	@Override
	public JComponent copyComponent(FormModel model) 
	{
		JDateChooser dateChooser = (JDateChooser) this.component;
		
		// add listener
		FormController controller = new FormController(model);
		
//		if (getFormulaAt(CARET_UPDATED).length() > 0)
//		{
			((JTextComponent)dateChooser.getDateEditor()).addCaretListener(controller);
			controller.setCodeAt(FormController.CARET_UPDATED, getScriptAt(CARET_UPDATED));
//		}
		
		if (getScriptAt(ACTION_PERFORMED).length() > 0)
		{
			dateChooser.getCalendarButton().addActionListener(controller);
			controller.setCodeAt(FormController.ACTION_PERFORMED, getScriptAt(ACTION_PERFORMED));
		}
		
		dateChooser.addPropertyChangeListener(controller);
		controller.setCodeAt(FormController.PROPERTY_CHANGE, getScriptAt(PROPERTY_CHANGED));
		
		addDefaultListener(dateChooser, controller);
		
		removeKeyListener(controller);
		((JTextFieldDateEditor)((JDateChooser)dateChooser).getDateEditor()).addKeyListener(controller);
		
		return dateChooser;
	}

	@Override
	public String getComponentType() {
//		getDateEditor().setDate(null);
		return "dateChooser";
	}

	@Override
	protected int getListenerMethodSize() {
		return LISTERNER_METHOD_SIZE;
	}

	@Override
	public String getText() {
		/* ======================================== */
		if (getDateEditor().getDate() != null) {
			return FormWidgets.formatAsInternationalDateAndTimeFormat(getDateEditor().getDate());
		} else {
			return getDateEditor().getText();
		}
		/* ======================================== */
	}

	@Override
	public void setText(String text) {
		/* ======================================== */
		if (type != FormModel.TYPE_EDITOR && text.equals(TODAY)) {
			getDateEditor().setDate(new Date(System.currentTimeMillis()));
		} else {
			Date date = FormWidgets.parseInternationalDateAndTimeFormat(text);
			
			if (date == null) {
				
				// TODO: delete when all entries in test DB are changed
//				if (text.startsWith(DATE_PREFIX)) {
//					text = text.replace(DATE_PREFIX, "");
//				}
//				Long millis = FormWidgets.parseLong(text);
//				if (millis != null) {
//					getDateEditor().setDate(new Date(millis));
//				} else {
					// TODO: THIS MUST STAY!
					getDateEditor().setText(text);
//				}
			} else {
				getDateEditor().setDate(date);
			}
		}
		/* ======================================== */
	}
	
	@Override
	public void setName (String name) {
		super.setName(name);
		getDateEditor().setName(name);
	}

	@Override
	public String getStructure() {
		return "";
	}

	@Override
	public void setStructure(String text) { }
	
	
	@Override
	public String getTypeTranslation () {
		/* ======================================== */
		return Translatrix.getTranslationString("formeditor.add_datechooser");
		/* ======================================== */
	}
	
	@Override
	protected JComponent createCaptionText()
	{
		// define the panel
		CellConstraints cc = new CellConstraints();
		
		JButton removeDateButton = new JButton(GECAMedModule.getScaledIcon(GECAMedIconNames.CANCEL, 16));
		removeDateButton.setToolTipText(Translatrix.getTranslationString("formeditor.removeDateButtonToolTip"));
		removeDateButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) 
			{
				getMenuDateEditor().setText("");
			}
		});
		
		JButton todayButton = new JButton(GECAMedModule.getScaledIcon(GECAMedIconNames.MEMO, 16));
		todayButton.setToolTipText(Translatrix.getTranslationString("formeditor.todayButtonToolTip"));
		todayButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) 
			{
				getMenuDateEditor().setText(TODAY);
			}
		});
		
		getMenuDateEditor().setText(getDateEditor().getText());
		
		JPanel innerPanel = new JPanel(new FormLayout("f:p:g, 2px, 24px, 2px, 24px", "20px"));
		innerPanel.add(menuDateChooser, cc.xy(1, 1));
		innerPanel.add(removeDateButton, cc.xy(3, 1));
		innerPanel.add(todayButton, cc.xy(5, 1));
		
//		panel.add(new NamedComponent(Translatrix.getTranslationString(
//		"formeditor.start_value"), innerPanel, true), cc.xy(2, 1));
		
		return innerPanel;
	}
	
	@Override
	public Element getDataAsXML()
	{
		Element data = new Element(getKey());
		Element text = new Element(XML_ELEMENT_TEXT);
		Element date = FormDataConverter.getDateXMLData(XML_ELEMENT_DATA, getDateEditor().getDate());
		
		text.setText(getDateEditor().getText());
		
		data.addContent(text);
		data.addContent(date);
		
		addDefaultProperties(data);
		return data;
	}
	
	
	
	private JTextFieldDateEditor getDateEditor () {
		return (JTextFieldDateEditor) ((JDateChooser)component).getDateEditor();
	}
	
	private JTextFieldDateEditor getMenuDateEditor () {
		return (JTextFieldDateEditor) menuDateChooser.getDateEditor();
	}
}
