/*=============================================================================#
 # 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.internal.r.ui.rhelp;

import static org.eclipse.statet.ecommons.ui.SharedUIResources.OBJ_LINE_MATCH_IMAGE_ID;

import static org.eclipse.statet.r.ui.rhelp.RHelpUI.RHELP_PAGE_INTERNAL_OBJ_IMAGE_ID;
import static org.eclipse.statet.r.ui.rhelp.RHelpUI.RHELP_PAGE_OBJ_IMAGE_ID;
import static org.eclipse.statet.r.ui.rhelp.RHelpUI.RPACKAGE_OBJ_IMAGE_ID;

import org.eclipse.jface.viewers.ColumnViewer;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.StyledCellLabelProvider;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.StyledString.Styler;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.ViewerCell;
import org.eclipse.jface.viewers.ViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyleRange;
import org.eclipse.swt.graphics.Image;

import org.eclipse.statet.ecommons.ui.SharedUIResources;
import org.eclipse.statet.ecommons.ui.util.UIResources;
import org.eclipse.statet.ecommons.workbench.search.ui.TextSearchLabelUtil;

import org.eclipse.statet.ltk.ui.ElementLabelProvider;
import org.eclipse.statet.r.ui.RUI;
import org.eclipse.statet.r.ui.rhelp.RHelpUI;
import org.eclipse.statet.rhelp.core.RHelpKeyword;
import org.eclipse.statet.rhelp.core.RHelpKeywordGroup;
import org.eclipse.statet.rhelp.core.RHelpPage;
import org.eclipse.statet.rhelp.core.RHelpSearchMatch;
import org.eclipse.statet.rhelp.core.RHelpSearchMatch.MatchFragment;
import org.eclipse.statet.rhelp.core.RPkgHelp;
import org.eclipse.statet.rj.renv.core.REnv;
import org.eclipse.statet.rj.renv.core.REnvConfiguration;


public class RHelpLabelProvider extends StyledCellLabelProvider
		implements ILabelProvider, IStyledLabelProvider {
	
	
	private static final String TITLE_SEP= " – "; //$NON-NLS-1$
	
	public static final int WITH_TITLE= 0x1;
	public static final int WITH_QUALIFIER= 0x2;
	
	public static final int HEADER= 0x20;
	public static final int TOOLTIP= 0x10;
	
	
	public static void append(final StyledString string, final MatchFragment fragment) {
		final String text= fragment.getText();
		int startIdx= 0;
		int endIdx= 0;
		while ((startIdx= text.indexOf(RHelpSearchMatch.PRE_TAGS_PREFIX, endIdx)) >= 0) {
			if (startIdx > endIdx) {
				string.append(text.substring(endIdx, startIdx));
			}
			final int m= (text.charAt(startIdx+8)) - ('A');
			startIdx+= 10;
			endIdx= text.indexOf(RHelpSearchMatch.POST_TAGS[m], startIdx);
			if (endIdx < 0) {
				return;
			}
			string.append(text.substring(startIdx, endIdx), TextSearchLabelUtil.HIGHLIGHT_STYLE);
			endIdx+= 11;
		}
		if (endIdx < text.length()) {
			string.append(text.substring(endIdx));
		}
	}
	
	
	private boolean tooltip;
	private final boolean withTitle;
	private boolean withQualifier;
	
	private Object focusObject;
	
	private final Styler defaultStyler;
	
	private final SharedUIResources commonUIResources= SharedUIResources.INSTANCE;
	private final UIResources helpUIResources= RHelpUI.getUIResources();
	
	
	public RHelpLabelProvider() {
		this(WITH_TITLE);
	}
	
	public RHelpLabelProvider(final int style) {
		this.tooltip= ((style & TOOLTIP) != 0);
		this.withQualifier= ((style & WITH_QUALIFIER) != 0);
		this.withTitle= ((style & (WITH_TITLE | TOOLTIP)) != 0);
		if ((style & HEADER) != 0) {
			this.defaultStyler= ElementLabelProvider.TITLE_STYLER;
		}
		else {
			this.defaultStyler= null;
		}
	}
	
	
	@Override
	public void initialize(final ColumnViewer viewer, final ViewerColumn column) {
		super.initialize(viewer, column);
		
		if (viewer instanceof TableViewer) {
			this.withQualifier= true;
		}
	}
	
	public void setFocusObject(final Object object) {
		this.focusObject= object;
	}
	
	
	@Override
	public Image getImage(Object element) {
		if (element instanceof RHelpSearchUIMatch) {
			element= ((RHelpSearchUIMatch) element).getRHelpMatch().getPage();
		}
		
		if (element instanceof RHelpPage) {
			if (((RHelpPage)element).isInternal()) {
				return this.helpUIResources.getImage(RHELP_PAGE_INTERNAL_OBJ_IMAGE_ID);
			}
			return this.helpUIResources.getImage(RHELP_PAGE_OBJ_IMAGE_ID);
		}
		else if (element instanceof RPkgHelp) {
			return this.helpUIResources.getImage(RPACKAGE_OBJ_IMAGE_ID);
		}
		
		else if (element instanceof REnvConfiguration || element instanceof REnv) {
			return RUI.getImage(RUI.IMG_OBJ_R_RUNTIME_ENV);
		}
		
		else if (element instanceof RHelpSearchMatch.MatchFragment) {
			return this.commonUIResources.getImage(OBJ_LINE_MATCH_IMAGE_ID);
		}
		
		else {
			return null;
		}
	}
	
	@Override
	public String getText(Object element) {
		if (element instanceof RHelpSearchUIMatch) {
			element= ((RHelpSearchUIMatch) element).getRHelpMatch().getPage();
		}
		if (element instanceof RHelpPage) {
			final StringBuilder sb= new StringBuilder(32);
			final RHelpPage page= (RHelpPage) element;
			sb.append(page.getName());
			if (this.tooltip) {
				sb.append(" {"); //$NON-NLS-1$
				sb.append(page.getPackage().getName());
				sb.append("}\n"); //$NON-NLS-1$
				sb.append(page.getTitle());
			}
			else {
				if (this.withTitle && page.getTitle().length() > 0) {
					sb.append(TITLE_SEP);
					sb.append(page.getTitle());
				}
			}
			return sb.toString();
		}
		else if (element instanceof RPkgHelp) {
			final StringBuilder sb= new StringBuilder(32);
			final RPkgHelp packageHelp= (RPkgHelp) element;
			if (this.tooltip) {
				sb.append(packageHelp.getName());
				sb.append(" ["); //$NON-NLS-1$
				sb.append(packageHelp.getVersion());
				sb.append("]\n"); //$NON-NLS-1$
				sb.append(packageHelp.getTitle());
			}
			else {
				sb.append(packageHelp.getName());
				if ((element == this.focusObject)
						&& packageHelp.getTitle().length() > 0) {
					sb.append(TITLE_SEP);
					sb.append(packageHelp.getTitle());
				}
			}
			return sb.toString();
		}
		
		else if (element instanceof REnvConfiguration) {
			final REnvConfiguration rEnv= (REnvConfiguration) element;
			return rEnv.getName();
		}
		else if (element instanceof REnv) {
			final REnv rEnv= (REnv) element;
			final String name= rEnv.getName();
			return (name != null) ? name : ""; //$NON-NLS-1$
		}
		
		else if (element instanceof RHelpKeywordGroup) {
			final RHelpKeywordGroup group= (RHelpKeywordGroup) element;
			return group.getLabel() + TITLE_SEP + group.getDescription();
		}
		else if (element instanceof RPkgHelp) {
			final RHelpKeyword keyword= (RHelpKeyword) element;
			return keyword.getKeyword() + TITLE_SEP + keyword.getDescription();
		}
		
		else if (element instanceof RHelpSearchMatch.MatchFragment) {
			final RHelpSearchMatch.MatchFragment fragment= (MatchFragment) element;
			return RHelpSearchMatch.ALL_TAGS_PATTERN.matcher(fragment.getText())
					.replaceAll(""); //$NON-NLS-1$
		}
		
		else if (element instanceof Object[]) {
			final Object[] array= (Object[]) element;
			return array[array.length-1].toString();
		}
		else {
			return element.toString();
		}
	}
	
	@Override
	public boolean useNativeToolTip(final Object object) {
		return true;
	}
	
	@Override
	public String getToolTipText(final Object element) {
		final boolean wasTooltip= this.tooltip;
		try {
			this.tooltip= true;
			return getText(element);
		}
		finally {
			this.tooltip= wasTooltip;
		}
	}
	
	@Override
	public StyledString getStyledText(final Object element) {
		final StyledString text= new StyledString();
		
		if (element instanceof RHelpSearchUIMatch) {
			final RHelpSearchMatch match= ((RHelpSearchUIMatch) element).getRHelpMatch();
			final RHelpPage page= match.getPage();
			text.append(page.getName(), this.defaultStyler);
			if (this.withTitle && page.getTitle().length() > 0) {
				text.append(TITLE_SEP, this.defaultStyler);
				text.append(page.getTitle(), this.defaultStyler);
			}
			if (this.withQualifier) {
				text.append(" - ", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
				text.append(page.getPackage().getName(), StyledString.QUALIFIER_STYLER);
			}
			else if (match.getMatchCount() > 0){
				text.append(" (", StyledString.COUNTER_STYLER); //$NON-NLS-1$
				text.append(Integer.toString(match.getMatchCount()), StyledString.COUNTER_STYLER);
				text.append(")", StyledString.COUNTER_STYLER); //$NON-NLS-1$
			}
		}
		else if (element instanceof RHelpPage) {
			final RHelpPage page= (RHelpPage) element;
			text.append(page.getName(), this.defaultStyler);
			if (this.withTitle && page.getTitle().length() > 0) {
				text.append(TITLE_SEP, this.defaultStyler);
				text.append(page.getTitle(), this.defaultStyler);
			}
			if (this.withQualifier) {
				text.append(" - ", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
				text.append(page.getPackage().getName(), StyledString.QUALIFIER_STYLER);
			}
		}
		else if (element instanceof RPkgHelp) {
			final RPkgHelp packageHelp= (RPkgHelp) element;
			text.append(packageHelp.getName(), this.defaultStyler);
			if (packageHelp == this.focusObject && packageHelp.getTitle().length() > 0) {
				text.append(TITLE_SEP, this.defaultStyler);
				text.append(packageHelp.getTitle(), this.defaultStyler);
			}
		}
		
		else if (element instanceof RHelpKeywordGroup) {
			final RHelpKeywordGroup group= (RHelpKeywordGroup) element;
			text.append(group.getLabel());
			text.append(" - " + group.getDescription(), StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
		}
		else if (element instanceof RHelpKeyword) {
			final RHelpKeyword keyword= (RHelpKeyword) element;
			text.append(keyword.getKeyword());
			text.append(" - " + keyword.getDescription(), StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
		}
		
		else if (element instanceof REnvConfiguration) {
			final REnvConfiguration rEnv= (REnvConfiguration) element;
			text.append(rEnv.getName());
		}
		else if (element instanceof REnv) {
			final REnv rEnv= (REnv) element;
			final String name= rEnv.getName();
			text.append((name != null) ? name : "", this.defaultStyler); //$NON-NLS-1$
		}
		
		else if (element instanceof RHelpSearchMatch.MatchFragment) {
			final RHelpSearchMatch.MatchFragment fragment= (MatchFragment) element;
			{	final String fieldLabel= fragment.getFieldLabel();
				if (fieldLabel != null) {
					text.append(fieldLabel, StyledString.QUALIFIER_STYLER);
					text.append(": ", StyledString.QUALIFIER_STYLER); //$NON-NLS-1$
				}
			}
			append(text, fragment);
		}
		
		else if (element instanceof Object[]) {
			final Object[] array= (Object[]) element;
			text.append(array[array.length-1].toString());
		}
		else {
			text.append(element.toString());
		}
		
		return text;
	}
	
	
	@Override
	public void update(final ViewerCell cell) {
		final Object element= cell.getElement();
		final Image image= getImage(element);
		final StyledString text= getStyledText(element);
		
		cell.setImage(image);
		cell.setText(text.getString());
		cell.setStyleRanges(text.getStyleRanges());
		
		super.update(cell);
	}
	
	@Override
	protected StyleRange prepareStyleRange(StyleRange styleRange, final boolean applyColors) {
		if (!applyColors && styleRange.background != null) {
			styleRange= super.prepareStyleRange(styleRange, applyColors);
			styleRange.borderStyle= SWT.BORDER_DOT;
			return styleRange;
		}
		return super.prepareStyleRange(styleRange, applyColors);
	}
	
}
