/*=============================================================================#
 # Copyright (c) 2012, 2017 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.internal.r.ui.datafilterview;

import static org.eclipse.statet.internal.r.ui.datafilter.IntervalVariableFilter.MAX_IDX;
import static org.eclipse.statet.internal.r.ui.datafilter.IntervalVariableFilter.MIN_IDX;
import static org.eclipse.statet.internal.r.ui.datafilter.IntervalVariableFilter.NA_IDX;

import org.eclipse.core.databinding.conversion.IConverter;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.services.IServiceLocator;

import org.eclipse.statet.ecommons.databinding.jface.DataBindingSupport;
import org.eclipse.statet.ecommons.ui.components.WaScale;
import org.eclipse.statet.ecommons.ui.content.IntValue2Double2TextBinding;
import org.eclipse.statet.ecommons.ui.content.IntValue2TextBinding;
import org.eclipse.statet.ecommons.ui.util.LayoutUtil;

import org.eclipse.statet.internal.r.ui.datafilter.IntervalVariableFilter;
import org.eclipse.statet.rj.data.RStore;


public class IntervalClient extends FilterClient {
	
	
	private WaScale scaleControl;
	
	private Text lowerBoundControl;
	private Text upperBoundControl;
	
	private Object lowerUpperGroup;
	
	private final IntervalVariableFilter filter;
	
	private Button NAControl;
	
	
	public IntervalClient(final VariableComposite parent, final IntervalVariableFilter filter) {
		super(parent);
		
		this.filter= filter;
		filter.setListener(this);
		
		init(5);
	}
	
	
	@Override
	public IntervalVariableFilter getFilter() {
		return this.filter;
	}
	
	@Override
	protected void addWidgets() {
		this.scaleControl= new WaScale(this, SWT.HORIZONTAL);
		this.scaleControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 5, 1));
		
		this.lowerBoundControl= new Text(this, SWT.BORDER);
		this.lowerBoundControl.setLayoutData(LayoutUtil.hintWidth(
				new GridData(SWT.FILL, SWT.CENTER, true, false), this.lowerBoundControl, 10 ));
		this.lowerBoundControl.setToolTipText(Messages.Interval_LowerBound_tooltip);
		
		LayoutUtil.addGDDummy(this, true);
		
		this.NAControl= new Button(this, SWT.CHECK);
		this.NAControl.setText("NA"); //$NON-NLS-1$
		this.NAControl.setFont(JFaceResources.getFontRegistry().getItalic(JFaceResources.DIALOG_FONT));
		this.NAControl.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false));
		
		LayoutUtil.addGDDummy(this, true);
		
		this.upperBoundControl= new Text(this, SWT.BORDER);
		this.upperBoundControl.setLayoutData(LayoutUtil.hintWidth(
				new GridData(SWT.FILL, SWT.CENTER, true, false), this.lowerBoundControl, 10 ));
		this.upperBoundControl.setToolTipText(Messages.Interval_UpperBound_tooltip);
	}
	
	@Override
	protected void initActions(final IServiceLocator serviceLocator) {
	}
	
	@Override
	protected void addBindings(final DataBindingSupport db) {
		if (this.filter.getColumn().getDataStore().getStoreType() == RStore.NUMERIC) {
			final IConverter text2value= new Text2NumConverter();
			final IConverter value2text= new Num2TextConverter();
//			{	RDataFormatter colFormatter= this.filter.getColumn().getDefaultFormat();
//				if (colFormatter != null && colFormatter.hasNumFormat()) {
//					RDataFormatter textFormatter= new RDataFormatter();
//					textFormatter.initNumFormat(colFormatter.getMaxFractionalDigits() + 1,
//							colFormatter.getMaxExponentDigits() );
//					value2text= new RDataFormatterConverter(Double.TYPE, textFormatter);
//				}
//			}
			final IntValue2Double2TextBinding.LowerUpperGroup group= new IntValue2Double2TextBinding.LowerUpperGroup(
					this.scaleControl, this.lowerBoundControl, this.upperBoundControl,
					db.getRealm(), value2text, text2value );
			db.getContext().bindValue(group.getLower(),
					this.filter.getSelectedLowerValue() );
			db.getContext().bindValue(group.getUpper(),
					this.filter.getSelectedUpperValue() );
			this.lowerUpperGroup= group;
		}
		else {
			final IConverter text2value= new Text2IntConverter();
			final IConverter value2text= new Int2TextConverter();
			final IntValue2TextBinding.LowerUpperGroup group= new IntValue2TextBinding.LowerUpperGroup(
					this.scaleControl, this.lowerBoundControl, this.upperBoundControl,
					db.getRealm(), value2text, text2value );
			db.getContext().bindValue(group.getLower(),
					this.filter.getSelectedLowerValue() );
			db.getContext().bindValue(group.getUpper(),
					this.filter.getSelectedUpperValue() );
			this.lowerUpperGroup= group;
		}
		db.getContext().bindValue(SWTObservables.observeSelection(this.NAControl),
				this.filter.getSelectedNA() );
	}
	
	@Override
	protected void updateInput() {
		final RStore minMaxData= this.filter.getMinMaxData();
		if (minMaxData == null) {
			setEnabled(false, false);
			return;
		}
		
		if (this.lowerUpperGroup instanceof IntValue2Double2TextBinding.LowerUpperGroup) {
			final double min= minMaxData.getNum(MIN_IDX);
			final double max= minMaxData.getNum(MAX_IDX);
			setEnabled((min != max), minMaxData.getLogi(NA_IDX));
			((IntValue2Double2TextBinding.LowerUpperGroup) this.lowerUpperGroup).setMinMax(
					min, max );
		}
		else {
			final int min= minMaxData.getInt(MIN_IDX);
			final int max= minMaxData.getInt(MAX_IDX);
			setEnabled((min != max), minMaxData.getLogi(NA_IDX));
			((IntValue2TextBinding.LowerUpperGroup) this.lowerUpperGroup).setMinMax(
					min, max );
		}
	}
	
	public void setEnabled(final boolean scale, final boolean na) {
		if (this.scaleControl.getEnabled() != scale) {
			this.scaleControl.setEnabled(scale);
			this.lowerBoundControl.setEnabled(scale);
			this.upperBoundControl.setEnabled(scale);
		}
		if (this.NAControl.getEnabled() != na) {
			this.NAControl.setEnabled(na);
			this.NAControl.setVisible(na);
		}
	}
	
}
