/**
 * Copyright (c) 2008 Oracle 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:
 *    Oracle Corporation - initial API and implementation
 */
package org.eclipse.jst.jsf.apache.trinidad.tagsupport.converter.operations;

import java.util.Iterator;
import java.util.List;

import org.eclipse.jst.jsf.apache.trinidad.tagsupport.Messages;
import org.eclipse.jst.jsf.apache.trinidad.tagsupport.model.SelectItem;
import org.eclipse.jst.jsf.apache.trinidad.tagsupport.model.SelectItemModel;
import org.eclipse.jst.pagedesigner.converter.ConvertPosition;
import org.w3c.dom.Element;

/**
 * ITransformOperation implementation specifically for "selectManyShuttle" and
 * "selectOrderShuttle" JSF Elements.
 * 
 * <br><b>Note:</b> requires ITransformOperation.setTagConverterContext(...) to
 * have been called to provide a valid ITagConverterContext instance prior to
 * a call to the transform(...) method.
 * 
 * @author Ian Trimble - Oracle
 */
public class SelectShuttleOperation extends AbstractTrinidadTransformOperation {

	private static final String STYLE_HEADER = "font-family:Arial,Helvetica,Geneva,sans-serif;font-size:9pt;color:#669966;font-weight:bold;padding:0px 0px 0px 18px;"; //$NON-NLS-1$
	private static final String STYLE_REQUIRED = "color:#669966;font-family:Courier,sans-serif;"; //$NON-NLS-1$
	private static final String STYLE_LISTCOLUMN = "font-family:Arial,Helvetica,Geneva,sans-serif;font-size:10pt;font-weight:normal;"; //$NON-NLS-1$
	private static final String STYLE_SELECT = "font-family:Arial,Helvetica,Geneva,sans-serif;font-size:10pt;font-weight:normal;color:#000000;"; //$NON-NLS-1$
	private static final String STYLE_DESCRIPTION = "font-family:Arial,Helvetica,Geneva,sans-serif;font-size:10pt;font-weight:normal;color:#000000;"; //$NON-NLS-1$
	private static final String STYLE_LINK = "font-family:Arial,Helvetica,Geneva,sans-serif;font-size:10pt;font-weight:normal;color:#003333;"; //$NON-NLS-1$
	private static final String DEFAULT_SIZE = "10"; //$NON-NLS-1$

	private static final String[] LINKS_MOVE = new String[]{
		Messages.SelectShuttleOperation_LinkMove,
		Messages.SelectShuttleOperation_LinkMoveAll,
		Messages.SelectShuttleOperation_LinkRemove,
		Messages.SelectShuttleOperation_LinkRemoveAll
	};
	private static final String[] LINKS_ORDER = new String[]{
		Messages.SelectShuttleOperation_LinkTop,
		Messages.SelectShuttleOperation_LinkUp,
		Messages.SelectShuttleOperation_LinkDown,
		Messages.SelectShuttleOperation_LinkBottom
	};

	private boolean showOrderLinks;

