/*******************************************************************************
 * Copyright (c) 2007, 2015 David Green and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     David Green - initial API and implementation
 *******************************************************************************/
package org.eclipse.mylyn.internal.wikitext.ui.editor.preferences;

import java.io.IOException;
import java.io.Reader;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.regex.Pattern;

import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.mylyn.internal.wikitext.ui.WikiTextUiPlugin;
import org.eclipse.mylyn.internal.wikitext.ui.viewer.HtmlTextPresentationParser;
import org.eclipse.mylyn.wikitext.parser.css.CssParser;
import org.eclipse.mylyn.wikitext.parser.css.Stylesheet;

import com.google.common.io.CharStreams;

/**
 * @see WikiTextUiPlugin#getPreferences()
 * @author David Green
 */
public class Preferences implements Cloneable {

	private static final String KEY_MARKUP_VIEWER_CSS = "preview.css"; //$NON-NLS-1$

	private static final String KEY_EDITOR_FOLDING = "editorFolding"; //$NON-NLS-1$

	private static final Pattern BAD_CHAR_PATTERN = Pattern.compile("[^a-zA-Z0-9]"); //$NON-NLS-1$

	public static final String PHRASE_CODE = "@code@"; //$NON-NLS-1$

	public static final String PHRASE_SPAN = "%span%"; //$NON-NLS-1$

	public static final String PHRASE_SUBSCRIPT = "~subscript~"; //$NON-NLS-1$

	public static final String PHRASE_SUPERSCRIPT = "^superscript^"; //$NON-NLS-1$

	public static final String PHRASE_INSERTED_TEXT = "+inserted text+"; //$NON-NLS-1$

	public static final String PHRASE_DELETED_TEXT = "-deleted text-"; //$NON-NLS-1$

	public static final String PHRASE_CITATION = "??citation??"; //$NON-NLS-1$

	public static final String PHRASE_BOLD = "**bold**"; //$NON-NLS-1$

	public static final String PHRASE_ITALIC = "__italic__"; //$NON-NLS-1$

	public static final String PHRASE_STRONG = "*strong*"; //$NON-NLS-1$

	public static final String PHRASE_EMPHASIS = "_emphasis_"; //$NON-NLS-1$

	public static final String PHRASE_MONOSPACE = "monospace"; //$NON-NLS-1$

	public static final String PHRASE_UNDERLINED = "underlined"; //$NON-NLS-1$

	public static final String PHRASE_QUOTE = "quote"; //$NON-NLS-1$

	public static final String BLOCK_QUOTE = "bq."; //$NON-NLS-1$

	public static final String BLOCK_PRE = "pre."; //$NON-NLS-1$

	public static final String BLOCK_BC = "bc."; //$NON-NLS-1$

	public static final String BLOCK_H6 = "h6."; //$NON-NLS-1$

	public static final String BLOCK_H5 = "h5."; //$NON-NLS-1$

	public static final String BLOCK_H4 = "h4."; //$NON-NLS-1$

	public static final String BLOCK_H3 = "h3."; //$NON-NLS-1$

	public static final String BLOCK_H2 = "h2."; //$NON-NLS-1$

	public static final String BLOCK_H1 = "h1."; //$NON-NLS-1$

	public static final String BLOCK_DT = "dt"; //$NON-NLS-1$

	/**
	 * heading preferences key indexed by level (0 is null, 1 is {@link #BLOCK_H1}, etc.)
	 */
	public static final String[] HEADING_PREFERENCES = new String[] { null, BLOCK_H1, BLOCK_H2, BLOCK_H3, BLOCK_H4,
			BLOCK_H5, BLOCK_H6 };

	private Map<String, String> cssByBlockModifierType = new LinkedHashMap<>();

