/**
 * Copyright (c) 2011, 2015 - Lunifera GmbH (Gross Enzersdorf, Austria), Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0 
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *         Florian Pirchner - Initial implementation
 */
package org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;

import org.eclipse.core.databinding.Binding;
import org.eclipse.core.databinding.observable.IObservable;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.emf.databinding.EMFObservables;
import org.eclipse.osbp.ecview.core.common.editpart.IElementEditpart;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableBindingEndpoint;
import org.eclipse.osbp.ecview.core.common.model.core.YEmbeddableValueEndpoint;
import org.eclipse.osbp.ecview.core.common.model.datatypes.YDatatype;
import org.eclipse.osbp.ecview.core.emf.api.IDateFormatProvider;
import org.eclipse.osbp.ecview.core.emf.api.IDateFormatProvider.Info;
import org.eclipse.osbp.ecview.core.extension.model.datatypes.YDateTimeDatatype;
import org.eclipse.osbp.ecview.core.extension.model.datatypes.YDateTimeFormat;
import org.eclipse.osbp.ecview.core.extension.model.datatypes.YDateTimeResolution;
import org.eclipse.osbp.ecview.core.extension.model.extension.ExtensionModelPackage;
import org.eclipse.osbp.ecview.core.extension.model.extension.YDateTime;
import org.eclipse.osbp.ecview.core.ui.core.editparts.extension.IDateTimeEditpart;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.AbstractFieldWidgetPresenter;
import org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.internal.util.Util;

import com.vaadin.data.util.ObjectProperty;
import com.vaadin.server.ErrorMessage;
import com.vaadin.server.FontAwesome;
import com.vaadin.shared.ui.datefield.Resolution;
import com.vaadin.ui.Button;
import com.vaadin.ui.Component;
import com.vaadin.ui.ComponentContainer;
import com.vaadin.ui.DateField;
import com.vaadin.ui.Field;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.UI;
import com.vaadin.ui.themes.ValoTheme;

/**
 * This presenter is responsible to render a text area on the given layout.
 */
public class DateTimePresentation extends AbstractFieldWidgetPresenter<Component> {

	/** The model access. */
	private final ModelAccess modelAccess;

	/** The date field. */
	private CustomField dateField;

	/** The binding_value to ui. */
	private Binding binding_valueToUI;

	/** The property. */
	private ObjectProperty<Date> property;

	/** The format info. */
	private Info formatInfo;

