/*=============================================================================#
 # Copyright (c) 2010, 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.ltk.ui.sourceediting.assist;

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

import org.eclipse.jface.text.IInformationControlCreator;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;
import org.eclipse.statet.jcommons.status.ProgressMonitor;
import org.eclipse.statet.jcommons.status.StatusException;
import org.eclipse.statet.jcommons.status.Statuses;


/**
 * Special information hover showing the first match of the specified hover types.
 */
@NonNullByDefault
public class CombinedHover implements InfoHover {
	
	
	private List<InfoHoverDescriptor> descriptors;
	private List<InfoHover> instantiatedHovers;
	
	private volatile @Nullable InfoHover bestHover;
	
	
	public CombinedHover() {
	}
	
	
	public synchronized void setHovers(final List<InfoHoverDescriptor> descriptors) {
		this.descriptors= descriptors;
		this.instantiatedHovers= new ArrayList<>(descriptors.size());
	}
	
	
	@Override
	public @Nullable Object getHoverInfo(final AssistInvocationContext context,
			final ProgressMonitor m) throws StatusException {
		this.bestHover= null;
		final List<InfoHoverDescriptor> descriptors;
		final List<InfoHover> instantiatedHovers;
		synchronized (this) {
			descriptors= this.descriptors;
			instantiatedHovers= this.instantiatedHovers;
		}
		if (descriptors == null) {
			return null;
		}
		
		for (int i= 0; i < descriptors.size(); i++) {
			m.setWorkRemaining(descriptors.size() - i);
			if (m.isCanceled()) {
				throw new StatusException(Statuses.CANCEL_STATUS);
			}
			
			if (i == instantiatedHovers.size()) {
				instantiatedHovers.add(descriptors.get(i).createHover());
			}
			final InfoHover hover= instantiatedHovers.get(i);
			if (hover != null) {
				try {
					final Object info= hover.getHoverInfo(context, m.newSubMonitor(1));
					if (info != null) {
						this.bestHover= hover;
						return info;
					}
				}
				catch (final StatusException e) {
				}
			}
		}
		return null;
	}
	
	@Override
	public @Nullable IInformationControlCreator getHoverControlCreator() {
		final InfoHover hover= this.bestHover;
		if (hover != null) {
			return hover.getHoverControlCreator();
		}
		return null;
	}
	
}