	{
		cssByBlockModifierType.put(BLOCK_H1, "font-size: 120%; font-weight: bold; color: #172f47;"); //$NON-NLS-1$
		cssByBlockModifierType.put(BLOCK_H2, "font-size: 110%; font-weight: bold; color: #172f47;"); //$NON-NLS-1$
		cssByBlockModifierType.put(BLOCK_H3, "font-size: 105%; font-weight: bold; color: #172f47;"); //$NON-NLS-1$
		cssByBlockModifierType.put(BLOCK_H4, "font-weight: bold; color: #172f47;"); //$NON-NLS-1$
		cssByBlockModifierType.put(BLOCK_H5, "font-size: 90%; font-weight: bold; color: #172f47;"); //$NON-NLS-1$
		cssByBlockModifierType.put(BLOCK_H6, "font-size: 80%; font-weight: bold; color: #172f47;"); //$NON-NLS-1$
		cssByBlockModifierType.put(BLOCK_BC, "font-family: monospace; color: #4444CC;"); //$NON-NLS-1$
		cssByBlockModifierType.put(BLOCK_PRE, "font-family: monospace;"); //$NON-NLS-1$
		cssByBlockModifierType.put(BLOCK_QUOTE, "color: rgb(38,86,145);"); //$NON-NLS-1$
		cssByBlockModifierType.put(BLOCK_DT, "font-weight: bold;"); //$NON-NLS-1$
	}

	private Map<String, String> cssByPhraseModifierType = new LinkedHashMap<>();

	{

		cssByPhraseModifierType.put(PHRASE_EMPHASIS, "font-style: italic;"); //$NON-NLS-1$
		cssByPhraseModifierType.put(PHRASE_STRONG, "font-weight: bold;"); //$NON-NLS-1$
		cssByPhraseModifierType.put(PHRASE_ITALIC, "font-style: italic;"); //$NON-NLS-1$
		cssByPhraseModifierType.put(PHRASE_BOLD, "font-weight: bold;"); //$NON-NLS-1$
		cssByPhraseModifierType.put(PHRASE_CITATION, "font-style: italic;"); //$NON-NLS-1$
		cssByPhraseModifierType.put(PHRASE_DELETED_TEXT, "text-decoration: line-through;"); //$NON-NLS-1$
		cssByPhraseModifierType.put(PHRASE_INSERTED_TEXT, "text-decoration: underline;"); //$NON-NLS-1$
		cssByPhraseModifierType.put(PHRASE_SUPERSCRIPT, "font-size: smaller; vertical-align: super;"); //$NON-NLS-1$
		cssByPhraseModifierType.put(PHRASE_SUBSCRIPT, "font-size: smaller; vertical-align: sub;"); //$NON-NLS-1$
		cssByPhraseModifierType.put(PHRASE_SPAN, ""); //$NON-NLS-1$
		cssByPhraseModifierType.put(PHRASE_CODE, "font-family: monospace; color: #4444CC;"); //$NON-NLS-1$
		cssByPhraseModifierType.put(PHRASE_MONOSPACE, "font-family: monospace;"); //$NON-NLS-1$
		cssByPhraseModifierType.put(PHRASE_UNDERLINED, "text-decoration: underline;"); //$NON-NLS-1$
		cssByPhraseModifierType.put(PHRASE_QUOTE, "color: rgb(38,86,145);"); //$NON-NLS-1$
	}

	private boolean editorFolding = true;

	private String markupViewerCss;

	private Stylesheet stylesheet;

	private boolean mutable = true;

	public Map<String, String> getCssByBlockModifierType() {
		return cssByBlockModifierType;
	}

	public Map<String, String> getCssByPhraseModifierType() {
		return cssByPhraseModifierType;
	}

	/**
	 * indicate if editor folding is enabled
	 */
	public boolean isEditorFolding() {
		return editorFolding;
	}

	/**
	 * indicate if editor folding is enabled
	 */
	public void setEditorFolding(boolean editorFolding) {
		if (!mutable) {
			throw new UnsupportedOperationException();
		}
		this.editorFolding = editorFolding;
	}

	/**
	 * get the CSS content used to render the markup viewer
	 */
	public String getMarkupViewerCss() {
		if (markupViewerCss == null) {
			markupViewerCss = getDefaultMarkupViewerCss();
		}
		return markupViewerCss;
	}

	/**
	 * set the CSS content used to render the markup viewer
	 */
	public void setMarkupViewerCss(String markupViewerCss) {
		if (!mutable) {
			throw new UnsupportedOperationException();
		}
		this.markupViewerCss = markupViewerCss;
		stylesheet = null;
	}

