/*=============================================================================#
 # Copyright (c) 2008, 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;

import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullAssert;
import static org.eclipse.statet.jcommons.lang.ObjectUtils.nonNullLateInit;

import org.eclipse.jface.internal.text.html.BrowserInformationControlInput;
import org.eclipse.jface.internal.text.html.HTMLPrinter;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.graphics.FontData;

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

import org.eclipse.statet.internal.ltk.ui.LTKUIPlugin;


/**
 * 
 */
@NonNullByDefault
public class DefaultBrowserInformationInput extends BrowserInformationControlInput {
	
	
	public static final int FORMAT_NONE= 0;
	public static final int FORMAT_TEXT_INPUT= 1;
	public static final int FORMAT_SOURCE_INPUT= 2;
	public static final int FORMAT_HTMLBODY_INPUT= 3;
	public static final int FORMAT_HTMLSOURCE_INPUT= 4;
	
	
	private static @Nullable Formatter FORMATTER;
	
	private static class Formatter implements IPropertyChangeListener, Disposable {
		
		private String stylesheet= nonNullLateInit();
		
		public Formatter() {
			JFaceResources.getFontRegistry().addListener(this);
			LTKUIPlugin.getInstance().addStoppingListener(this);
			updateStyleSheet();
		}
		
		@Override
		public void dispose() {
			JFaceResources.getFontRegistry().removeListener(this);
			FORMATTER= null;
		}
		
		@Override
		public void propertyChange(final PropertyChangeEvent event) {
			if (event.getProperty().equals(JFaceResources.DIALOG_FONT)) {
				updateStyleSheet();
			}
		}
		
		private void updateStyleSheet() {
			String style =
				// Font definitions
				"html        { font-family: sans-serif; font-size: 9pt; font-style: normal; font-weight: normal; }\n" +
				"body, h1, h2, h3, h4, h5, h6, p, table, td, caption, th, ul, ol, dl, li, dd, dt { font-size: 1em; }\n" +
				"pre         { font-family: monospace; }\n" +
				// Margins
				"html        { margin: 0px; padding: 0px }" +
				"body        { overflow: auto; margin-top: 0.25em; margin-bottom: 0.5em; margin-left: 0.25em; margin-right: 0.25em; }\n" +
				"h1          { margin-top: 0.3em; margin-bottom: 0.04em; }\n" +
				"h2          { margin-top: 2em; margin-bottom: 0.25em; }\n" +
				"h3          { margin-top: 1.7em; margin-bottom: 0.25em; }\n" +
				"h4          { margin-top: 2em; margin-bottom: 0.3em; }\n" +
				"h5          { margin-top: 0px; margin-bottom: 0px; }\n" +
				"p           { margin-top: 1em; margin-bottom: 1em; }\n" +
//				"pre         { margin-left: 0.6em; }\n" +
				"ul          { margin-top: 0px; margin-bottom: 1em; }\n" +
				"li          { margin-top: 0px; margin-bottom: 0px; }\n" +
				"li p        { margin-top: 0px; margin-bottom: 0px; }\n" +
				"ol          { margin-top: 0px; margin-bottom: 1em; }\n" +
				"dl          { margin-top: 0px; margin-bottom: 1em; }\n" +
				"dt          { margin-top: 0px; margin-bottom: 0px; font-weight: bold; }\n" +
				"dd          { margin-top: 0px; margin-bottom: 0px; }\n" +
				// Styles and colors
				"a:link      { color: #0000FF; }\n" +
				"a:hover     { color: #000080; }\n" +
				"a:visited   { text-decoration: underline; }\n" +
				"h4          { font-style: italic; }\n" +
				"strong      { font-weight: bold; }\n" +
				"em          { font-style: italic; }\n" +
				"var         { font-style: italic; }\n" +
				"th          { font-weight: bold; }\n";
			try {
				final FontData[] fontData= JFaceResources.getFontRegistry().getFontData(JFaceResources.DIALOG_FONT);
				if (fontData != null && fontData.length > 0) {
					style= style.replace("9pt", fontData[0].getHeight() + "pt");
					style= style.replace("sans-serif", "sans-serif, '" + fontData[0].getName() + "'");
				}
			}
			catch (final Throwable e) {
			}
			this.stylesheet= style;
		}
		
		String format(String content, final int formatting,
				final int tabSize) {
			final String stylesheet= this.stylesheet;
			
			final StringBuilder sb;
			switch (formatting) {
			case FORMAT_NONE:
				return content;
			case FORMAT_TEXT_INPUT:
				content= HTMLPrinter.convertToHTMLContent(content);
				sb= new StringBuilder(content.length() + stylesheet.length() + 500);
				sb.append(content);
				break;
			case FORMAT_HTMLBODY_INPUT:
				sb= new StringBuilder(content.length() + stylesheet.length() + 500);
				sb.append(content);
				break;
			case FORMAT_SOURCE_INPUT:
				content= HTMLPrinter.convertToHTMLContent(content);
				//$FALL-THROUGH$
			case FORMAT_HTMLSOURCE_INPUT:
				sb= new StringBuilder((int)(content.length() * 1.066) + stylesheet.length() + 500);
				sb.append("<pre>"); //$NON-NLS-1$
				{	final String spaces= " ".repeat(tabSize); //$NON-NLS-1$
					int fromIdx= 0;
					int tabIdx;
					while ((tabIdx= content.indexOf('\t', fromIdx)) >= 0) {
						sb.append(content, fromIdx, tabIdx);
						sb.append(spaces);
						fromIdx= tabIdx + 1;
					}
					sb.append(content, fromIdx, content.length());
				}
				sb.append("</pre>"); //$NON-NLS-1$
				break;
			default:
				throw new IllegalArgumentException("Unsupported format"); //$NON-NLS-1$
			}
			
			HTMLPrinter.insertPageProlog(sb, 0, this.stylesheet);
			HTMLPrinter.addPageEpilog(sb);
			return sb.toString();
		}
		
	}
	
	
	private final String name;
	private final String html;
	
	
	public DefaultBrowserInformationInput(final String name,
			final String content, final int formatting,
			final int tabSize,
			final @Nullable BrowserInformationControlInput previous) {
		super(previous);
		
		this.name= nonNullAssert(name);
		this.html= getFormatter().format(nonNullAssert(content), formatting, tabSize);
	}
	
	public DefaultBrowserInformationInput(final String name,
			final String content, final int formatting,
			final @Nullable BrowserInformationControlInput previous) {
		this(name, content, formatting, 4, previous);
	}
	
	public DefaultBrowserInformationInput(final String name,
			final String content, final int formatting,
			final int tabSize) {
		this(name, content, formatting, tabSize, null);
	}
	
	public DefaultBrowserInformationInput(final String name,
			final String content, final int formatting) {
		this(name, content, formatting, 4, null);
	}
	
	
	protected Formatter getFormatter() {
		synchronized (DefaultBrowserInformationInput.class) {
			var formatter= FORMATTER;
			if (formatter == null) {
				formatter= new Formatter();
				FORMATTER= formatter;
			}
			return formatter;
		}
	}
	
	
	@Override
	public String getInputName() {
		return this.name;
	}
	
	@Override
	public Object getInputElement() {
		return this.html;
	}
	
	@Override
	public String getHtml() {
		return this.html;
	}
	
}
