/*=============================================================================#
 # Copyright (c) 2021 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.ecommons.text.ui.presentation;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.statet.jcommons.lang.NonNullByDefault;


@NonNullByDefault
public abstract class BasicTextStyleManager<TStyleData> implements TextStyleManager<TStyleData> {
	
	
	protected static class BasicTextStyleToken<TStyleData> implements TextStyleToken<TStyleData> {
		
		
		private TStyleData data;
		
		
		public BasicTextStyleToken(final TStyleData data) {
			this.data= data;
		}
		
		
		protected void setData(final TStyleData data) {
			this.data= data;
		}
		
		
		@Override
		public boolean isUndefined() {
			return false;
		}
		
		@Override
		public boolean isWhitespace() {
			return false;
		}
		
		@Override
		public boolean isEOF() {
			return false;
		}
		
		@Override
		public boolean isOther() {
			return false;
		}
		
		@Override
		public TStyleData getData() {
			return this.data;
		}
		
	}
	
	
	private final Map<String, BasicTextStyleToken<TStyleData>> tokenMap= new HashMap<>();
	
	
	public BasicTextStyleManager() {
	}
	
	
	/**
	 * Token access for styles.
	 * 
	 * @param key id and prefix for preference keys
	 * @return token with text style attribute
	 */
	@Override
	public TextStyleToken<TStyleData> getToken(final String key) {
		BasicTextStyleToken<TStyleData> token= this.tokenMap.get(key);
		if (token == null) {
			token= new BasicTextStyleToken<>(createStyleData(key));
			this.tokenMap.put(key, token);
		}
		return token;
	}
	
	protected abstract TStyleData createStyleData(String key);
	
	
	protected void updateTextStyles() {
		for (final var token : this.tokenMap.entrySet()) {
			token.getValue().setData(createStyleData(token.getKey()));
		}
	}
	
}