	/**
	 * Constructor.
	 * 
	 * @param editpart
	 *            The editpart of that presenter
	 */
	public DateTimePresentation(IElementEditpart editpart) {
		super((IDateTimeEditpart) editpart);
		this.modelAccess = new ModelAccess((YDateTime) editpart.getModel());
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public Component doCreateWidget(Object parent) {
		if (dateField == null) {
			dateField = new CustomField();
			dateField.initField();
			dateField.addStyleName(CSS_CLASS_CONTROL);
			dateField.setImmediate(true);
			setupComponent(dateField.field, getCastedModel());

			associateWidget(dateField.field, modelAccess.yField);
			if (modelAccess.isCssIdValid()) {
				dateField.setId(modelAccess.getCssID());
			} else {
				dateField.setId(getEditpart().getId());
			}

			property = new ObjectProperty<>(null, Date.class);
			dateField.setPropertyDataSource(property);
			
			// creates the binding for the field
			createBindings(modelAccess.yField, dateField);

			if (modelAccess.isCssClassValid()) {
				dateField.addStyleName(modelAccess.getCssClass());
			}

			doApplyDatatype(modelAccess.yField.getDatatype());

			applyCaptions();

			initializeField(dateField);
		}
		return dateField;
	}

	/**
	 * Applies the datatype options to the field.
	 *
	 * @param yDt
	 *            the y dt
	 */
	@Override
	protected void doApplyDatatype(YDatatype yDt) {
		if (dateField == null) {
			return;
		}

		IDateFormatProvider service = getViewContext().getService(IDateFormatProvider.class.getName());
		YDateTimeDatatype yDatatype = (YDateTimeDatatype) yDt;
		if (service != null) {
			formatInfo = service.getInfo(yDatatype, UI.getCurrent().getLocale());
		} else {
			formatInfo = new DefaultDateFormatProvider().getInfo(yDatatype, UI.getCurrent().getLocale());
		}
		if ( yDatatype != null )  {
			dateField.setShowISOWeekNumber(yDatatype.isShowISOWeekNumbersActive());
		} else {
			dateField.setShowISOWeekNumber(false);		
		}
		dateField.setDateFormat(formatInfo.getDateFormat());
		dateField.setResolution(mapToVaadin(formatInfo.getResolution()));
	}

	/**
	 * Map to vaadin.
	 *
	 * @param resolution
	 *            the resolution
	 * @return the resolution
	 */
	private Resolution mapToVaadin(YDateTimeResolution resolution) {
		switch (resolution) {
		case YEAR:
			return Resolution.YEAR;
		case MONTH:
			return Resolution.MONTH;
		case DAY:
			return Resolution.DAY;
		case HOUR:
			return Resolution.HOUR;
		case MINUTE:
			return Resolution.MINUTE;
		case SECOND:
			return Resolution.SECOND;
		case UNDEFINED:
			return Resolution.DAY;
		}

		return Resolution.DAY;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractVaadinWidgetPresenter#doUpdateLocale(java.util.Locale)
	 */
	@Override
	protected void doUpdateLocale(Locale locale) {
		// need to refresh the locale datetime pattern
		doApplyDatatype(modelAccess.yField.getDatatype());
		// update the captions
		applyCaptions();
	}

	/**
	 * Applies the labels to the widgets.
	 */
	protected void applyCaptions() {
		Util.applyCaptions(getI18nService(), modelAccess.getLabel(), modelAccess.getLabelI18nKey(), getLocale(),
				dateField);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractFieldWidgetPresenter#doGetField()
	 */
	@Override
	protected Field<?> doGetField() {
		return dateField;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see org.eclipse.osbp.runtime.web.ecview.presentation.vaadin.common.
	 * AbstractVaadinWidgetPresenter#internalGetObservableEndpoint(org.eclipse.
	 * osbp.ecview.core.common.model.core.YEmbeddableBindingEndpoint)
	 */
	@Override
	protected IObservable internalGetObservableEndpoint(YEmbeddableBindingEndpoint bindableValue) {
		if (bindableValue == null) {
			throw new IllegalArgumentException("BindableValue must not be null!");
		}

		if (bindableValue instanceof YEmbeddableValueEndpoint) {
			return internalGetValueEndpoint();
		}
		throw new IllegalArgumentException("Not a valid input: " + bindableValue);
	}

	/**
	 * Returns the observable to observe value.
	 *
	 * @return the i observable value
	 */
	protected IObservableValue internalGetValueEndpoint() {
		// return the observable value for text
		return EMFObservables.observeValue(castEObject(getModel()), ExtensionModelPackage.Literals.YDATE_TIME__VALUE);
	}

	/**
	 * Creates the bindings for the given values.
	 *
	 * @param yField
	 *            the y field
	 * @param customfield
	 *            the field
	 */
	protected void createBindings(YDateTime yField, CustomField customfield) {
		// create the model binding from widget to ECView-model
		binding_valueToUI = createBindingsValue(castEObject(getModel()),
				ExtensionModelPackage.Literals.YDATE_TIME__VALUE, customfield.field, null, null);
		registerBinding(binding_valueToUI);

		super.createBindings(yField, customfield.field, null);
	}

	
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#
	 * getWidget()
	 */
	@Override
	public Component getWidget() {
		return dateField;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.eclipse.osbp.ecview.core.common.presentation.IWidgetPresentation#
	 * isRendered()
	 */
	@Override
	public boolean isRendered() {
		return dateField != null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void doUnrender() {
		if (dateField != null) {

			// unbind all active bindings
			unbind();

			Component parent = (dateField.getParent());
			if (parent != null && parent instanceof ComponentContainer) {
				((ComponentContainer) parent).removeComponent(dateField);
			}

			// remove assocations
			unassociateWidget(dateField);

			dateField = null;
		}
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void internalDispose() {
		try {
			unrender();
		} finally {
			super.internalDispose();
		}

		if (binding_valueToUI != null) {
			binding_valueToUI.dispose();
			binding_valueToUI = null;
		}
	}
	
	/**
	 * A helper class.
	 */
	private static class ModelAccess {

		/** The y field. */
		private final YDateTime yField;

		/**
		 * Instantiates a new model access.
		 *
		 * @param yField
		 *            the y field
		 */
		public ModelAccess(YDateTime yField) {
			super();
			this.yField = yField;
		}

		/**
		 * Gets the css class.
		 *
		 * @return the css class
		 * @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssClass()
		 */
		public String getCssClass() {
			return yField.getCssClass();
		}

		/**
		 * Returns true, if the css class is not null and not empty.
		 *
		 * @return true, if is css class valid
		 */
		public boolean isCssClassValid() {
			return getCssClass() != null && !getCssClass().equals("");
		}

		/**
		 * Gets the css id.
		 *
		 * @return the css id
		 * @see org.eclipse.osbp.ecview.core.ui.core.model.core.YCssAble#getCssID()
		 */
		public String getCssID() {
			return yField.getCssID();
		}

		/**
		 * Returns true, if the css id is not null and not empty.
		 *
		 * @return true, if is css id valid
		 */
		public boolean isCssIdValid() {
			return getCssID() != null && !getCssID().equals("");
		}

		/**
		 * Returns the label.
		 *
		 * @return the label
		 */
		public String getLabel() {
			return yField.getDatadescription() != null ? yField.getDatadescription().getLabel() : null;
		}

		/**
		 * Returns the label.
		 *
		 * @return the label i18n key
		 */
		public String getLabelI18nKey() {
			return yField.getDatadescription() != null ? yField.getDatadescription().getLabelI18nKey() : null;
		}

		/**
		 * Returns true, if the date format is valid.
		 *
		 * @return true, if is dateformat valid
		 */
		@SuppressWarnings("unused")
		public boolean isDateformatValid() {
			return yField.getDatadescription() != null && yField.getDatatype().getFormat() != null;
		}
	}

	/**
	 * The Class CustomField.
	 */
	@SuppressWarnings("serial")
	private class CustomField extends com.vaadin.ui.CustomField<Date> {
		private DateField field;
		private Button resetDate;
		private ObjectProperty<Date> property;
		private boolean showISOWeekNumber;

		@Override
		protected Component initContent() {
			field.setShowISOWeekNumbers(showISOWeekNumber);
			property.addValueChangeListener(e -> {
				super.setValue((Date) e.getProperty().getValue());
			});
			resetDate = new Button();
			resetDate.setIcon(FontAwesome.CALENDAR_CHECK_O);
			resetDate.addClickListener(e -> {
				property.setValue(new Date(System.currentTimeMillis()));
				super.focus();
			});
			
			setFocusDelegate(field);
			
			resetDate.setVisible(field.isVisible());
			resetDate.setEnabled(field.isEnabled());
			if(field.isReadOnly()){
				resetDate.setVisible(false);
			}
			
			HorizontalLayout layout = new HorizontalLayout(field, resetDate);
			layout.setStyleName(ValoTheme.LAYOUT_COMPONENT_GROUP);
			return layout;
		}
		
		public void setShowISOWeekNumber(boolean value) {
			showISOWeekNumber = value;
		}

		void initField(){
			field = new DateField();
		}
		
		public void setResolution(Resolution res) {
			field.setResolution(res);
		}

		public void setDateFormat(String dateFormat) {
			field.setDateFormat(dateFormat);
		}
		
		public void setPropertyDataSource(ObjectProperty<Date> property){
			this.property = property;
			field.setPropertyDataSource(property);
		}

		@Override
		public Class<Date> getType() {
			return Date.class;
		}

		@Override
		protected void setInternalValue(Date newValue) {
			super.setInternalValue(newValue);

			if (property != null) {
				property.setValue(newValue);
			}
		}

		/*
		 * (non-Javadoc)
		 * 
		 * @see com.vaadin.ui.AbstractField#getErrorMessage()
		 */
		@Override
		public ErrorMessage getErrorMessage() {
			if (isDisposed()) {
				// after disposal, Vaadin will call this method once.
				return null;
			}

			ErrorMessage message = super.getErrorMessage();
			reportValidationError(message);
			return message;
		}
	}

	/**
	 * The Class DefaultDateFormatProvider.
	 */
	private static class DefaultDateFormatProvider implements IDateFormatProvider {

		/*
		 * (non-Javadoc)
		 * 
		 * @see
		 * org.eclipse.osbp.ecview.core.emf.api.IDateFormatProvider#getInfo(org.
		 * eclipse.osbp.ecview.core.extension.model.datatypes.YDateTimeDatatype,
		 * java.util.Locale)
		 */
		@Override
		public Info getInfo(YDateTimeDatatype yDt, Locale locale) {

			if (yDt == null) {
				DateFormat formatter = DateFormat.getDateInstance(DateFormat.DEFAULT, locale);
				return new IDateFormatProvider.Info(((SimpleDateFormat) formatter).toPattern(),
						YDateTimeResolution.DAY);
			}

			DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, locale);
			String pattern = ((SimpleDateFormat) formatter).toPattern();

			String dateFormat = null;
			String rightpattern = null;
			YDateTimeResolution resolution = calcResolution(yDt);
			YDateTimeFormat yFormat = yDt.getFormat();
			if (yFormat != null) {
				switch (yFormat) {
				case DATE:
					switch (resolution) {
					case YEAR:
						dateFormat = filterFormat(pattern, "yyyy");
						break;
					case MONTH:
						dateFormat = filterFormat(pattern, "yyyy.MM");
						break;
					case DAY:
						dateFormat = filterFormat(pattern, "yyyy.MM.dd");
						break;
					default:
						throw new IllegalArgumentException(resolution + " is not a valid resolution for " + yFormat);
					}
					break;
				case DATE_TIME:
					switch (resolution) {
					case YEAR:
						dateFormat = filterFormat(pattern, "yyyy");
						break;
					case MONTH:
						dateFormat = filterFormat(pattern, "yyyy.MM");
						break;
					case DAY:
						dateFormat = filterFormat(pattern, "yyyy.MM.dd");
						break;
					case HOUR:
						rightpattern = pattern.contains("a") ? "yyyy.MM.dd hhHH a" : "yyyy.MM.dd hhHH";
						dateFormat = filterFormat(pattern, rightpattern);
						break;
					case MINUTE:
						rightpattern = pattern.contains("a") ? "yyyy.MM.dd hhHH:mm a" : "yyyy.MM.dd hhHH:mm";
						dateFormat = filterFormat(pattern, rightpattern);
						break;
					case SECOND:
						rightpattern = pattern.contains("a") ? "yyyy.MM.dd hhHH:mm:ss a" : "yyyy.MM.dd hhHH:mm:ss";
						dateFormat = filterFormat(pattern, rightpattern);
						break;
					default:
						throw new IllegalArgumentException(resolution + " is not a valid resolution for " + yFormat);
					}
					break;
				case TIME:
					switch (resolution) {
					case HOUR:
						rightpattern = pattern.contains("a") ? "hhHH a" : "hhHH";
						dateFormat = filterFormat(pattern, rightpattern);
						break;
					case MINUTE:
						rightpattern = pattern.contains("a") ? "hhHH:mm a" : "hhHH:mm";
						dateFormat = filterFormat(pattern, rightpattern);
						break;
					case SECOND:
						rightpattern = pattern.contains("a") ? "hhHH:mm:ss a" : "hhHH:mm:ss";
						dateFormat = filterFormat(pattern, rightpattern);
						break;
					default:
						throw new IllegalArgumentException(resolution + " is not a valid resolution for " + yFormat);
					}
					break;
				}
			}
			return new IDateFormatProvider.Info(dateFormat, resolution);
		}

		/**
		 * filters from any localized date-time pattern the desired subset
		 * defined by filterPattern without destroying the original localized
		 * pattern .
		 *
		 * @param localizedPattern
		 *            the localized full date-time pattern
		 * @param filterPattern
		 *            the subset of desired date-time formatter patterns
		 * @return the string
		 */
		private String filterFormat(String localizedPattern, String filterPattern) {
			// remove any multiple characters sequences and remove all separator
			// signs from filterPattern
			String filter = filterPattern.replaceAll("(.)\\1+", "$1").replaceAll("[^\\w\\s]", "") + ",";
			// create a replacement pattern to remove unnecessary blanks
			// disturbing the recognition of orphaned separators
			// rule: each blank must be surrounded by any filter-letter to be
			// valid
			String invalidBlanks = "(?![" + filter + "])( )(?![" + filter + "])";
			// create a replacement pattern to remove remaining separators
			// without formatting function
			// rule: each separator must be surrounded by any filter-letter or
			// blank to be valid
			String invalidSeparators = "(?![" + filter + " ])([.:])(?![" + filter + " ])";
			
			String dateFormat = localizedPattern.replaceAll("[^" + filter + ",.: ]", "").replaceAll(invalidBlanks, "").trim()
					.replaceAll(invalidSeparators, "");
			if(dateFormat.startsWith(",") || dateFormat.startsWith(".")){ dateFormat = dateFormat.substring(1); }
			return dateFormat;
		}

		/**
		 * Calc resolution.
		 *
		 * @param yDt
		 *            the y dt
		 * @return the y date time resolution
		 */
		private YDateTimeResolution calcResolution(YDateTimeDatatype yDt) {
			YDateTimeFormat yFormat = yDt.getFormat();
			YDateTimeResolution resolution = null;
			if (yFormat != null) {
				YDateTimeResolution yResolution = yDt.getResolution();
				switch (yFormat) {
				case DATE:
					if (yResolution == YDateTimeResolution.UNDEFINED || yResolution == YDateTimeResolution.SECOND
							|| yResolution == YDateTimeResolution.MINUTE || yResolution == YDateTimeResolution.HOUR) {
						resolution = YDateTimeResolution.DAY;
					}
					break;
				case DATE_TIME:
					if (yResolution == YDateTimeResolution.UNDEFINED || yResolution == YDateTimeResolution.DAY
							|| yResolution == YDateTimeResolution.MONTH || yResolution == YDateTimeResolution.YEAR) {
						resolution = YDateTimeResolution.MINUTE;
					}
					break;
				case TIME:
					if (yResolution == YDateTimeResolution.UNDEFINED || yResolution == YDateTimeResolution.DAY
							|| yResolution == YDateTimeResolution.MONTH || yResolution == YDateTimeResolution.YEAR) {
						resolution = YDateTimeResolution.MINUTE;
					}
					break;
				}
			}

			if (resolution == null) {
				switch (yDt.getResolution()) {
				case SECOND:
					resolution = YDateTimeResolution.SECOND;
					break;
				case MINUTE:
					resolution = YDateTimeResolution.MINUTE;
					break;
				case HOUR:
					resolution = YDateTimeResolution.HOUR;
					break;
				case DAY:
					resolution = YDateTimeResolution.DAY;
					break;
				case MONTH:
					resolution = YDateTimeResolution.MONTH;
					break;
				case YEAR:
					resolution = YDateTimeResolution.YEAR;
					break;
				case UNDEFINED:
					resolution = YDateTimeResolution.MINUTE;
					break;
				default:
					resolution = YDateTimeResolution.MINUTE;
				}
			}

			return resolution;
		}

	}
}
