/*******************************************************************************
 * Copyright (c) 2004 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 API and implementation
 *******************************************************************************/
package org.eclipse.wst.html.core.document;



import java.util.Iterator;

import org.eclipse.wst.sse.core.INodeNotifier;
import org.eclipse.wst.sse.core.text.IStructuredDocument;
import org.eclipse.wst.sse.core.text.IStructuredDocumentRegion;
import org.eclipse.wst.sse.core.text.ITextRegion;
import org.eclipse.wst.sse.core.text.ITextRegionList;
import org.eclipse.wst.xml.core.document.TagAdapter;
import org.eclipse.wst.xml.core.document.XMLElement;
import org.eclipse.wst.xml.core.document.XMLModel;
import org.eclipse.wst.xml.core.jsp.model.parser.temp.XMLJSPRegionContexts;
import org.eclipse.wst.xml.core.parser.XMLRegionContext;

/**
 */
public class MetaDataAdapter implements TagAdapter, MetaData {

	private XMLElement element = null;
	private String type = null;
	private String data = null;
	private String endData = null;

	/**
	 */
	public MetaDataAdapter(String type) {
		super();

		if (type != null) {
			if (type.equals(ANNOTATION)) {
				this.type = ANNOTATION;
			}
			else if (type.equals(AUTHOR_TIME_VISUAL)) {
				this.type = AUTHOR_TIME_VISUAL;
			}
			else {
				this.type = type;
			}
		}
	}

	/**
	 */
	private String getData(IStructuredDocumentRegion flatNode) {
		if (flatNode == null)
			return null;
		ITextRegionList regions = flatNode.getRegions();
		if (regions == null)
			return null;

		String data = null;
		Iterator e = regions.iterator();
		while (e.hasNext()) {
			ITextRegion region = (ITextRegion) e.next();
			String regionType = region.getType();
			if (regionType == XMLRegionContext.XML_COMMENT_TEXT || regionType == XMLJSPRegionContexts.JSP_COMMENT_TEXT) {
				data = flatNode.getText(region);
				break;
			}
		}
		if (data == null)
			return null;
		int length = data.length();
		int offset = 0;
		for (; offset < length; offset++) {
			char c = data.charAt(offset);
			if (c == '\r' || c == '\n') {
				offset++;
				break;
			}
		}
		for (; offset < length; offset++) {
			char c = data.charAt(offset);
			if (c != '\r' && c != '\n') {
				break;
			}
		}
		return data.substring(offset);
	}

	/**
	 */
	public String getData() {
		if (this.element == null)
			return null;
		IStructuredDocumentRegion flatNode = this.element.getStartStructuredDocumentRegion();
		if (flatNode == null)
			return null;
		if (this.data != null)
			return this.data;
		return getData(flatNode);
	}

	/**
	 */
	private String getDelimiter(XMLModel model) {
		String delim = null;
		if (model != null) {
			IStructuredDocument structuredDocument = model.getStructuredDocument();
			if (structuredDocument != null)
				delim = structuredDocument.getLineDelimiter();
		}
		if (delim == null)
			delim = "\r\n";//$NON-NLS-1$
		return delim;
	}

	/**
	 */
	public String getEndData() {
		if (this.element == null)
			return null;
		IStructuredDocumentRegion flatNode = this.element.getEndStructuredDocumentRegion();
		if (flatNode == null)
			return null;
		if (this.endData != null)
			return this.endData;
		return getData(flatNode);
	}

	/**
	 */
	public String getEndTag(XMLElement element) {
		StringBuffer buffer = new StringBuffer();
		if (element.isJSPTag())
			buffer.append("<%--");//$NON-NLS-1$
		else
			buffer.append("<!--");//$NON-NLS-1$
		buffer.append(METADATA);
		buffer.append(' ');
		buffer.append(TYPE);
		buffer.append("=\"");//$NON-NLS-1$
		buffer.append(this.type);
		buffer.append("\" ");//$NON-NLS-1$
		buffer.append(MetaData.ENDSPAN);
		String data = getEndData();
		if (data != null && data.length() > 0) {
			String delim = getDelimiter(element.getModel());
			buffer.append(delim);
			buffer.append(data);
			buffer.append(delim);
		}
		if (element.isJSPTag())
			buffer.append("--%>");//$NON-NLS-1$
		else
			buffer.append("-->");//$NON-NLS-1$

		return buffer.toString();
	}

	/**
	 */
	public String getStartTag(XMLElement element) {
		StringBuffer buffer = new StringBuffer();
		if (element.isJSPTag())
			buffer.append("<%--");//$NON-NLS-1$
		else
			buffer.append("<!--");//$NON-NLS-1$
		buffer.append(METADATA);
		buffer.append(' ');
		buffer.append(TYPE);
		buffer.append("=\"");//$NON-NLS-1$
		buffer.append(this.type);
		buffer.append("\" ");//$NON-NLS-1$
		buffer.append(MetaData.STARTSPAN);
		String data = getData();
		if (data != null && data.length() > 0) {
			String delim = getDelimiter(element.getModel());
			buffer.append(delim);
			buffer.append(data);
			buffer.append(delim);
		}
		if (element.isJSPTag())
			buffer.append("--%>");//$NON-NLS-1$
		else
			buffer.append("-->");//$NON-NLS-1$

		return buffer.toString();
	}

	/**
	 */
	public String getType() {
		return this.type;
	}

	/**
	 */
	public boolean isAdapterForType(Object type) {
		return (type == TagAdapter.class || type == MetaDataAdapter.class);
	}

	/**
	 */
	public boolean isEndTag() {
		if (this.element == null)
			return false;
		if (this.element.hasStartTag())
			return false;
		if (this.element.hasEndTag())
			return true;
		if (this.data != null)
			return false;
		return (this.endData != null);
	}

	/**
	 */
	public boolean isRuntimeContainer() {
		return (this.type == ANNOTATION || this.type == AUTHOR_TIME_VISUAL);
	}

	/**
	 */
	public void notifyChanged(INodeNotifier notifier, int eventType, Object changedFeature, Object oldValue, Object newValue, int pos) {
	}

	/**
	 */
	public void setData(String data) {
		this.data = data;

		if (this.element != null)
			this.element.notifyStartTagChanged();
	}

	/**
	 */
	public void setEndData(String data) {
		this.endData = data;

		if (this.element != null)
			this.element.notifyEndTagChanged();
	}

	/**
	 */
	public void setElement(XMLElement element) {
		this.element = element;

		if (this.element != null) {
			this.element.setCommentTag(true);
			if (this.type != MetaData.ANNOTATION) {
				this.element.setJSPTag(true);
			}
		}
	}

	/**
	 */
	public void setRuntimeSource(String source) {
		if (source == null)
			return;
		if (this.element == null)
			return;
		if (isRuntimeContainer())
			return;

		XMLModel model = this.element.getModel();
		if (model == null)
			return;
		IStructuredDocument structuredDocument = model.getStructuredDocument();
		if (structuredDocument == null)
			return;
		int offset = this.element.getStartEndOffset();
		int end = this.element.getEndStartOffset();
		int length = end - offset;
		structuredDocument.replaceText(model, offset, length, source);
	}
}