/*******************************************************************************
 * 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.jst.jsp.core.internal.document;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.jface.text.IDocumentExtension3;
import org.eclipse.jface.text.IDocumentPartitioner;
import org.eclipse.jst.jsp.core.internal.modelhandler.EmbeddedTypeStateData;
import org.eclipse.jst.jsp.core.internal.text.StructuredTextPartitionerForJSP;
import org.eclipse.wst.sse.core.internal.ltk.modelhandler.EmbeddedTypeHandler;
import org.eclipse.wst.sse.core.internal.modelhandler.EmbeddedTypeRegistry;
import org.eclipse.wst.sse.core.internal.modelhandler.EmbeddedTypeRegistryImpl;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapter;
import org.eclipse.wst.sse.core.internal.provisional.INodeAdapterFactory;
import org.eclipse.wst.sse.core.internal.provisional.INodeNotifier;
import org.eclipse.wst.sse.core.internal.provisional.IStructuredModel;
import org.eclipse.wst.sse.core.internal.provisional.text.IStructuredPartitioning;
import org.eclipse.wst.sse.core.internal.util.Debug;
import org.eclipse.wst.sse.core.internal.util.StringUtils;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;

/**
 * This class has the responsibility to provide 
 * an embedded factory registry for JSP Aware INodeAdapter Factories
 * to use. 
 * 
 * Typically, the embedded type is to be considered a feature of 
 * the document, so JSP Aware AdpaterFactories should call
 * getAdapter(PageDirectiveAdapter.class) directoy on the document
 * (or owning document) node.
 */
public class PageDirectiveAdapterImpl implements PageDirectiveAdapter {

