/*******************************************************************************
 * Copyright (c) 2006 Sybase, Inc. 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:
 *     Sybase, Inc. - initial API and implementation
 *******************************************************************************/
package org.eclipse.jst.pagedesigner.editors.palette.impl;

import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;

import org.eclipse.core.resources.IProject;
import org.eclipse.gef.palette.PaletteDrawer;
import org.eclipse.gef.palette.PaletteEntry;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jst.jsf.common.metadata.Entity;
import org.eclipse.jst.jsf.common.metadata.Model;
import org.eclipse.jst.jsf.common.metadata.Trait;
import org.eclipse.jst.jsf.common.metadata.internal.IImageDescriptorProvider;
import org.eclipse.jst.jsf.common.metadata.internal.IMetaDataSourceModelProvider;
import org.eclipse.jst.jsf.common.metadata.internal.TraitValueHelper;
import org.eclipse.jst.jsf.common.metadata.query.ITaglibDomainMetaDataModelContext;
import org.eclipse.jst.jsf.common.metadata.query.TaglibDomainMetaDataQueryHelper;
import org.eclipse.jst.jsf.common.ui.JSFUICommonPlugin;
import org.eclipse.jst.jsf.common.ui.internal.utils.JSFSharedImages;
import org.eclipse.jst.jsf.tagdisplay.internal.paletteinfos.PaletteInfo;
import org.eclipse.jst.jsf.tagdisplay.internal.paletteinfos.PaletteInfos;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDDocument;
import org.eclipse.jst.jsp.core.internal.contentmodel.tld.provisional.TLDElementDeclaration;
import org.eclipse.jst.pagedesigner.IHTMLConstants;
import org.eclipse.jst.pagedesigner.PDPlugin;
import org.eclipse.jst.pagedesigner.editors.palette.IPaletteItemManager;
import org.eclipse.jst.pagedesigner.editors.palette.TagToolPaletteEntry;
import org.eclipse.wst.html.core.internal.contentmodel.HTMLCMDocument;
import org.eclipse.wst.html.core.internal.contentmodel.JSPCMDocument;
import org.eclipse.wst.xml.core.internal.contentmodel.CMDocument;
import org.eclipse.wst.xml.core.internal.contentmodel.CMElementDeclaration;
import org.eclipse.wst.xml.core.internal.contentmodel.CMNamedNodeMap;
import org.eclipse.wst.xml.core.internal.provisional.contentmodel.CMDocType;

/**
 * Helper class.
 * 
 * @author mengbo
 */
public class PaletteHelper {
	
    // pattern to strip all <x> and </x> HTML tags
    final private static Pattern removeHTMLTags = Pattern.compile("<[/?\\w\\s=\"\\.\\#]+>");
    
    // pattern to find all runs of spaces longer than one
    final private static Pattern trimInteriorWhitespace = Pattern.compile("[ ]+");
    
    // pattern to find all new lines for removal
    final private static Pattern removeNewLines = Pattern.compile("[\n]");
    
	private final static ImageDescriptor DEFAULT_SMALL_ICON = JSFUICommonPlugin
		.getDefault().getImageDescriptor(
			JSFSharedImages.DEFAULT_PALETTE_TAG_IMG);

