/*=============================================================================#
 # Copyright (c) 2012, 2019 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 java.util.ArrayList;
import java.util.List;

import org.eclipse.core.databinding.observable.Realm;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.services.IServiceLocator;

import org.eclipse.statet.ecommons.ui.util.LayoutUtils;

import org.eclipse.statet.internal.r.ui.dataeditor.RDataLabelProvider;
import org.eclipse.statet.internal.r.ui.dataeditor.RDataTableContentDescription;
import org.eclipse.statet.internal.r.ui.datafilter.FilterSet;
import org.eclipse.statet.internal.r.ui.datafilter.IFilterListener;
import org.eclipse.statet.internal.r.ui.datafilter.IntervalVariableFilter;
import org.eclipse.statet.internal.r.ui.datafilter.LevelVariableFilter;
import org.eclipse.statet.internal.r.ui.datafilter.TextVariableFilter;
import org.eclipse.statet.internal.r.ui.datafilter.VariableFilter;
import org.eclipse.statet.r.ui.dataeditor.RDataTableColumn;


public class VariableContainer {
	
	
	private final IServiceLocator serviceLocator;
	
	private final ScrolledPageComposite variableComposite;
	
	private final List<VariableComposite> variables;
	
	private final RDataLabelProvider labelProvider;
	
	private final FilterSet filterSet;
	
	private RDataTableContentDescription description;
	
	
	public VariableContainer(final IServiceLocator serviceLocator, final ScrolledPageComposite variableComposite) {
		this.serviceLocator= serviceLocator;
		this.variableComposite= variableComposite;
		this.variables= new ArrayList<>();
		
		this.variableComposite.getContent().setLayout(LayoutUtils.newContentGrid(1));
		
		this.labelProvider= new RDataLabelProvider();
		
		this.filterSet= new FilterSet(Realm.getDefault()) {
			@Override
			protected void filterRemoved(final VariableFilter oldFilter) {
				final int vIdx= getVariable(oldFilter);
				if (vIdx >= 0) {
					final VariableComposite composite= VariableContainer.this.variables.remove(vIdx);
					composite.dispose();
				}
			}
			@Override
			protected void filterReplaced(final int idx, final VariableFilter oldFilter, final VariableFilter newFilter) {
				final int vIdx= getVariable(oldFilter);
				if (vIdx >= 0) {
					final VariableComposite composite= VariableContainer.this.variables.get(vIdx);
					composite.setColumn(newFilter.getColumn());
					final FilterClient oldClient= composite.getClient();
					createFilterClient(composite, newFilter);
					oldClient.dispose();
					if (vIdx != idx) {
						VariableContainer.this.variables.remove(vIdx);
						VariableContainer.this.variables.add(idx, composite);
					}
					composite.layout(new Control[] { composite.getClient() });
				}
				else {
					filterAdded(idx, newFilter);
				}
			}
			@Override
			protected void filterAdded(final int idx, final VariableFilter newFilter) {
				final VariableComposite composite= createVariable(newFilter.getColumn());
				createFilterClient(composite, newFilter);
				VariableContainer.this.variables.add(idx, composite);
			}
		};
		
		this.filterSet.addPostListener(new IFilterListener() {
			@Override
			public void filterChanged() {
				for (final VariableComposite variable : VariableContainer.this.variables) {
					variable.updateImage(false);
				}
			}
		});
	}
	
	
	public void updateInput(final RDataTableContentDescription description) {
		this.description= description;
		
		this.variableComposite.setRedraw(false);
		this.variableComposite.setDelayedReflow(true);
		try {
			this.filterSet.updateInput(description);
			
			if (this.variables.size() == 1) {
				this.variables.get(0).setExpanded(true);
			}
		}
		finally {
			this.variableComposite.setDelayedReflow(false);
			this.variableComposite.setRedraw(true);
			this.variableComposite.reflow(true);
		}
	}
	
	public RDataTableContentDescription getDescription() {
		return this.description;
	}
	
	protected FilterClient createFilterClient(final VariableComposite composite, final VariableFilter filter) {
		if (filter == null) {
			return null;
		}
		FilterClient client;
		switch (filter.getType().getId()) {
		case 0:
			client= new LevelClient(composite, (LevelVariableFilter) filter);
			break;
		case 1:
			client= new IntervalClient(composite, (IntervalVariableFilter) filter);
			break;
		case 2:
			client= new TextClient(composite, (TextVariableFilter) filter);
			break;
		default:
			throw new IllegalStateException(filter.toString());
		}
		this.variableComposite.adaptChild(client);
		
		return client;
	}
	
	protected VariableComposite createVariable(final RDataTableColumn column) {
		final VariableComposite expandable= new VariableComposite(
				this.variableComposite.getContent(), this, column);
		expandable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
//		expandable.setExpanded(true);
		this.variableComposite.adaptChild(expandable);
		
		return expandable;
	}
	
	
	public FilterSet getFilterSet() {
		return this.filterSet;
	}
	
	public IServiceLocator getServiceLocator() {
		return this.serviceLocator;
	}
	
	public ScrolledPageComposite getVariableComposite() {
		return this.variableComposite;
	}
	
	public List<VariableComposite> getVariables() {
		return this.variables;
	}
	
	protected int getVariable(final VariableFilter filter) {
		for (int i= 0; i < this.variables.size(); i++) {
			final FilterClient client= this.variables.get(i).getClient();
			if (client != null && client.getFilter() == filter) {
				return i;
			}
		}
		return -1;
	}
	
	public RDataLabelProvider getLabelProvider() {
		return this.labelProvider;
	}
	
	public void dispose() {
		this.labelProvider.dispose();
	}
	
}
