/*=============================================================================#
 # Copyright (c) 2012, 2020 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.rtm.base.ui.rexpr;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.graphics.Image;

import org.eclipse.statet.ecommons.emf.core.IContext;

import org.eclipse.statet.ltk.core.ElementName;
import org.eclipse.statet.ltk.ui.ElementNameProvider;
import org.eclipse.statet.r.core.model.RElementName;
import org.eclipse.statet.rtm.base.util.RExprType;


public class RExprTypeUIAdapter {
	
	
	protected static final int PRIORITY_INVALID= 0;
	protected static final int PRIORITY_DEFAULT= 10;
	
	
	private final RExprType type;
	
	private final Image image;
	
	
	public RExprTypeUIAdapter(final RExprType type, final Image image) {
		this.type= type;
		this.image= image;
	}
	
	
	public RExprType getType() {
		return this.type;
	}
	
	public Image getImage() {
		return this.image;
	}
	
	public String getLabel() {
		return this.type.getLabel();
	}
	
	public RExprWidget.TypeDef createWidgetDef() {
		return new RExprWidget.TypeDef(this);
	}
	
	
	public int isValidInput(final Object input, final IContext context) {
		final List<?> elements= getElements(input);
		if (elements == null || elements.isEmpty()
				|| (!isMulti() && elements.size() != 1) ) {
			return PRIORITY_INVALID;
		}
		return isValidElements(elements);
	}
	
	public List<String> getInputExprs(final Object input, final IContext context) {
		final List<?> elements= getElements(input);
		return collectElementName(elements, (input instanceof ElementNameProvider) ?
				(ElementNameProvider) input : DefaultRExprTypeUIAdapters.DIRECT_NAME);
	}
	
	public int isMoveValid(final Object input, final IContext source, final IContext context) {
		return PRIORITY_INVALID;
	}
	
	
	protected List<?> getElements(final Object input) {
		if (input instanceof IStructuredSelection) {
			return ((IStructuredSelection) input).toList();
		}
		if (input instanceof List) {
			return (List<?>) input;
		}
		return null;
	}
	
	protected boolean isMulti() {
		return false;
	}
	
	protected int isValidElements(final List<?> elements) {
		int priority= Integer.MAX_VALUE;
		for (final Object element : elements) {
			final int elementPriority= isValidElement(element);
			if (elementPriority <= 0) {
				return PRIORITY_INVALID;
			}
			if (elementPriority < priority) {
				priority= elementPriority;
			}
		}
		return priority;
	}
	
	protected int isValidElement(final Object element) {
		return PRIORITY_INVALID;
	}
	
	protected List<String> collectElementName(final List<?> elements, final ElementNameProvider nameProvider) {
		final List<String> expressions= new ArrayList<>(elements.size());
		for (final Object element : elements) {
			final ElementName elementName= nameProvider.getElementName(element);
			if (elementName instanceof RElementName) {
				final String name= elementName.getDisplayName();
				if (name != null) {
					expressions.add(name);
				}
			}
		}
		return expressions;
	}
	
	public String adopt(final String typeKey, final String expr) {
		return null;
	}
	
	
	@Override
	public String toString() {
		final StringBuilder sb= new StringBuilder("RExprTypeUIAdapter"); //$NON-NLS-1$
		sb.append(" for '").append(getType().getTypeKey()).append("'");  //$NON-NLS-1$//$NON-NLS-2$
		sb.append(" (").append(getClass().getName()).append(")"); //$NON-NLS-1$ //$NON-NLS-2$
		sb.append("\n\tlabel= ").append(getLabel()); //$NON-NLS-1$
		sb.append("\n\tisMulti= ").append(isMulti()); //$NON-NLS-1$
		return sb.toString();
	}
	
}
