//------------------------------------------------------------------------------
// 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.IHTMLFormatter;
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) {
		this(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 = IHTMLFormatter.jTidyErrorParser.matcher(fullErrMsg);                                                                          
			if (m.find()) {                                                                                                                          
				String location = m.group(1);
				String errorMsg = m.group(4);
				BasicDiagnostic diagnostics = 
			          new BasicDiagnostic
			            (IHTMLFormatter.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);
	}
}