	/* (non-Javadoc)
	 * @see org.eclipse.jst.pagedesigner.dtmanager.converter.operations.AbstractTransformOperation#transform(org.w3c.dom.Element, org.w3c.dom.Element)
	 */
	@Override
	public Element transform(Element srcElement, Element curElement) {
		//get parameter
		if (getParameters().length < 1) {
			getLog().error("Warning.TransformOperationFactory.TooFewParameters", getTransformOperationID()); //$NON-NLS-1$
			return null;
		} else {
			showOrderLinks = Boolean.parseBoolean(getParameters()[0]);
		}
		
		//build outer table element
		Element outerTableElement = createElement("table"); //$NON-NLS-1$
		appendAttribute(outerTableElement, "cellpadding", "0"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(outerTableElement, "cellspacing", "0"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(outerTableElement, "border", "0"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(outerTableElement, "width", "10%"); //$NON-NLS-1$ //$NON-NLS-2$
		String inlineStyle = srcElement.getAttribute("inlineStyle"); //$NON-NLS-1$
		if (inlineStyle != null && inlineStyle.length() > 0) {
			appendAttribute(outerTableElement, "style", inlineStyle); //$NON-NLS-1$
		}
		String styleClass = srcElement.getAttribute("styleClass"); //$NON-NLS-1$
		if (styleClass != null && styleClass.length() > 0) {
			appendAttribute(outerTableElement, "class", styleClass); //$NON-NLS-1$
		}

		//build header row
		Element trHeaderElement = appendChildElement("tr", outerTableElement); //$NON-NLS-1$
		Element tdLeadingHeaderElement = appendChildElement("td", trHeaderElement); //$NON-NLS-1$
		String leadingHeader = srcElement.getAttribute("leadingHeader"); //$NON-NLS-1$
		if (leadingHeader != null && leadingHeader.length() > 0) {
			appendAttribute(tdLeadingHeaderElement, "style", STYLE_HEADER); //$NON-NLS-1$
			appendAttribute(tdLeadingHeaderElement, "valign", "bottom"); //$NON-NLS-1$ //$NON-NLS-2$
			appendChildText(leadingHeader, tdLeadingHeaderElement);
		}
		appendChildElement("td", trHeaderElement); //$NON-NLS-1$
		Element tdTrailingHeaderElement = appendChildElement("td", trHeaderElement); //$NON-NLS-1$
		String required = srcElement.getAttribute("required"); //$NON-NLS-1$
		String trailingHeader = srcElement.getAttribute("trailingHeader"); //$NON-NLS-1$
		if ((required != null && Boolean.parseBoolean(required)) || (trailingHeader != null && trailingHeader.length() > 0)) {
			appendAttribute(tdTrailingHeaderElement, "style", STYLE_HEADER); //$NON-NLS-1$
			appendAttribute(tdTrailingHeaderElement, "valign", "bottom"); //$NON-NLS-1$ //$NON-NLS-2$
			if (required != null && Boolean.parseBoolean(required)) {
				Element spanRequiredElement = appendChildElement("span", tdTrailingHeaderElement); //$NON-NLS-1$
				appendAttribute(spanRequiredElement, "style", STYLE_REQUIRED); //$NON-NLS-1$
				appendChildText("*", spanRequiredElement); //$NON-NLS-1$
			}
			if (trailingHeader != null && trailingHeader.length() > 0) {
				appendChildText(trailingHeader, tdTrailingHeaderElement);
			}
		}

		//build content row
		Element trContentElement = appendChildElement("tr", outerTableElement); //$NON-NLS-1$
		buildListColumn(srcElement, trContentElement, true);
		buildLinkColumn(trContentElement, LINKS_MOVE);
		buildListColumn(srcElement, trContentElement, false);

		return outerTableElement;
	}

	private void buildListColumn(Element srcElement, Element parentElement, boolean isLeadingColumn) {
		//build outer structure
		Element tdElement0 = appendChildElement("td", parentElement); //$NON-NLS-1$
		Element tableElement0 = appendChildElement("table", tdElement0); //$NON-NLS-1$
		appendAttribute(tableElement0, "style", "width:100%;"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tableElement0, "cellpadding", "0"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tableElement0, "cellspacing", "0"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tableElement0, "border", "0"); //$NON-NLS-1$ //$NON-NLS-2$
		Element tbodyElement0 = appendChildElement("tbody", tableElement0); //$NON-NLS-1$
		Element trElement0 = appendChildElement("tr", tbodyElement0); //$NON-NLS-1$
		Element tdElement1 = appendChildElement("td", trElement0); //$NON-NLS-1$
		Element divElement0 = appendChildElement("div", tdElement1); //$NON-NLS-1$
		appendAttribute(divElement0, "style", STYLE_LISTCOLUMN); //$NON-NLS-1$
		Element tableElement1 = appendChildElement("table", divElement0); //$NON-NLS-1$
		appendAttribute(tableElement1, "cellpadding", "0"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tableElement1, "border", "0"); //$NON-NLS-1$ //$NON-NLS-2$

		//build filter structure
		if (isLeadingColumn) {
			Element filterFacet = getChildFacetByName(srcElement, "filter"); //$NON-NLS-1$
			if (filterFacet != null) {
				Element trFilterElement = appendChildElement("tr", tableElement1); //$NON-NLS-1$
				Element tdFilterElement = appendChildElement("td", trFilterElement); //$NON-NLS-1$
				appendAttribute(tdFilterElement, "nowrap", ""); //$NON-NLS-1$ //$NON-NLS-2$
				appendAttribute(tdFilterElement, "valign", "middle"); //$NON-NLS-1$ //$NON-NLS-2$
				appendAttribute(tdFilterElement, "colspan", "3"); //$NON-NLS-1$ //$NON-NLS-2$
				tagConverterContext.addChild(filterFacet, new ConvertPosition(tdFilterElement, 0));
			}
		}

		//build select element structure
		Element trSelectElement = appendChildElement("tr", tableElement1); //$NON-NLS-1$
		Element tdSelectElement = appendChildElement("td", trSelectElement); //$NON-NLS-1$
		appendAttribute(tdSelectElement, "nowrap", ""); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tdSelectElement, "valign", "middle"); //$NON-NLS-1$ //$NON-NLS-2$
		Element spanSelectElement = appendChildElement("span", tdSelectElement); //$NON-NLS-1$
		Element selectElement = appendChildElement("select", spanSelectElement); //$NON-NLS-1$
		appendAttribute(selectElement, "multiple", ""); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(selectElement, "style", STYLE_SELECT); //$NON-NLS-1$
		appendAttribute(selectElement, "size", getSizeString(srcElement)); //$NON-NLS-1$

		if (isLeadingColumn) {
			List<SelectItem> selectItems = SelectItemModel.getModel(srcElement);
			Iterator<SelectItem> itSelectItems = selectItems.iterator();
			while (itSelectItems.hasNext()) {
				SelectItem selectItem = itSelectItems.next();
				Element optionElement = appendChildElement("option", selectElement); //$NON-NLS-1$
				appendChildText(selectItem.getLabel(), optionElement); //$NON-NLS-1$
			}
		}
		Element optionElement = appendChildElement("option", selectElement); //$NON-NLS-1$
		appendChildText("_______________", optionElement); //$NON-NLS-1$

		//build order links
		if (!isLeadingColumn && showOrderLinks) {
			buildLinkColumn(trSelectElement, LINKS_ORDER);
		}

		//build description structure
		boolean showDesc = false;
		String showDescAttrName;
		if (isLeadingColumn) {
			showDescAttrName = "leadingDescShown"; //$NON-NLS-1$
		} else {
			showDescAttrName = "trailingDescShown"; //$NON-NLS-1$
		}
		String showDescAttr = srcElement.getAttribute(showDescAttrName);
		if (showDescAttr != null && showDescAttr.length() > 0) {
			showDesc = Boolean.parseBoolean(showDescAttr);
		}
		if (showDesc) {
			Element trDescElement = appendChildElement("tr", tableElement1); //$NON-NLS-1$
			Element tdDescElement = appendChildElement("td", trDescElement); //$NON-NLS-1$
			appendAttribute(tdDescElement, "nowrap", ""); //$NON-NLS-1$ //$NON-NLS-2$
			appendAttribute(tdDescElement, "valign", "middle"); //$NON-NLS-1$ //$NON-NLS-2$
			appendAttribute(tdDescElement, "colspan", "3"); //$NON-NLS-1$ //$NON-NLS-2$
			Element spanDescElement = appendChildElement("span", tdDescElement); //$NON-NLS-1$
			appendAttribute(spanDescElement, "style", STYLE_DESCRIPTION); //$NON-NLS-1$
			appendChildText(Messages.SelectShuttleOperation_Description, spanDescElement);
			appendChildElement("div", tdDescElement); //$NON-NLS-1$
			Element textareaElement = appendChildElement("textarea", tdDescElement); //$NON-NLS-1$
			appendAttribute(textareaElement, "rows", "2"); //$NON-NLS-1$ //$NON-NLS-2$
			appendAttribute(textareaElement, "cols", "18"); //$NON-NLS-1$ //$NON-NLS-2$
			appendAttribute(textareaElement, "readonly", ""); //$NON-NLS-1$ //$NON-NLS-2$
		}

		//build footer structure
		String footerFacetName;
		if (isLeadingColumn) {
			footerFacetName = "leadingFooter"; //$NON-NLS-1$
		} else {
			footerFacetName = "trailingFooter"; //$NON-NLS-1$
		}
		Element footerFacet = getChildFacetByName(srcElement, footerFacetName); //$NON-NLS-1$
		if (footerFacet != null) {
			Element trFooterElement = appendChildElement("tr", tableElement1); //$NON-NLS-1$
			Element tdFooterElement = appendChildElement("td", trFooterElement); //$NON-NLS-1$
			appendAttribute(tdFooterElement, "nowrap", ""); //$NON-NLS-1$ //$NON-NLS-2$
			appendAttribute(tdFooterElement, "valign", "middle"); //$NON-NLS-1$ //$NON-NLS-2$
			appendAttribute(tdFooterElement, "colspan", "3"); //$NON-NLS-1$ //$NON-NLS-2$
			tagConverterContext.addChild(footerFacet, new ConvertPosition(tdFooterElement, 0));
		}
	}

	private void buildLinkColumn(Element parentElement, String[] linkText) {
		Element tdElement = appendChildElement("td", parentElement); //$NON-NLS-1$
		appendAttribute(tdElement, "align", "center"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tdElement, "valign", "middle"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tdElement, "nowrap", ""); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tdElement, "style", "padding:5px;"); //$NON-NLS-1$ //$NON-NLS-2$
		for (int i = 0; i < linkText.length; i++) {
			Element aElement = appendChildElement("a", tdElement); //$NON-NLS-1$
			appendAttribute(aElement, "href", "#"); //$NON-NLS-1$ //$NON-NLS-2$
			appendAttribute(aElement, "style", STYLE_LINK); //$NON-NLS-1$
			appendChildText(linkText[i], aElement);
			if (i < linkText.length - 1) {
				appendChildElement("br", tdElement); //$NON-NLS-1$
			}
		}
	}

	private String getSizeString(Element srcElement) {
		String size = DEFAULT_SIZE;
		String sizeAttr = srcElement.getAttribute("size"); //$NON-NLS-1$
		if (sizeAttr != null && sizeAttr.length() > 0) {
			try {
				int iSize = Integer.parseInt(sizeAttr);
				iSize = Math.max(iSize, 10);
				iSize = Math.min(iSize, 20);
				size = String.valueOf(iSize);
			} catch(NumberFormatException nfe) {
				//ignore - default of "10" will be returned
			}
		}
		return size;
	}

}
