//------------------------------------------------------------------------------
// Copyright (c) 2005, 2007 IBM Corporation 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:
// IBM Corporation - initial implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.authoring.ui.editors;

import java.io.UnsupportedEncodingException;
import java.util.regex.Matcher;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.emf.common.util.BasicDiagnostic;
import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.EStructuralFeature;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.epf.authoring.ui.forms.BaseFormPage;
import org.eclipse.epf.authoring.ui.richtext.IMethodRichText;
import org.eclipse.epf.authoring.ui.richtext.MethodRichTextContext;
import org.eclipse.epf.authoring.ui.util.MethodRichTextMarkerHelper;
import org.eclipse.epf.common.html.HTMLFormatter;
import org.eclipse.epf.library.layout.RichTextContentValidator;
import org.eclipse.epf.library.util.ResourceHelper;
import org.eclipse.epf.richtext.RichText;
import org.eclipse.epf.uma.ContentDescription;
import org.eclipse.epf.uma.DescribableElement;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.ProcessComponent;
import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.jface.fieldassist.FieldDecorationRegistry;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;

/**
 * A Method Editor Rich Text control.
 * 
 * @author Kelvin Low
 * @author Jeff Hardy
 * @since 1.0
 */
public class MethodRichText extends RichText implements IMethodRichText {

	// The method element associated with this rich text control.
	private MethodElement methodElement;
	
	// the MethodElement's ContentDescription
	private ContentDescription contentDescription;

	// The modal object associated with this rich text control.
	private EObject modalObject;

	// The modal object feature associated with this rich text control.
	private EStructuralFeature modalObjectFeature;

	// The resource being edited       
	protected Resource resource;
	
	// the decoratedField label
	protected Label label;
	
	protected ControlDecoration controlDecoration;
	
	protected final Image errorFieldDecorationImage = FieldDecorationRegistry.getDefault().getFieldDecoration(FieldDecorationRegistry.DEC_ERROR).getImage();
                                      
	// Field name being edited
	protected String fieldName = ""; //$NON-NLS-1$

	// Field name being edited with the trailing : removed     
	protected String fieldNameTrim;
	
	// marker helper
	protected MethodRichTextMarkerHelper markerHelper;
	
//	// marker attribute
//	private static String METHOD_FIELDNAME = "MethodFieldName";

//	// marker ID
//	protected static final String MARKER_ID = "org.eclipse.epf.authoring.ui.methodRichText"; //$NON-NLS-1$

	/**
	 * Creates a new instance.
	 * 
	 * @param parent
	 *            The parent control.
	 * @param style
	 *            The initial style for the editor.
	 * @param basePath
	 *            The base path used for resolving hrefs.
	 */
	public MethodRichText(Composite parent, int style, String basePath) {
		super(parent, style, basePath);
	}

	/**
	 * Creates a new instance.
	 * 
	 * @param context
	 *            The context
	 */
	public MethodRichText(MethodRichTextContext context) {
		super(context.getParent(), context.getStyle(), context.getBasePath());
	}

	/**
	 * Updates the presentation names of all element links.
	 * 
	 * @param text
	 *            Rich text encoded in HTML format.
	 */
	@Override
	protected String tidyText(String text) {
		/*
		 *  this will do the following to the HTML:
		 *  1.  update Element Links
		 *  2.  change <A ..> to <a ..>
		 *  3.  change </A> to </a>
		 *  4.  add double-quotes (") around all attribute values if they are missing
		 */
		
		return ResourceHelper.validateRichTextContent(methodElement, text,
				new RichTextContentValidator());
	}

	/**
	 * Sets the method element associated with this rich text control.
	 * 
	 * @param methodElement
	 */
	public void setMethodElement(MethodElement methodElement) {
		this.methodElement = methodElement;
		if (this.methodElement instanceof ProcessComponent) {
			this.methodElement = ((ProcessComponent) this.methodElement).getProcess();
		}
		if (this.methodElement instanceof DescribableElement) { 
			this.contentDescription = ((DescribableElement)this.methodElement).getPresentation();
		}
	}

	/**
	 * Returns the method element associated with this rich text control.
	 */
	public MethodElement getMethodElement() {
		return methodElement;
	}

	/**
	 * Returns the modal object associated with this rich text control.
	 */
	public EObject getModalObject() {
		return modalObject;
	}

	/**
	 * Sets the modal object associated with this rich text control.
	 */
	public void setModalObject(EObject modalObject) {
		this.modalObject = modalObject;
	}