	protected static final String STR_CHARSET = "charset"; //$NON-NLS-1$
	private final static Object adapterType = PageDirectiveAdapter.class;
	private IStructuredModel model;
	protected final String[] JAVASCRIPT_LANGUAGE_KEYS = new String[]{"javascript", "javascript1.0", "javascript1.1_3", "javascript1.2", "javascript1.3", "javascript1.4", "javascript1.5", "javascript1.6", "jscript", "sashscript"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$ //$NON-NLS-8$ //$NON-NLS-9$ //$NON-NLS-10$
	protected final String[] JAVA_LANGUAGE_KEYS = new String[]{"java"}; //$NON-NLS-1$

	/**
	 * Constructor for PageDirectiveAdapterImpl.
	 */
	public PageDirectiveAdapterImpl(INodeNotifier target) {
		super();
		notifierAtCreation = target;
		// we need to remember our instance of model, 
		// in case we need to "signal" a re-init needed.
		if (target instanceof IDOMNode) {
			IDOMNode node = (IDOMNode) target;
			model = node.getModel();
		}

	}

	/**
	 * parses the full contentType value into its two parts
	 * the contentType, and the charset, if present. Note: this 
	 * method is a lightly modified version of a method in AbstractHeadParser.
	 * There, we're mostly interested in the charset part of contentTypeValue. 
	 * Here, we're mostly interested in the mimeType part.
	 */
	private String getMimeTypeFromContentTypeValue(String contentTypeValue) {
		if (contentTypeValue == null)
			return null;
		String cleanContentTypeValue = StringUtils.stripNonLetterDigits(contentTypeValue);
		StringTokenizer tokenizer = new StringTokenizer(cleanContentTypeValue, ";= \t\n\r\f"); //$NON-NLS-1$
		int tLen = tokenizer.countTokens();
		// if contains encoding should have three tokens, the mimetype, the word 'charset', and the encoding value
		String[] tokens = new String[tLen];
		int j = 0;
		while (tokenizer.hasMoreTokens()) {
			tokens[j] = tokenizer.nextToken();
			j++;
		}
		// 
		// Following is the common form for target expression		
		// <META http-equiv="Content-Type" content="text/html; charset=UTF-8">
		// But apparrently is also valid without the content type there, 
		// just the charset, as follows:
		// <META http-equiv="Content-Type" content="charset=UTF-8">
		// So we'll loop through tokens and key off of 'charset'

		int charsetPos = -1;
		for (int i = 0; i < tokens.length; i++) {
			if (tokens[i].equalsIgnoreCase(STR_CHARSET)) {
				charsetPos = i;
				break;
			}
		}
		//String charset = null;
		String contentType = null;
		if (charsetPos > -1) {
			// case where charset was present
			//			int charsetValuePos = charsetPos + 1;
			//			if (charsetValuePos < tokens.length) {
			//				charset = tokens[charsetValuePos];
			//			}
			int contentTypeValuePos = charsetPos - 1;
			if (contentTypeValuePos > -1) {
				contentType = tokens[contentTypeValuePos];
			}
		}
		else {
			// charset was not present, so if there's 
			// a value, we assume its the contentType value
			if (tokens.length > 0) {
				contentType = tokens[0];
			}
		}
		return contentType;
	}

	private EmbeddedTypeHandler embeddedTypeHandler;
	private List embeddedFactoryRegistry = new ArrayList();
	private String cachedLanguage;
	private String cachedContentType;
	private INodeNotifier notifierAtCreation;

	private int firstLanguagePosition = -1;
	private int firstContentTypePosition = -1;

	private boolean reinitializing;

	/*
	 * @see INodeAdapter#isAdapterForType(Object)
	 */
	public boolean isAdapterForType(Object type) {
		return (type == adapterType);
	}

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

	public void setEmbeddedType(EmbeddedTypeHandler handler) {
		// if really the same handler, no need for further processing
		if (embeddedTypeHandler == handler) {
			return;
		}
		// then one exists, and the new one is truely different, so we need to 
		// release and remove current factories
		if (embeddedTypeHandler != null) {
			Iterator list = embeddedFactoryRegistry.iterator();
			while (list.hasNext()) {
				INodeAdapterFactory factory = (INodeAdapterFactory) list.next();
				factory.release();
			}

			embeddedFactoryRegistry.clear();
		}

		embeddedTypeHandler = handler;
		// when the handler is set, "transfer" its factories to our own list.
		// note: our own list may also be added to else where, such as on
		// "editor side".
		if (embeddedTypeHandler != null) {
			Iterator iterator = embeddedTypeHandler.getAdapterFactories().iterator();
			while (iterator.hasNext()) {
				INodeAdapterFactory factory = (INodeAdapterFactory) iterator.next();
				embeddedFactoryRegistry.add(factory);
			}
		}
	}

	/**
	 * @see PageDirectiveAdapter#adapt(INodeNotifier, Object)
	 */
	public INodeAdapter adapt(INodeNotifier notifier, Object type) {
		INodeAdapter result = null;
		// if embeddedContentType hasn't been set, 
		// then we can not adapt it.
		if (embeddedTypeHandler != null) {
			if (embeddedFactoryRegistry != null) {
				Iterator iterator = embeddedFactoryRegistry.iterator();
				INodeAdapterFactory factory = null;
				while (iterator.hasNext()) {
					factory = (INodeAdapterFactory) iterator.next();
					if (factory.isFactoryForType(type)) {
						result = factory.adapt(notifier);
						break;
					}
				}
			}
		}
		return result;

	}

	/**
	 * @see PageDirectiveAdapter#getEmbeddedType()
	 */
	public EmbeddedTypeHandler getEmbeddedType() {
		if (embeddedTypeHandler == null) {
			embeddedTypeHandler = getDefaultEmbeddedType();
		}
		return embeddedTypeHandler;
	}

	public void addEmbeddedFactory(INodeAdapterFactory factory) {
		// should we check if already exists in list?
		embeddedFactoryRegistry.add(factory);
	}

	//	/**
	//	 * Used by PageDirectiveWatchers to signal that some important attribute has changed, and 
	//	 * any cached values should be re-calcuated
	//	 */
	//	void changed() {
	//		// we won't actually check if change is needed, if the model state is already changing.
	//		if (!model.isReinitializationNeeded()) {
	//			// go through our list of page watcher adapters, and updates the attributes 
	//			// we're interested in, if and only if they are the earliest occurance in the resource
	//			String potentialContentType = null;
	//			String potentialLanguage = null;
	//			int contentTypePosition = -1;
	//			int languagePosition = -1;
	//			Iterator iterator = pageDirectiveWatchers.iterator();
	//			while (iterator.hasNext()) {
	//				PageDirectiveWatcher pdWatcher = (PageDirectiveWatcher) iterator.next();
	//				String contentType = pdWatcher.getContentType();
	//				String language = pdWatcher.getLanguage();
	//				int offset = pdWatcher.getOffset();
	//				if (potentialContentType == null || (hasValue(contentType) && (offset < contentTypePosition))) {
	//					potentialContentType = contentType;
	//					contentTypePosition = offset;
	//				}
	//			}
	//			// now we have the best candiates for cached values, let's see if they've really changed from 
	//			// what we had. If so, note we go through the setters so side effects can take place there.
	//			potentialContentType = getMimeTypeFromContentTypeValue(potentialContentType);
	//			if (potentialContentType == null || potentialContentType.length() == 0) {
	//				//potentialContentType = getDefaultContentType();
	//			} else {
	//				setCachedContentType(potentialContentType);
	//			}
	//
	//			if (potentialLanguage != null && hasValue(potentialLanguage)) {
	//				setCachedLanguage(potentialLanguage);
	//			}
	//		}
	//	}
	void changedContentType(int elementOffset, String newValue) {
		// only need to process if this new value is 
		// earlier in the file than our current value
		if (firstContentTypePosition == -1 || elementOffset <= firstContentTypePosition) {
			// dw_TODO: update embedded partitioner in JSP document partitioner
			// nsd_TODO: update embedded partitioner in JSP document partitioner

			// no need to change current value, if we're told some 
			// earlier value is null or blank (sounds like an error, anyway)
			if (hasValue(newValue)) {
				firstContentTypePosition = elementOffset;
				String potentialContentType = getMimeTypeFromContentTypeValue(newValue);
				// only do the set processing if different
				// from what it already is
				//	if (!potentialContentType.equalsIgnoreCase(cachedLanguage)) {
				setCachedContentType(potentialContentType);
				//	}
			}
		}
	}

	/**
	 * Used by PageDirectiveWatchers to signal that some important attribute has changed, and 
	 * any cached values should be re-calcuated
	 */
	void changedLanguage(int elementOffset, String newValue) {
		// only need to process if this new value is 
		// earlier in the file than our current value
		// has to be less than or equal to, in case our previous earliest one, 
		// is itself changing!
		if (firstLanguagePosition == -1 || elementOffset <= firstLanguagePosition) {

			// no need to change current value, if we're told some 
			// earlier value is null or blank (sounds like an error, anyway)
			if (hasValue(newValue)) {
				firstLanguagePosition = elementOffset;
				// only do the set processing if different
				// from what it already is
				if (!newValue.equalsIgnoreCase(cachedLanguage)) {
					setCachedLanguage(newValue);
				}
			}

			// dw_TODO: set language in document partitioner
			// nsd_TODO: set language in document partitioner
		}
	}

	/**
	 * Used by PageDirectiveWatchers to signal that some important attribute has changed, and 
	 * any cached values should be re-calcuated
	 */
	void changedPageEncoding(int elementOffset, String newValue) {

		// we don't currently track active value, since
		// just need during read and write (where its 
		// calculated. We will need in future, to 
		// acurately clone a model and to display 
		// "current encoding" to user in status bar.
	}

	/**
	 * Method hasValue.
	 * @param contentType
	 * @return boolean
	 */
	private boolean hasValue(String value) {
		if (value != null && value.length() > 0)
			return true;
		else
			return false;
	}

	/**
	 * Returns the cachedContentType.
	 * @return String
	 */
	public String getContentType() {
		if (cachedContentType == null) {
			cachedContentType = getDefaultContentType();
		}
		return cachedContentType;
	}

	/**
	 * Method getDefaultContentType.
	 * @return String
	 */
	private String getDefaultContentType() {
		return "text/html"; //$NON-NLS-1$
	}

	/**
	 * Returns the cachedLanguage.
	 * @return String
	 */
	public String getLanguage() {
		if (cachedLanguage == null)
			cachedLanguage = getDefaultLanguage();
		return cachedLanguage;
	}

	/**
	 * Method getDefaultLanguage.
	 * @return String
	 */
	private String getDefaultLanguage() {
		return "java"; //$NON-NLS-1$
	}

	/**
	 * Sets the cachedContentType.
	 * @param cachedContentType The cachedContentType to set
	 */
	public void setCachedContentType(String newContentType) {
		// if the passed in value is the same as existing, there's nothing to do.
		// if its different, then we need to change the contentHandler as well
		// and, more to the point, signal a re-initializtation is needed.
		// Note: if the value we're getting set to does not have a handler in the registry, 
		// we'll actually not set it to null or anything, we'll just continue on with the one
		// we have. This is pretty important to avoid re-initializing on every key stroke if someone 
		// is typing in a new content type, but haven't yet finished the whole "word".
		// However, if an contentType is not recognized, the registry returns the one 
		// for XML.
		//		if (this.cachedContentType != null && this.cachedContentType.equalsIgnoreCase(newContentType)) { // then do nothing
		//		} else {
		this.cachedContentType = newContentType;
		// see if we can update embedded handler
		//		if (this.cachedContentType == null || this.cachedContentType.length() == 0) { // do nothing, don't can't get a new handler, so we'll keep what we have
		//		} else {

		// getHandler should always return something (never null), based 
		// on the rules in the factory. 
		EmbeddedTypeHandler handler = getHandlerFor(this.cachedContentType);
		// we do this check for re-init here, instead of in setEmbeddedType, 
		// since setEmbeddedType is called during the normal initializtion 
		// process, when re-init is not needed (since there is no content)
		if (embeddedTypeHandler != null && handler != null && embeddedTypeHandler != handler) {
			// changing this embedded handler here may 
			// be in the middle of anotify loop, not sure
			// if that'll cause problems.
			
			// be sure to hold oldHandler in temp var
			// or else setEmbeddedType will "reset" it
			// before modelReinitNeeded(oldHandler, handler) is called
		    EmbeddedTypeHandler oldHandler = embeddedTypeHandler;
			setEmbeddedType(handler);
			modelReinitNeeded(oldHandler, handler);
		}
		//		}

		//		}

	}

	/**
	 * This method is used to re-init based on embeddedTypeHandler
	 * changing. It is given priority over the language change, since
	 * there its more important to have old and new handlers's in the 
	 * stateData field.
	 */
	private void modelReinitNeeded(EmbeddedTypeHandler oldHandler, EmbeddedTypeHandler newHandler) {
		if (model.isReinitializationNeeded()) {
			System.out.println("already being initialized"); //$NON-NLS-1$
		}

		try {
			model.aboutToChangeModel();
			model.setReinitializeStateData(new EmbeddedTypeStateData(oldHandler, newHandler));
			model.setReinitializeNeeded(true);
		}
		finally {
			model.changedModel();
		}
	}

	/**
	 * Method modelReinitNeeded.
	 */
	private void modelReinitNeeded(String oldlanguage, String newLanguage) {
		// bit of a short cut for now .... we dont' need language at the moment, 
		// but should set the state data
		if (model.isReinitializationNeeded()) {
			if (Debug.displayWarnings) {
				System.out.println("already being initialized"); //$NON-NLS-1$
			}
		}
		else {
			try {
				// if already being re-initialized, we don't want to 
				// reset the data in the stateData field.
				model.aboutToChangeModel();
				model.setReinitializeStateData(newLanguage);
				model.setReinitializeNeeded(true);
			}
			finally {
				model.changedModel();
			}
		}
	}

	public void setCachedLanguage(String newLanguage) {
		if (cachedLanguage != null && languageStateChanged(cachedLanguage, newLanguage)) { // a complete re-init overkill in current system, since really just need for 
			// the line style providers, 
			// BUT, a change in language could effect other things, 
			// and we don't expect to happen often so a little overkill isn't too bad.
			// The deep problem is that there is no way to get at the "edit side" adpapters
			// specifically here in model class.
			// we have to do the model changed sequence to get the 
			// screen to update.
			// do not signal again, if signaled once (the reinit state data will be wrong.
			// (this needs to be improved in future)
			if (!model.isReinitializationNeeded()) {
				modelReinitNeeded(cachedLanguage, newLanguage);
			}
		}
		setLanguage(newLanguage);
	}

	/**
	 * This is public access method, used especially
	 * from loader, for JSP Fragment support. 
	 */
	public void setLanguage(String newLanguage) {
		this.cachedLanguage = newLanguage;
		IDocumentPartitioner partitioner = ((IDocumentExtension3) model.getStructuredDocument()).getDocumentPartitioner(IStructuredPartitioning.DEFAULT_STRUCTURED_PARTITIONING);
		if (partitioner instanceof StructuredTextPartitionerForJSP) {
			((StructuredTextPartitionerForJSP) partitioner).setLanguage(newLanguage);
		}
	}

	/**
	 * Method languageStateChange.
	 * @param cachedLanguage
	 * @param newLanguage
	 * @return boolean
	 */
	private boolean languageStateChanged(String cachedLanguage, String newLanguage) {
		boolean result = false; // languages are equal, then no change in state
		if (!cachedLanguage.equalsIgnoreCase(newLanguage)) {
			boolean oldLanguageKnown = languageKnown(cachedLanguage);
			boolean newLanguageKnown = languageKnown(newLanguage);
			result = newLanguageKnown || (!newLanguageKnown && oldLanguageKnown);
		}
		return result;
	}

	/**
	 * Method languageKnown.
	 * @param cachedLanguage
	 * @return boolean
	 */
	private boolean languageKnown(String language) {
		return (StringUtils.contains(JAVA_LANGUAGE_KEYS, language, false) || StringUtils.contains(JAVASCRIPT_LANGUAGE_KEYS, language, false));
	}

	private IFile getFile(IStructuredModel model) {
		String location = model.getBaseLocation();
		IPath path = new Path(location);
		if (!path.toFile().exists() && path.segmentCount() > 1) {
			return ResourcesPlugin.getWorkspace().getRoot().getFile(path);
		}
		return null;
	}

	private EmbeddedTypeHandler getHandlerFor(String contentType) {
		EmbeddedTypeRegistry reg = getEmbeddedContentTypeRegistry();
		EmbeddedTypeHandler handler = null;
		if (reg != null)
			handler = reg.getTypeFor(contentType);
		return handler;
	}

	/**
	 * Gets the embeddedContentTypeRegistry.
	 * @return Returns a EmbeddedContentTypeRegistry
	 */
	private EmbeddedTypeRegistry getEmbeddedContentTypeRegistry() {
		return EmbeddedTypeRegistryImpl.getInstance();
	}

	/**
	 * For JSP files, text/html is the default 
	 * content type. This may want this different 
	 * for types like jsv (jsp for voice xml)
	 * For now, hard code to new instance.
	 * In future, should get instance from registry.
	 * 
	 * Specification cites HTML as the default contentType.
	 */
	protected EmbeddedTypeHandler getDefaultEmbeddedType() {
		return getHandlerFor(getDefaultContentType());
	}

	public void contentSettingsChanged(IResource resource) {
		// Note: we currently get notified multiple times, 
		// I assume since there's mulitple fields in the properties.
		// For now, I'll assume that once we get notified, all the 
		// fields are accurate, so if we're reinitializing, don't 
		// check any further. To NOT do this causes concurrent modification
		// exceptions. To do it, may cause us to miss when user changes
		// two fields at once. Will need to test. 
		if (reinitializing)
			return;
		if (resource == null)
			return;
		IFile file = getFile(model);
		if (file == null)
			return;
		//        String filename = null;
		//        if (resource.FILE == resource.getType()) {
		//        	filename = resource.getLocation().toString();
		//        }
		IProject project = file.getProject();
		if (project == null)
			return;
		if (!project.equals(resource.getProject()))
			return;
		// Note: these change notifications appear to be coming 
		// in based on any change in project. I'm not sure how
		// to tell if they are for my particular file, or 
		// if there's some other error I'm making in listeners.
		// the setters below should be smart enough 
		// to know if a meaningful change occurred, or 
		// not. Note: we seem to get called a lot (for resources other than our own?)
		// with lots of 'null' values. The logic below may prevent the correct unsetting
		// of a property (such as changing from a language setting back to 'none'). 
		// We may need a 'none' id, or something, to help detect that case, since we can't 
		// always assume the 'null' is accurate.
	}

	public INodeNotifier getTarget() {
		return notifierAtCreation;
	}

	public void release() {
		if (embeddedTypeHandler != null) {
			if (embeddedFactoryRegistry != null) {
				Iterator iterator = embeddedFactoryRegistry.iterator();
				INodeAdapterFactory factory = null;
				while (iterator.hasNext()) {
					factory = (INodeAdapterFactory) iterator.next();
					factory.release();
				}
			}
			// pa_TODO: possibly need to release here...
			// or "uninitializeFactoryRegistry"
			// initializeFactoryRegistry was called from JSPModelLoader
			embeddedTypeHandler = null;
		}
	}
}