/*=============================================================================#
 # 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.datafilter;

import org.eclipse.core.databinding.observable.value.WritableValue;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;

import org.eclipse.statet.r.ui.dataeditor.RDataTableColumn;
import org.eclipse.statet.rj.data.RDataUtils;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RStore;
import org.eclipse.statet.rj.data.UnexpectedRDataException;
import org.eclipse.statet.rj.eclient.core.RToolService;
import org.eclipse.statet.rj.services.FunctionCall;


public class IntervalVariableFilter extends VariableFilter {
	
	
	public static final int MIN_IDX= 0;
	public static final int MAX_IDX= 1;
	public static final int NA_IDX= 2;
	
	
	private RStore minMaxData;
	
	private final WritableValue selectedLowerValue;
	private final WritableValue selectedUpperValue;
	private final WritableValue selectedNA;
	
	
	protected IntervalVariableFilter(final FilterSet set, final RDataTableColumn column) {
		super(set, column);
		
		this.selectedLowerValue= new WritableValue(set.getRealm());
		this.selectedUpperValue= new WritableValue(set.getRealm());
		this.selectedNA= new WritableValue(set.getRealm(), true, Boolean.TYPE);
		registerObservable(this.selectedLowerValue);
		registerObservable(this.selectedUpperValue);
		registerObservable(this.selectedNA);
	}
	
	
	@Override
	public FilterType getType() {
		return FilterType.INTERVAL;
	}
	
	@Override
	public void load(final VariableFilter filter) {
		if (filter.getType() == FilterType.INTERVAL
				&& filter.getColumn().getDataStore().getStoreType() == getColumn().getDataStore().getStoreType()) {
			final IntervalVariableFilter intervalFilter= (IntervalVariableFilter) filter;
			runInRealm(new Runnable() {
				@Override
				public void run() {
					if (IntervalVariableFilter.this.minMaxData == null) {
						IntervalVariableFilter.this.selectedLowerValue.setValue(intervalFilter.getSelectedLowerValue().getValue());
						IntervalVariableFilter.this.selectedUpperValue.setValue(intervalFilter.getSelectedUpperValue().getValue());
						IntervalVariableFilter.this.selectedNA.setValue(intervalFilter.getSelectedNA().getValue());
					}
				}
			});
		}
	}
	
	@Override
	public void reset() {
		runInRealm(new Runnable() {
			@Override
			public void run() {
				if (IntervalVariableFilter.this.minMaxData == null) {
					return;
				}
				IntervalVariableFilter.this.selectedLowerValue.setValue(IntervalVariableFilter.this.minMaxData.get(MIN_IDX));
				IntervalVariableFilter.this.selectedUpperValue.setValue(IntervalVariableFilter.this.minMaxData.get(MAX_IDX));
				IntervalVariableFilter.this.selectedNA.setValue(Boolean.TRUE);
			}
		});
	}
	
	@Override
	protected void update(final RToolService r,
			final IProgressMonitor monitor) throws CoreException, UnexpectedRDataException {
		final RDataTableColumn column= getColumn();
		{	final FunctionCall fcall= r.createFunctionCall("rj:::.getDataIntervalValues"); //$NON-NLS-1$
			fcall.add(column.getRExpression());
			
			final RObject data= fcall.evalData(monitor);
			RDataUtils.checkRVector(data);
			setValues(RDataUtils.checkData(data.getData(), column.getDataStore().getStoreType()));
			return;
		}
	}
	
	@Override
	protected void setError(final String message) {
		runInRealm(new Runnable() {
			@Override
			public void run() {
				IntervalVariableFilter.this.minMaxData= null;
				IntervalVariableFilter.super.setError(message);
				notifyListeners();
			}
		});
	}
	
	protected void setValues(final RStore minMaxData) {
		runInRealm(new Runnable() {
			@Override
			public void run() {
				boolean wasMin;
				{	final Object value= IntervalVariableFilter.this.selectedLowerValue.getValue();
					wasMin= (value == null || value.equals(minMaxData.get(MIN_IDX)));
				}
				boolean wasMax;
				{	final Object value= IntervalVariableFilter.this.selectedLowerValue.getValue();
					wasMax= (value == null || value.equals(minMaxData.get(MAX_IDX)));
				}
				IntervalVariableFilter.this.minMaxData= minMaxData;
				if (wasMin) {
					IntervalVariableFilter.this.selectedLowerValue.setValue(IntervalVariableFilter.this.minMaxData.get(MIN_IDX));
				}
				if (wasMax) {
					IntervalVariableFilter.this.selectedUpperValue.setValue(IntervalVariableFilter.this.minMaxData.get(MAX_IDX));
				}
				IntervalVariableFilter.super.setError(null);
				notifyListeners();
			}
		});
	}
	
	private static boolean isSmaller(final Object e1, final Object e2) {
		if (e1 instanceof Integer) {
			return (((Integer) e1).doubleValue() < ((Integer) e2).doubleValue());
		}
		return (((Number) e1).doubleValue() < ((Number) e2).doubleValue());
	}
	
	private static boolean isGreater(final Object e1, final Object e2) {
		if (e1 instanceof Integer) {
			return (((Integer) e1).doubleValue() > ((Integer) e2).doubleValue());
		}
		return (((Number) e1).doubleValue() > ((Number) e2).doubleValue());
	}
	
	@Override
	protected String createFilter(final String varExpression) {
		if (this.minMaxData == null
				|| this.selectedLowerValue.getValue() == null
				|| this.selectedUpperValue.getValue() == null) {
			return null;
		}
		final StringBuilder sb= new StringBuilder();
		sb.append('(');
		{
			final Object lower= this.selectedLowerValue.getValue();
			if (isGreater(lower, this.minMaxData.get(MIN_IDX))) {
				sb.append(varExpression);
				sb.append(" >= "); //$NON-NLS-1$
				sb.append(lower);
			}
		}
		{	final Object upper= this.selectedUpperValue.getValue();
			if (isSmaller(upper, this.minMaxData.get(MAX_IDX))) {
				if (sb.length() > 1) {
					sb.append(" & "); //$NON-NLS-1$
				}
				sb.append(varExpression);
				sb.append(" <= "); //$NON-NLS-1$
				sb.append(upper);
			}
		}
//		if (this.minMaxData.getLogi(NA_IDX)) {
			final Boolean na= (!this.minMaxData.getLogi(NA_IDX))
					|| (Boolean) this.selectedNA.getValue();
			if (na) {
				if (sb.length() > 1) {
					sb.insert(0, '(');
					sb.append(") | "); //$NON-NLS-1$
					sb.append("is.na(").append(varExpression).append(')'); //$NON-NLS-1$
				}
			}
			else { // !na
				if (sb.length() > 1) {
					sb.append(" & "); //$NON-NLS-1$
				}
				sb.append("!is.na(").append(varExpression).append(')'); //$NON-NLS-1$
			}
//		}
		sb.append(')');
		return (sb.length() <= 2) ? "" : sb.toString(); //$NON-NLS-1$
	}
	
	
	public RStore getMinMaxData() {
		return this.minMaxData;
	}
	
	
	public WritableValue getSelectedLowerValue() {
		return this.selectedLowerValue;
	}
	
	public WritableValue getSelectedUpperValue() {
		return this.selectedUpperValue;
	}
	
	public WritableValue getSelectedNA() {
		return this.selectedNA;
	}
	
}