	/**
	 * Returns modal object feature associated with this rich text control.
	 */
	public EStructuralFeature getModalObjectFeature() {
		return modalObjectFeature;
	}

	/**
	 * Sets the modal object feature associated with this rich text control.
	 */
	public void setModalObjectFeature(EStructuralFeature modalObjectFeature) {
		this.modalObjectFeature = modalObjectFeature;
	}

	public String getFieldName() {
		return fieldName;
	}

	public void setDecoratedFieldLabel(Label label) {
		this.label = label;
		if (label != null) {
			Object data = label.getData(BaseFormPage.LABEL_DECORATOR_KEY);
			if (data instanceof ControlDecoration) {
				controlDecoration = (ControlDecoration)data;
				controlDecoration.setImage(errorFieldDecorationImage);
				controlDecoration.hide();
			}
			updateFieldNameFromLabel(label);
		}
	}

	private boolean updateFieldNameFromLabel(Label label) {
		if (label != null) {
			String fieldName = label.getText();
			if (!this.fieldName.equals(fieldName)) {
				this.fieldName = fieldName;
				int colonIndex = fieldName.indexOf(':');
				if (colonIndex == -1)
					colonIndex = fieldName.length();
				this.fieldNameTrim = fieldName.substring(0, colonIndex).trim();
				return true;
			}
		}
		return false;
	}
	
	public void init(MethodElement element, Label label) {
		setMethodElement(element);
		setDecoratedFieldLabel(label);
		markerHelper = MethodRichTextMarkerHelper.INSTANCE;
	}
	
	@Override
	protected String formatHTML(String text) {
		String formattedText;
		try {
			// clear markers first
			clearMarkers();
			// Call JTidy to format the source to XHTML.
			formattedText = htmlFormatter.formatHTML(text);
			if (htmlFormatter.getLastErrorStr() != null) {
				String errorString = htmlFormatter.getLastErrorStr();
				// create markers
				try {
					createMarker(errorString);
				} catch (CoreException cex) {
					logger.logError(cex);
				}
			}
			return formattedText;
		} catch (UnsupportedEncodingException e) {
			logger.logError(e);
		}
		return text;
	}
	
	protected void clearMarkers() {
		markerHelper.deleteMarkers(contentDescription, fieldNameTrim);
		setErrorDescription(""); //$NON-NLS-1$
		hideErrorDecoration();
		refreshDecorators();
	}
	
	protected void setErrorDescription(String text) {
		if (controlDecoration != null) {
			controlDecoration.setDescriptionText(text);
		}
	}
	
	protected void refreshDecorators() {
		// refresh
//		PlatformUI.getWorkbench().getDecoratorManager().update(MethodElementLightweightLabelDecorator.DECORATOR_ID);
	}
	
	
	/*
	 * TODO:
	 * had to undo change in DescribableElementImpl to set presentation on any new obj
	 * so editor will need to assign presentation when field is edited so that the marker
	 * can be added to the presentation's resource
	 */
	
	
	protected void createMarker(String fullErrMsg) throws CoreException {
		if (contentDescription.eContainer() instanceof DescribableElement) {
			Matcher m = HTMLFormatter.jTidyErrorParser.matcher(fullErrMsg);                                                                          
			if (m.find()) {                                                                                                                          
				String location = m.group(1);
				String errorMsg = m.group(4);
				BasicDiagnostic diagnostics = 
			          new BasicDiagnostic
			            (HTMLFormatter.DIAGNOSTIC_SOURCE,
			             0, "", //$NON-NLS-1$
			                new Object[] { contentDescription, fieldNameTrim });
	
				diagnostics.add( 
					new BasicDiagnostic(Diagnostic.ERROR,
						location, 0, errorMsg,
						new Object[] { contentDescription, fieldNameTrim }));
	
		        markerHelper.createMarkers(diagnostics);
		        setErrorDescription(errorMsg);
		        showErrorDecoration();
				refreshDecorators();
			}
		}
	}

	@Override
	public void dispose() {
		super.dispose();
		clearMarkers();
		refreshDecorators();
	}
	
	public void showErrorDecoration() {
        if (controlDecoration != null) {
        	controlDecoration.show();
        }
	}

	public void hideErrorDecoration() {
        if (controlDecoration != null) {
        	controlDecoration.hide();
        }
	}
	
	@Override
	public void setText(String text) {
		// check if label text was changed (this happens when RTE is expanded)
		// this is called when RTE is toggled in editor - read new fieldName
		if (updateFieldNameFromLabel(label))
			hideErrorDecoration();
		super.setText(text);
	}
}
