//------------------------------------------------------------------------------
// 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();
		} else if (this.methodElement instanceof ContentDescription) {
			this.contentDescription = (ContentDescription)(this.methodElement);
		}
	}

	/**
	 * 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);
	}
}
