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