	private final static ImageDescriptor DEFAULT_LARGE_ICON = PDPlugin
		.getDefault().getImageDescriptor(
				"palette/GENERIC/large/PD_Palette_Default.gif");



// how many characters to truncate a palette item's description to.
// TODO: add preference?
// the soft length is the ideal length we try to truncate to. We first
// try to find a period (end of sentence; TODO: should have a character class)
// inside the first SOFT_LENGTH chars at which to truncate a description string.
// if we can't find one then we search for the first one between SOFT_LENGTH
// and min(HARD_LENGTH, str.length()).  If found, we truncate there.  If not,
// we truncate to HARD_LENGTH-" ...".length() and append the ellipsis.
// In all cases the truncated description string returned should <= HARD_LENGTH.
//	private final static int  DESCRIPTION_TRUNCATE_SOFT_LENGTH = 150;
	private final static int  DESCRIPTION_TRUNCATE_HARD_LENGTH = 250;
	
	
	/**
	 * Creates a TaglibPaletteDrawer with TagTool palette entries for each tag from the CMDocument
	 * @param manager
	 * @param project
	 * @param doc
	 * @return TaglibPaletteDrawer
	 */
	public static TaglibPaletteDrawer configPaletteItemsByTLD(IPaletteItemManager manager, IProject project,
			CMDocument doc) {
		//bit of a hack... could be greatly improved		
		String tldURI = null;
		if (doc instanceof TLDDocument){
			tldURI = ((TLDDocument)doc).getUri();
		}
		else if (doc instanceof HTMLCMDocument){
			tldURI = CMDocType.HTML_DOC_TYPE;
		}
		else if (doc instanceof JSPCMDocument){
			tldURI = CMDocType.JSP11_DOC_TYPE;
		}
		
		if (tldURI == null) 
			return null;
			
		TaglibPaletteDrawer category = findCategory(manager, tldURI);
		if (category != null) 
			return category;
		
		ITaglibDomainMetaDataModelContext modelContext = TaglibDomainMetaDataQueryHelper.createMetaDataModelContext(project, tldURI);
		Model model = TaglibDomainMetaDataQueryHelper.getModel(modelContext);
		category = createTaglibPaletteDrawer(manager, doc, model);
		
		if (category != null){		
			loadTags(category, doc, model);		
			sortTags(category.getChildren());
		}
		return category;
	}

	private static void sortTags(List tags) {
		//note that once we store ordering customizations, we will need to do something different
		//it will also be complicated if we decide to do 181958 and 181866
		Collections.sort(tags, new Comparator(){

			public int compare(Object o1, Object o2) {
				String label1 = ((PaletteEntry)o1).getLabel();
				String label2 = ((PaletteEntry)o2).getLabel();
				
				if (label1 == null)
				{
				    // if both null, then equal
				    if (label2 == null)
				    {
				        return 0;
				    }
				    // otherwise, sort label 2 before
			        return 1;
				}
				
				
				if (label2 == null)
				{
				    // if both null then equal
				    if (label1 == null)
				    {
				        return 0;
				    }
				    // if label1 not null, then sort it first
				    return -1;
				}
				return label1.compareTo(label2);
			}
			
		});
		
	}

	private static void loadTags(TaglibPaletteDrawer category,
			CMDocument doc,Model model) {
		
		if (model != null) {//load from metadata - should always drop in here
			Trait trait = TaglibDomainMetaDataQueryHelper.getTrait(model, "paletteInfos");
			if (trait != null){
				PaletteInfos tags = (PaletteInfos)trait.getValue();
				for (Iterator it=tags.getInfos().iterator();it.hasNext();){
					PaletteInfo tag = (PaletteInfo)it.next();
					createTagEntry(category, tag);
				}
			} else {
				for (Iterator it=model.getChildEntities().iterator();it.hasNext();){
					Entity tagAsEntity = (Entity)it.next();
					createTagEntry(category, tagAsEntity);
				}
			}
		}
		else {//fail safe loading from cmDoc... should no longer go in here 
			loadFromCMDocument(category, doc);
		}
		
	}

	private static TaglibPaletteDrawer createTaglibPaletteDrawer(IPaletteItemManager manager,
			CMDocument doc, Model model) {
		
		TaglibPaletteDrawer	 category = null;
		if (model != null){
			//do we create it?
			boolean isHidden = getBooleanTagTraitValue(model, "hidden", false);			
			if (isHidden){
				return null;
			}
						
			String label = getStringTagTraitValue(model, "display-label", model.getId());
			label = label.equals("") ? model.getId() : label;
			category = manager.createTaglibPaletteDrawer(model.getId(), label);
			
			String desc = getStringTagTraitValue(model, "description", model.getId());
			category.setDescription(formatDescription(desc));
			
			ImageDescriptor largeIconImage = getImageDescriptorFromTagTraitValueAsString(model, "small-icon", null);
			if (largeIconImage != null)
				category.setLargeIcon(largeIconImage);			
			
			String prefix = getStringTagTraitValue(model, "default-prefix", null);
			category.setDefaultPrefix(prefix);
			
			boolean isVisible = !(getBooleanTagTraitValue(model, "expert", false));
			category.setVisible(isVisible);
			
			category.setInitialState(PaletteDrawer.INITIAL_STATE_CLOSED);
		
		}
		return category;
	}

