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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.eclipse.jface.resource.ImageDescriptor;

import org.eclipse.statet.jcommons.collections.ImCollections;
import org.eclipse.statet.jcommons.lang.NonNullByDefault;
import org.eclipse.statet.jcommons.lang.Nullable;

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


/**
 * Describes a category for {@link ContentAssistProcessor}s.
 */
@NonNullByDefault
public final class ContentAssistCategory {
	
	
	private static final List<ContentAssistComputer> NO_COMPUTERS= ImCollections.emptyList();
	
	
	private final String id;
	
	private final String name;
	
	/** The image descriptor for this category, or <code>null</code> if none specified. */
	private final @Nullable ImageDescriptor image;
	
	boolean isEnabledAsSeparate= false;
	
	boolean isIncludedInDefault= false;
	
	private final int sortOrder= 0x10000;
	
	private final List<ContentAssistComputerRegistry.ComputerDescriptor> computerDescriptors;
	private final Map<String, List<ContentAssistComputer>> computersByPartition;
	
	
	public ContentAssistCategory(final String partitionId, final List<ContentAssistComputer> computers) {
		this.id= "explicite:" + partitionId; //$NON-NLS-1$
		this.name= null;
		this.image= null;
		this.computerDescriptors= ImCollections.emptyList();
		this.computersByPartition= new HashMap<>();
		this.computersByPartition.put(partitionId, computers);
		this.isIncludedInDefault= true;
	}
	
	ContentAssistCategory(final String id, final String name, final @Nullable ImageDescriptor imageDsrc,
			final List<ContentAssistComputerRegistry.ComputerDescriptor> computers) {
		this.id= id;
		this.name= name;
		this.image= imageDsrc;
		this.computerDescriptors= computers;
		this.computersByPartition= new HashMap<>();
	}
	
	ContentAssistCategory(final ContentAssistCategory template) {
		this.id= template.id;
		this.name= template.name;
		this.image= template.image;
		this.computerDescriptors= template.computerDescriptors;
		this.computersByPartition= template.computersByPartition;
	}
	
	
	/**
	 * Returns the identifier of the described extension.
	 *
	 * @return Returns the id
	 */
	public String getId() {
		return this.id;
	}
	
	/**
	 * Returns the name of the described extension.
	 * 
	 * @return Returns the name
	 */
	public String getName() {
		return this.name;
	}
	
	/**
	 * Returns the name of the described extension
	 * without mnemonic hint in order to be displayed
	 * in a message.
	 * 
	 * @return Returns the name
	 */
	public String getDisplayName() {
		return MessageUtils.removeMnemonics(this.name);
	}
	
	/**
	 * Returns the image descriptor of the described category.
	 * 
	 * @return the image descriptor of the described category
	 */
	public @Nullable ImageDescriptor getImageDescriptor() {
		return this.image;
	}
	
	public boolean isEnabledInDefault() {
		return this.isIncludedInDefault;
	}
	
	public boolean isEnabledInCircling() {
		return this.isEnabledAsSeparate;
	}
	
//	public int getSortOrder() {
//		return this.sortOrder;
//	}
//	
	public boolean hasComputers(final String contentTypeId) {
		final List<ContentAssistComputer> computers= this.computersByPartition.get(contentTypeId);
		if (computers == null) {
			for (final ContentAssistComputerRegistry.ComputerDescriptor descr : this.computerDescriptors) {
				if (descr.getPartitions().contains(contentTypeId)) {
					return true;
				}
			}
			this.computersByPartition.put(contentTypeId, NO_COMPUTERS);
			return false;
		}
		else {
			return !computers.isEmpty();
		}
	}
	
	public List<ContentAssistComputer> getComputers(final String contentTypeId) {
		List<ContentAssistComputer> computers= this.computersByPartition.get(contentTypeId);
		if (computers == null) {
			computers= initComputers(contentTypeId);
			this.computersByPartition.put(contentTypeId, computers);
		}
		return computers;
	}
	
	private List<ContentAssistComputer> initComputers(final String contentTypeId) {
		final List<ContentAssistComputer> computers= new ArrayList<>();
		for (final ContentAssistComputerRegistry.ComputerDescriptor descr : this.computerDescriptors) {
			if (descr.getPartitions().contains(contentTypeId)) {
				final ContentAssistComputer computer= descr.getComputer();
				if (computer != null) {
					computers.add(computer);
				}
			}
		}
		return computers;
	}
	
	
	@Override
	public String toString() {
		return this.id;
	}
	
}