	public Stylesheet getStylesheet() {
		if (stylesheet == null) {
			stylesheet = new CssParser().parse(getMarkupViewerCss());
		}
		return stylesheet;
	}

	/**
	 * indicate if this preferences is mutable
	 *
	 * @see #makeImmutable()
	 */
	public boolean isMutable() {
		return mutable;
	}

	/**
	 * @see #isMutable()
	 */
	public void makeImmutable() {
		if (mutable) {
			mutable = false;
			cssByBlockModifierType = Collections.unmodifiableMap(cssByBlockModifierType);
			cssByPhraseModifierType = Collections.unmodifiableMap(cssByPhraseModifierType);
		}
	}

	/**
	 * Save the settings to the given store
	 *
	 * @param store
	 *            the store to which the settings should be saved
	 * @param asDefault
	 *            if true, then the settings are saved as defaults.
	 */
	public void save(IPreferenceStore store, boolean asDefault) {
		for (Map.Entry<String, String> ent : cssByBlockModifierType.entrySet()) {
			String propKey = toPreferenceKey(ent.getKey(), true);
			if (asDefault) {
				store.setDefault(propKey, ent.getValue());
			} else {
				store.setValue(propKey, ent.getValue());
			}
		}
		for (Map.Entry<String, String> ent : cssByPhraseModifierType.entrySet()) {
			String propKey = toPreferenceKey(ent.getKey(), false);
			if (asDefault) {
				store.setDefault(propKey, ent.getValue());
			} else {
				store.setValue(propKey, ent.getValue());
			}
		}
		if (asDefault) {
			store.setDefault(KEY_EDITOR_FOLDING, editorFolding);
			store.setDefault(KEY_MARKUP_VIEWER_CSS, getDefaultMarkupViewerCss());
		} else {
			store.setValue(KEY_EDITOR_FOLDING, editorFolding);
			store.setValue(KEY_MARKUP_VIEWER_CSS, markupViewerCss);
		}
	}

	public static String toPreferenceKey(String key, boolean block) {
		String propKey = (block ? "block-" : "phrase-") + BAD_CHAR_PATTERN.matcher(key).replaceAll(""); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
		return propKey;
	}

	public void load(IPreferenceStore store) {
		if (!mutable) {
			throw new UnsupportedOperationException();
		}
		for (Map.Entry<String, String> ent : cssByBlockModifierType.entrySet()) {
			String propKey = toPreferenceKey(ent.getKey(), true);

			String value = store.getString(propKey);
			if (value != null) {
				ent.setValue(value);
			}
		}
		for (Map.Entry<String, String> ent : cssByPhraseModifierType.entrySet()) {
			String propKey = toPreferenceKey(ent.getKey(), false);
			String value = store.getString(propKey);
			if (value != null) {
				ent.setValue(value);
			}
		}
		editorFolding = store.getBoolean(KEY_EDITOR_FOLDING);
		markupViewerCss = store.getString(KEY_MARKUP_VIEWER_CSS);
		if (isEmpty(markupViewerCss)) {
			markupViewerCss = getDefaultMarkupViewerCss();
		}
		stylesheet = null;
	}

	private String getDefaultMarkupViewerCss() {
		try (Reader reader = HtmlTextPresentationParser.getDefaultStylesheetContent()) {
			return CharStreams.toString(reader);
		} catch (IOException e) {
			WikiTextUiPlugin.getDefault().log(e);
			return ""; //$NON-NLS-1$
		}
	}

	private boolean isEmpty(String text) {
		if (text == null || text.length() == 0) {
			return true;
		}
		final int length = text.length();
		for (int x = 0; x < length; ++x) {
			char c = text.charAt(x);
			if (!Character.isWhitespace(c)) {
				return false;
			}
		}
		return true;
	}

	/**
	 * clone the preferences, returning a mutable copy.
	 */
	@Override
	public Preferences clone() {
		try {
			Preferences copy = (Preferences) super.clone();
			copy.mutable = true;
			return copy;
		} catch (CloneNotSupportedException e) {
			throw new IllegalStateException();
		}
	}
}