	private static TaglibPaletteDrawer findCategory(IPaletteItemManager manager,
			String tldURI) {
		TaglibPaletteDrawer lib = null;
		for (Iterator it = manager.getAllCategories().iterator();it.hasNext();){
			lib = (TaglibPaletteDrawer)it.next();
			if (tldURI.equals(lib.getURI()))
				return lib;					
		}
		return null;
	}

	/* (non-JavaDoc)
	 * This method will read information from the CMDocument to create the tag entries. It will
	 * check the existing items in the registry. If the corresponding tag is not
	 * in palette manager, then it will create one, and mark the newly created
	 * item as "expert". Otherwise, it will check whether the tld contains more
	 * information than the palette manager, and adding those information to it
	 * (such as description, icons for tags)
	 * 
	 * @param category 
	 * @param cmdoc
	 */
	private static void loadFromCMDocument(TaglibPaletteDrawer category,
			CMDocument cmdoc) {
		
		CMNamedNodeMap nodeMap = cmdoc.getElements();
		for (int i = 0, size = nodeMap.getLength(); i < size; i++) {
			CMElementDeclaration eledecl = (CMElementDeclaration) nodeMap
					.item(i);
			String tagName = eledecl.getElementName();
			TagToolPaletteEntry item;
			if (tagName.equalsIgnoreCase(IHTMLConstants.TAG_INPUT)) {//TODO:  fix this nonsense!
				StringBuffer name = new StringBuffer(category.getURI());
				name.append(":").append(tagName).append(":").append(tagName);
				item = category.getTagPaletteEntryById(name.toString());
			} else {
				item = category.getTagPaletteEntryByTagName(tagName);
			}
			if (item == null) {
				createTagEntry(category, eledecl);

			}
		}
	}
	
	private static void createTagEntry(TaglibPaletteDrawer category,
			PaletteInfo info) {
		
		Boolean hidden = info.getHidden();
		if ((hidden != null) && (hidden.booleanValue()))//do not create a palette entry
			return; 
		
		IMetaDataSourceModelProvider sourceProvider = ((Trait)info.eContainer().eContainer()).getSourceModelProvider();
		String tagName = info.getTag();
		String id = info.getId();		
		String label = info.getDisplayLabel();
		String desc = formatDescription(info.getDescription());		
		ImageDescriptor smallIcon = getImageDescriptorFromString(sourceProvider, info.getSmallIcon(), DEFAULT_SMALL_ICON);
		ImageDescriptor largeIcon = getImageDescriptorFromString(sourceProvider, info.getLargeIcon(), DEFAULT_LARGE_ICON);
		Boolean expert = info.getExpert();
				
		internalCreateTagEntry(category, id, tagName, label, desc, smallIcon, largeIcon, (expert !=null && expert.booleanValue()));		
		
	}

	private static void createTagEntry(TaglibPaletteDrawer category,
			Entity entity) {
		
		boolean hidden = getBooleanTagTraitValue(entity, "hidden", false);
		if (hidden)//do not create a palette entry
			return; 
		
		String tagName = entity.getId();
		String label = getStringTagTraitValue(entity, "display-label", tagName);
		String desc = formatDescription(getStringTagTraitValue(entity, "description", tagName));		
		ImageDescriptor smallIcon = getImageDescriptorFromTagTraitValueAsString(entity, "small-icon", DEFAULT_SMALL_ICON);
		ImageDescriptor largeIcon = getImageDescriptorFromTagTraitValueAsString(entity, "large-icon", DEFAULT_LARGE_ICON);
		boolean expert = getBooleanTagTraitValue(entity, "expert", false);
				
		internalCreateTagEntry(category, tagName, tagName, label, desc, smallIcon, largeIcon, expert);
		
	}

