/*=============================================================================#
 # Copyright (c) 2010, 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.internal.r.ui.rhelp;

import java.io.PrintWriter;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;

import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.JFacePreferences;
import org.eclipse.jface.preference.PreferenceConverter;
import org.eclipse.jface.resource.FontDescriptor;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.editors.text.EditorsUI;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.internal.editors.text.EditorsPlugin;

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

import org.eclipse.statet.ecommons.preferences.PreferencesUtil;
import org.eclipse.statet.ecommons.preferences.SettingsChangeNotifier;
import org.eclipse.statet.ecommons.preferences.core.util.PreferenceUtils;
import org.eclipse.statet.ecommons.ui.util.LayoutUtils;
import org.eclipse.statet.ecommons.ui.util.UIAccess;

import org.eclipse.statet.internal.r.ui.RIdentifierGroups;
import org.eclipse.statet.internal.r.ui.RUIPlugin;
import org.eclipse.statet.r.core.RCore;
import org.eclipse.statet.r.ui.RUIPreferenceConstants;
import org.eclipse.statet.rhelp.core.http.RHelpHttpServlet;
import org.eclipse.statet.rhelp.core.http.jetty.JettyForwardHandler;
import org.eclipse.statet.rhelp.core.http.jetty.JettyRHelpUtils;


@NonNullByDefault
public class RHelpUIServlet extends RHelpHttpServlet implements IPropertyChangeListener, SettingsChangeNotifier.ChangeListener {
	
	private static final long serialVersionUID= 1L;
	
	
	static final String STYLE_PARAM= "style"; //$NON-NLS-1$
	
	static final String HOVER_STYLE= "hover"; //$NON-NLS-1$
	
	
	private static final String[] DEFAULT_MATCH_COLORS= new String[] {
		".SMATCH-A { background: #ceccf7; }\n",
		".SMATCH-B { background: #ffffcf; }\n",
		".SMATCH-C { background: aquamarine; }\n",
		".SMATCH-D { background: palegreen; }\n",
		".SMATCH-E { background: coral; }\n",
		".SMATCH-F { background: wheat; }\n",
		".SMATCH-G { background: khaki; }\n",
		".SMATCH-H { background: lime; }\n",
		".SMATCH-I { background: deepskyblue; }\n",
		".SMATCH-J { background: plum; }\n",
	};
	
	
	private static void appendCssColor(final StringBuilder sb, final RGB color) {
		sb.append('#');
		String s= Integer.toHexString(color.red);
		if (s.length() == 1) {
			sb.append('0');
		}
		sb.append(s);
		s= Integer.toHexString(color.green);
		if (s.length() == 1) {
			sb.append('0');
		}
		sb.append(s);
		s= Integer.toHexString(color.blue);
		if (s.length() == 1) {
			sb.append('0');
		}
		sb.append(s);
	}
	
	private static void appendELinkColors(final StringBuilder sb, final RGB foregroundColor) {
		final RGB hyperlinkColor= JFaceResources.getColorRegistry().getRGB(JFacePreferences.HYPERLINK_COLOR);
		sb.append("a { color: "); //$NON-NLS-1$
				appendCssColor(sb, hyperlinkColor);
				sb.append("; }\n");//$NON-NLS-1$
		sb.append("a:hover, a:active, a:focus { color: "); //$NON-NLS-1$
				appendCssColor(sb, JFaceResources.getColorRegistry().getRGB(JFacePreferences.ACTIVE_HYPERLINK_COLOR));
				sb.append("; }\n"); //$NON-NLS-1$
		sb.append("a:visited { color: "); //$NON-NLS-1$
		appendCssColor(sb, new RGB(
				(hyperlinkColor.red + ((hyperlinkColor.red <= 127) ? +64 : -64)),
				(hyperlinkColor.green + foregroundColor.green) / 2,
				(hyperlinkColor.blue + ((hyperlinkColor.blue > 32) ? -32 : +32) + foregroundColor.blue ) / 2 ));
				sb.append("; }\n"); //$NON-NLS-1$
	}
	
	private static void appendMatchColors(final StringBuilder sb) {
		int i= 0;
		final RGB rgb= PreferenceConverter.getColor(
				EditorsPlugin.getDefault().getPreferenceStore(),
				"searchResultIndicationColor"); //$NON-NLS-1$
		if (rgb != null) {
			sb.append(".SMATCH-A { background: ");
			appendCssColor(sb, rgb);
			sb.append("; }\n"); //$NON-NLS-1$
			i++;
		}
		while (i < DEFAULT_MATCH_COLORS.length) {
			sb.append(DEFAULT_MATCH_COLORS[i++]);
		}
	}
	
	
	public static class Browse extends RHelpUIServlet {
		
		private static final long serialVersionUID= 1L;
		
		@Override
		protected void collectCss(final StringBuilder sb) {
			final RGB foregroundColor= JFaceResources.getColorRegistry().getRGB("org.eclipse.statet.workbench.themes.DocViewColor"); //$NON-NLS-1$
			final RGB docBackgroundColor= JFaceResources.getColorRegistry().getRGB("org.eclipse.statet.workbench.themes.DocViewBackgroundColor"); //$NON-NLS-1$
			final RGB borderColor= Display.getCurrent().getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW).getRGB();
			
			{	final FontDescriptor docFontDescr= JFaceResources.getFontDescriptor("org.eclipse.statet.workbench.themes.DocViewFont"); //$NON-NLS-1$
				final FontData fontData= docFontDescr.getFontData()[0];
				
				sb.append("body { font-family: '"); //$NON-NLS-1$
						sb.append(fontData.getName());
						sb.append("'; font-size:"); //$NON-NLS-1$
						sb.append(fontData.getHeight());
						sb.append("pt; color:"); //$NON-NLS-1$
						appendCssColor(sb, foregroundColor);
						sb.append("; background:"); //$NON-NLS-1$
						appendCssColor(sb, docBackgroundColor);
						sb.append("; }\n"); //$NON-NLS-1$
			}
			
			appendELinkColors(sb, foregroundColor);
			
			sb.append("div.toc a, div.toc a:visited { color: "); //$NON-NLS-1$
					appendCssColor(sb, foregroundColor);
					sb.append("; }\n"); //$NON-NLS-1$
			
			sb.append("@media screen {\n"); //$NON-NLS-1$
			
			sb.append("body { margin: "); //$NON-NLS-1$
					sb.append(LayoutUtils.defaultVSpacing());
					sb.append("px "); //$NON-NLS-1$
					sb.append(LayoutUtils.defaultHSpacing());
					sb.append("px; }\n"); //$NON-NLS-1$
			
			sb.append("div.toc { display: inline; float: right; border: 1px solid "); //$NON-NLS-1$
					appendCssColor(sb, borderColor);
					sb.append("; }\n"); //$NON-NLS-1$
			
			sb.append("span.mnemonic, div.toc a.mnemonic { text-decoration: underline; }\n"); //$NON-NLS-1$
			sb.append("hr { border: 0; height: 1px; background: " ); //$NON-NLS-1$
					appendCssColor(sb, borderColor);
					sb.append("; }\n"); //$NON-NLS-1$
			
			sb.append("}\n" ); // @media //$NON-NLS-1$
			
			appendMatchColors(sb);
			
			super.collectCss(sb);
		}
		
	}
	
	public static class Info extends RHelpUIServlet {
		
		private static final long serialVersionUID= 1L;
		
		@Override
		protected void collectCss(final StringBuilder sb) {
			final Display display= Display.getCurrent();
			final RGB infoForegroundColor= display.getSystemColor(SWT.COLOR_INFO_FOREGROUND).getRGB();
			final RGB infoBackgroundColor= display.getSystemColor(SWT.COLOR_INFO_BACKGROUND).getRGB();
			final int vIndent= Math.max(1, LayoutUtils.defaultVSpacing() / 4);
			final int hIndent= Math.max(3, LayoutUtils.defaultHSpacing() / 2);
			
			{	final FontDescriptor docFontDescr= JFaceResources.getDialogFontDescriptor();
				final FontData fontData= docFontDescr.getFontData()[0];
				sb.append("body { font-family: '"); //$NON-NLS-1$
						sb.append(fontData.getName());
						sb.append("'; font-size: "); //$NON-NLS-1$
						sb.append(fontData.getHeight());
						sb.append("pt; color: "); //$NON-NLS-1$
						appendCssColor(sb, infoForegroundColor);
						sb.append("; background: "); //$NON-NLS-1$
						appendCssColor(sb, infoBackgroundColor);
						sb.append("; margin: 0 "); //$NON-NLS-1$
						sb.append(hIndent);
						sb.append("px "); //$NON-NLS-1$
						sb.append(vIndent);
						sb.append("px; }\n"); //$NON-NLS-1$
			}
			appendELinkColors(sb, infoForegroundColor);
			
			sb.append("h2, h3#description { display: none; }\n"); //$NON-NLS-1$
			sb.append("h3 { font-size: 90%; margin-bottom: 0.4em; }\n"); //$NON-NLS-1$
			sb.append("p, pre { margin-top: 0.4em; margin-bottom: 0.4em; }\n" ); //$NON-NLS-1$
			
			sb.append("hr { visibility: hidden; }\n"); //$NON-NLS-1$
			
			super.collectCss(sb);
		}
		
	}
	
	
	private volatile @Nullable String cssStyle;
	
	private RHelpRCodeScanner rCodeScanner;
	
	
	@SuppressWarnings("null")
	public RHelpUIServlet() {
	}
	
	
	@Override
	public void init(final ServletConfig config) throws ServletException {
		super.init(config);
		
		init(RCore.getRHelpManager(),
				JettyRHelpUtils.newResourceHandler(config.getServletContext()),
				new JettyForwardHandler() );
		
		this.rCodeScanner= new RHelpRCodeScanner(RUIPlugin.getInstance().getEditorPreferenceStore());
		
		EditorsUI.getPreferenceStore().addPropertyChangeListener(this);
		JFaceResources.getFontRegistry().addListener(this);
		JFaceResources.getColorRegistry().addListener(this);
		PreferencesUtil.getSettingsChangeNotifier().addChangeListener(this);
		updateStyles();
	}
	
	@Override
	public void propertyChange(final PropertyChangeEvent event) {
		if (event.getProperty().equals("org.eclipse.statet.workbench.themes.DocViewFont") //$NON-NLS-1$
				|| event.getProperty().equals("org.eclipse.statet.workbench.themes.DocViewBackgroundColor") //$NON-NLS-1$
				|| event.getProperty().equals("org.eclipse.statet.workbench.themes.DocViewColor") //$NON-NLS-1$
				|| event.getProperty().equals(JFaceResources.DIALOG_FONT)
				|| event.getProperty().equals(JFacePreferences.HYPERLINK_COLOR)
				|| event.getProperty().equals(JFacePreferences.ACTIVE_HYPERLINK_COLOR)
				|| event.getProperty().equals("searchResultIndicationColor") ) { //$NON-NLS-1$
			updateStyles();
		}
	}
	
	@Override
	public void settingsChanged(final Set<String> groupIds) {
		if (groupIds.contains(RUIPreferenceConstants.R.TS_GROUP_ID)
				|| groupIds.contains(RIdentifierGroups.GROUP_ID)) {
			final Map<String, Object> options= new HashMap<>();
			synchronized (this.rCodeScanner) {
				this.rCodeScanner.handleSettingsChanged(groupIds, options);
			}
		}
	}
	
	@Override
	public void destroy() {
		super.destroy();
		
		final IPreferenceStore preferenceStore= EditorsUI.getPreferenceStore();
		if (preferenceStore != null) {
			preferenceStore.removePropertyChangeListener(this);
		}
		JFaceResources.getFontRegistry().removeListener(this);
		JFaceResources.getColorRegistry().removeListener(this);
		PreferencesUtil.getSettingsChangeNotifier().removeChangeListener(this);
	}
	
	
	@Override
	protected boolean getShowInternal() {
		return PreferenceUtils.getInstancePrefs().getPreferenceValue(
				RHelpPreferences.SHOW_INTERNAL_ENABLED_PREF );
	}
	
	@Override
	protected boolean canOpenFile(final String ext) {
		return true;
	}
	
	@Override
	protected void doOpenFile(final Path file) {
		try {
			final IFileStore fileStore= EFS.getLocalFileSystem().getStore(file.toUri());
			UIAccess.getDisplay().asyncExec(new Runnable() {
				@Override
				public void run() {
					final IWorkbenchPage page= UIAccess.getActiveWorkbenchPage(true);
					try {
						IDE.openEditorOnFileStore(page, fileStore);
					}
					catch (final PartInitException e) {}
				}
			});
		}
		catch (final Exception e) {}
	}
	
	
	private void updateStyles() {
		final StringBuilder sb= new StringBuilder(1024);
		UIAccess.getDisplay().syncExec(new Runnable() {
			@Override
			public void run() {
				collectCss(sb);
			}
		});
		sb.append(".header { display: none; }"); //$NON-NLS-1$
		this.cssStyle= sb.toString();
	}
	
	protected void collectCss(final StringBuilder sb) {
	}
	
	@Override
	protected void customizeCss(final PrintWriter writer) {
//		updateStyles();
		writer.print(this.cssStyle);
	}
	
	@Override
	protected void customizePageHtmlHeader(final HttpServletRequest req, final PrintWriter writer) {
		customizeHtmlHeader(req, writer, true);
	}
	
	@Override
	protected void customizeIndexHtmlHeader(final HttpServletRequest req, final PrintWriter writer) {
		customizeHtmlHeader(req, writer, false);
	}
	
	protected void customizeHtmlHeader(final HttpServletRequest req, final PrintWriter writer,
			final boolean page) {
		writer.println("<script type=\"text/javascript\">/* <![CDATA[ */"); //$NON-NLS-1$
		
		writer.println("function keyNavHandler(event) {"); //$NON-NLS-1$
		writer.println("if (!event) event= window.event;"); //$NON-NLS-1$
		writer.println("if (event.which) { key= event.which } else if (event.keyCode) { key= event.keyCode };"); //$NON-NLS-1$
		writer.println("if (!event.ctrlKey && !event.altKey) { var anchor= 0;"); //$NON-NLS-1$
		if (page) {
			writer.println("if (key == 68) anchor= \"#description\"; " + //$NON-NLS-1$
					"else if (key == 85) anchor= \"#usage\"; " + //$NON-NLS-1$
					"else if (key == 65) anchor= \"#arguments\"; " + //$NON-NLS-1$
					"else if (key == 73) anchor= \"#details\"; " + //$NON-NLS-1$
					"else if (key == 86) anchor= \"#value\"; " + //$NON-NLS-1$
					"else if (key == 79) anchor= \"#authors\"; " + //$NON-NLS-1$
					"else if (key == 82) anchor= \"#references\"; " + //$NON-NLS-1$
					"else if (key == 69) anchor= \"#examples\"; " + //$NON-NLS-1$
					"else if (key == 83) anchor= \"#seealso\";"); //$NON-NLS-1$
		}
		else {
			writer.println("if (key >= 65 && key <= 90) anchor= \"#idx\"+String.fromCharCode(key+32);"); //$NON-NLS-1$
		}
		writer.println("if (anchor) { window.location.hash= anchor; event.cancelBubble= true; return false; }"); //$NON-NLS-1$
		writer.println("} return true; }"); //$NON-NLS-1$
		writer.println("document.onkeydown= keyNavHandler;"); //$NON-NLS-1$
		
		writer.println("/* ]]> */</script>"); //$NON-NLS-1$
		
		if (HOVER_STYLE.equals(req.getParameter(STYLE_PARAM))) {
			writer.println("<style type=\"text/css\">body { overflow: hidden; }</style>"); //$NON-NLS-1$
		}
	}
	
	@Override
	protected void printRCode(final PrintWriter writer, final String html) {
		synchronized (this.rCodeScanner) {
			this.rCodeScanner.setHtml(html);
			writer.write("<span style=\""); //$NON-NLS-1$
			writer.write(this.rCodeScanner.getDefaultStyle());
			writer.write("\">"); //$NON-NLS-1$
			
			IToken token;
			int currentIdx= 0;
			while (!(token= this.rCodeScanner.nextToken()).isEOF()) {
				final String data= (String) token.getData();
				if (data != null) {
					final int tokenIdx= this.rCodeScanner.getTokenOffset();
					if (tokenIdx > currentIdx) {
						writer.write(html, currentIdx, tokenIdx-currentIdx);
					}
					writer.write("<span style=\""); //$NON-NLS-1$
					writer.write(data);
					writer.write("\">"); //$NON-NLS-1$
					writer.write(html, tokenIdx, this.rCodeScanner.getTokenLength());
					writer.write("</span>"); //$NON-NLS-1$
					currentIdx= tokenIdx + this.rCodeScanner.getTokenLength();
				}
			}
			writer.write(html, currentIdx, html.length()-currentIdx);
			
			writer.write("</span>"); //$NON-NLS-1$
		}
	}
	
}