	private static TagToolPaletteEntry internalCreateTagEntry(TaglibPaletteDrawer category, String id, String tagName, String label, String desc, ImageDescriptor smallIcon, ImageDescriptor largeIcon, boolean expert){
		TagToolPaletteEntry item = new TagToolPaletteEntry(tagName, label, desc, smallIcon, largeIcon);
		item.setId(id);
		
		item.setVisible(!expert);
		category.getChildren().add(item);
		item.setParent(category);
		
		return item;
	}

	private static boolean getBooleanTagTraitValue(Entity entity,
			String key, boolean defaultValue) {
		Trait trait = TaglibDomainMetaDataQueryHelper.getTrait(entity, key);
		if (trait != null){
			return TraitValueHelper.getValueAsBoolean(trait);
		}
		return defaultValue;	
	}

	private static String getStringTagTraitValue(Entity entity, String key, String defaultValue){
		Trait trait = TaglibDomainMetaDataQueryHelper.getTrait(entity, key);
		if (trait != null){
			String val = TraitValueHelper.getValueAsString(trait);
			if (val != null)
				return val;
		}
		return defaultValue;		
	}

	private static ImageDescriptor getImageDescriptorFromTagTraitValueAsString(Entity entity, String key, ImageDescriptor defaultValue){
		Trait t = TaglibDomainMetaDataQueryHelper.getTrait(entity, key);
		if (t != null){
			String imgDesc = TraitValueHelper.getValueAsString(t);
			return getImageDescriptorFromString(t.getSourceModelProvider(), imgDesc, defaultValue);
		}
		return defaultValue;
	}
	
	private static ImageDescriptor getImageDescriptorFromString(IMetaDataSourceModelProvider sourceModelProvider,  String imgDesc, ImageDescriptor defaultValue){
		ImageDescriptor image = defaultValue;
		IImageDescriptorProvider imageProvider = (IImageDescriptorProvider)sourceModelProvider.getAdapter(IImageDescriptorProvider.class);			
		if (imageProvider != null){
			image = imageProvider.getImageDescriptor(imgDesc);
		}
		return image;
	}
	
	private static void createTagEntry(TaglibPaletteDrawer category,
			CMElementDeclaration eledecl) {
		
		String tagName = eledecl.getElementName();
		String label = null;
		String desc = null;

		if (eledecl instanceof TLDElementDeclaration){
			TLDElementDeclaration tag = (TLDElementDeclaration)eledecl;			
			label = tag.getDisplayName();			
			desc = tag.getDescription();						
		}
		
		if (label == null || label.equals(""))
			label = tagName;
		
		if (desc == null )
			desc = "";
		else
			desc = formatDescription(desc);
		
		TagToolPaletteEntry item = internalCreateTagEntry(category, tagName, tagName, label, desc, getDefaultSmallIcon(), getDefaultLargeIcon(), false);
		item.setToolProperty("CMElementDeclaration", eledecl);
		
	}
	
	/**
	 * @return DEFAULT_LARGE_ICON
	 */
	private static ImageDescriptor getDefaultLargeIcon() {
		return DEFAULT_LARGE_ICON;
	}

	/**
	 * @return DEFAULT_SMALL_ICON
	 */
	private static ImageDescriptor getDefaultSmallIcon() {
		return DEFAULT_SMALL_ICON;
	}
	
	private static String formatDescription(final String desc) {
		//TODO: modify and use a formatter in the future?
		String aDesc = filterConvertString(desc);
		if (aDesc != null){
			if (aDesc.length() > DESCRIPTION_TRUNCATE_HARD_LENGTH) {
				StringBuffer result = new StringBuffer(aDesc.substring(0, DESCRIPTION_TRUNCATE_HARD_LENGTH));
				result.append("...");
				return result.toString();
			}
			return aDesc;

		}
		return "";
	}
	
	private static String filterConvertString(String text) {
		if (text == null) {
			return "";
		}
         
		String result = removeHTMLTags.matcher(text).replaceAll("");
		result = removeNewLines.matcher(result).replaceAll(" ");
        result = trimInteriorWhitespace.matcher(result).replaceAll(" ");        

		return result;
	}
}
