/**
 * 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.ITrinidadConstants;
import org.eclipse.jst.jsf.common.dom.TagIdentifier;
import org.eclipse.jst.jsf.core.internal.tld.TagIdentifierFactory;
import org.eclipse.jst.pagedesigner.converter.ConvertPosition;
import org.w3c.dom.Element;

/**
 * ITransformOperation implementation specifically for the "panelFormLayout"
 * JSF Element.
 * 
 * <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 PanelFormLayoutOperation extends AbstractTrinidadTransformOperation {

	private static final String STYLECLASS_REQUIREDSPAN = "AFRequiredIconStyle"; //$NON-NLS-1$
	private static final String STYLECLASS_GROUPSEPARATOR = "af_panelFormLayout_separator"; //$NON-NLS-1$
	private static final String STYLECLASS_LABELCELL = "af_inputText_label af_panelFormLayout_label-cell"; //$NON-NLS-1$
	private static final String STYLECLASS_FIELDCELL = "af_panelFormLayout_content-cell"; //$NON-NLS-1$

	/* (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) {
		//calculate required values
		int columnCount = calculateColumnCount(srcElement);
		int rowCount = calculateRowCount(srcElement);
		String fieldWidth = calculateFieldWidth(srcElement);
		String labelWidth = calculateLabelWidth(srcElement);

		//initialize current column/row variables
		int currentColumn = 1;
		int currentRow = 1;
		
		//build outer table
		Element outerTableElement = createElement("table"); //$NON-NLS-1$
		String styleClass = srcElement.getAttribute("styleClass"); //$NON-NLS-1$
		if (styleClass != null && styleClass.length() > 0) {
			appendAttribute(outerTableElement, "class", styleClass); //$NON-NLS-1$
		}
		String inlineStyle = srcElement.getAttribute("inlineStyle"); //$NON-NLS-1$
		if (inlineStyle != null && inlineStyle.length() > 0) {
			appendAttribute(outerTableElement, "style", inlineStyle + ";width:100%;"); //$NON-NLS-1$ //$NON-NLS-2$
		} else {
			appendAttribute(outerTableElement, "style", "width:100%;"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		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$
		Element outerTBodyElement = appendChildElement("tbody", outerTableElement); //$NON-NLS-1$
		Element outerTopTRElement = appendChildElement("tr", outerTBodyElement); //$NON-NLS-1$

		//build start of column
		Element currentTBodyElement = buildColumnStart(outerTopTRElement, columnCount, currentColumn, labelWidth, fieldWidth);

		//build controls
		List<Element> childElements = getChildElementsSkipFacets(srcElement);
		Iterator<Element> itChildElements = childElements.iterator();
		while (itChildElements.hasNext()) {
			Element childElement = itChildElements.next();
			if (ITrinidadConstants.TAG_IDENTIFIER_GROUP.isSameTagType(
					TagIdentifierFactory.createDocumentTagWrapper(childElement))) {
				if (currentRow > 1) {
					buildGroupSeparatorRow(currentTBodyElement);
				}
				List<Element> groupChildElements = getChildElementsSkipFacets(childElement);
				Iterator<Element> itGroupChildElements = groupChildElements.iterator();
				while (itGroupChildElements.hasNext()) {
					Element groupChildElement = itGroupChildElements.next();
					buildControlRow(groupChildElement, currentTBodyElement);
				}
				currentRow += groupChildElements.size();
				if (currentRow <= rowCount) {
					buildGroupSeparatorRow(currentTBodyElement);
				}
				if (currentRow > rowCount && currentColumn < columnCount) {
					currentRow = 1;
					currentColumn++;
					currentTBodyElement = buildColumnStart(
							outerTopTRElement, columnCount, currentColumn, labelWidth, fieldWidth);
				}
			} else {
				buildControlRow(childElement, currentTBodyElement);
				currentRow++;
				if (currentRow > rowCount && currentColumn < columnCount) {
					currentRow = 1;
					currentColumn++;
					currentTBodyElement = buildColumnStart(
							outerTopTRElement, columnCount, currentColumn, labelWidth, fieldWidth);
				}
			}
		}

		//handle "footer" facet
		Element footerElement = getChildFacetByName(srcElement, "footer"); //$NON-NLS-1$
		if (footerElement != null) {
			List<Element> footerChildElements = getChildElementsSkipFacets(footerElement);
			if (footerChildElements.size() > 0) {
				Element outerBottomTRElement = appendChildElement("tr", outerTBodyElement); //$NON-NLS-1$
				currentTBodyElement = buildFooterStart(
						outerBottomTRElement, columnCount, labelWidth);
				rowCount = countChildElements(footerElement);
				currentRow = 1;
				Iterator<Element> itFooterChildElements = footerChildElements.iterator();
				while (itFooterChildElements.hasNext()) {
					Element footerChildElement = itFooterChildElements.next();
					if (ITrinidadConstants.TAG_IDENTIFIER_GROUP.isSameTagType(
							TagIdentifierFactory.createDocumentTagWrapper(footerChildElement))) {
						if (currentRow > 1) {
							buildGroupSeparatorRow(currentTBodyElement);
						}
						List<Element> groupFooterChildElements = getChildElementsSkipFacets(footerChildElement);
						Iterator<Element> itGroupFooterChildElements = groupFooterChildElements.iterator();
						while (itGroupFooterChildElements.hasNext()) {
							Element groupFooterChildElement = itGroupFooterChildElements.next();
							if (ITrinidadConstants.TAG_IDENTIFIER_GROUP.isSameTagType(
									TagIdentifierFactory.createDocumentTagWrapper(groupFooterChildElement))) {
								if (currentRow > 1) {
									buildGroupSeparatorRow(currentTBodyElement);
								}
								List<Element> subGroupFooterChildElements = getChildElementsSkipFacets(groupFooterChildElement);
								Iterator<Element> itSubGroupFooterChildElements = subGroupFooterChildElements.iterator();
								while (itSubGroupFooterChildElements.hasNext()) {
									Element subGroupFooterChildElement = itSubGroupFooterChildElements.next();
									buildControlRow(subGroupFooterChildElement, currentTBodyElement, true);
									currentRow++;
								}
								if (currentRow <= rowCount) {
									buildGroupSeparatorRow(currentTBodyElement);
								}
							} else {
								buildControlRow(groupFooterChildElement, currentTBodyElement, true);
								currentRow++;
							}
						}
						if (currentRow <= rowCount) {
							buildGroupSeparatorRow(currentTBodyElement);
						}
					} else {
						buildControlRow(footerChildElement, currentTBodyElement, true);
						currentRow++;
					}
				}
			}
		}

		return outerTableElement;
	}

	private int calculateRowCount(Element srcElement) {
		int rowCount = Integer.MAX_VALUE;
		int specifiedRows = Integer.MAX_VALUE;
		String rows = srcElement.getAttribute("rows"); //$NON-NLS-1$
		if (rows != null && rows.length() > 0) {
			try {
				//not spec'ed, but observed that setting rows < 5 is ignored
				specifiedRows = Math.max(5, Integer.parseInt(rows));
			} catch(NumberFormatException nfe) {
				//ignore - specifiedRows will default to Integer.MAX_VALUE
			}
		}
		int specifiedMaxColumns = Integer.MAX_VALUE;
		String maxColumns = srcElement.getAttribute("maxColumns"); //$NON-NLS-1$
		if (maxColumns != null && maxColumns.length() > 0) {
			try {
				specifiedMaxColumns = Integer.parseInt(maxColumns);
			} catch(NumberFormatException nfe) {
				//ignore - specifiedMaxColumns will default to Integer.MAX_VALUE
			}
		}
		int childElementCount = countChildElements(srcElement);
		int calculatedColumns = childElementCount / specifiedRows;
		if (childElementCount % specifiedRows > 0) {
			calculatedColumns++;
		}
		if (calculatedColumns > specifiedMaxColumns) {
			rowCount = childElementCount / specifiedMaxColumns;
		} else {
			rowCount = specifiedRows;
		}
		return rowCount;
	}

	private int calculateColumnCount(Element srcElement) {
		int columnCount = Integer.MAX_VALUE;
		int specifiedRows = Integer.MAX_VALUE;
		String rows = srcElement.getAttribute("rows"); //$NON-NLS-1$
		if (rows != null && rows.length() > 0) {
			try {
				//not spec'ed, but observed that setting rows < 5 is ignored
				specifiedRows = Math.max(5, Integer.parseInt(rows));
			} catch(NumberFormatException nfe) {
				//ignore - specifiedRows will default to Integer.MAX_VALUE
			}
		}
		int specifiedMaxColumns = Integer.MAX_VALUE;
		String maxColumns = srcElement.getAttribute("maxColumns"); //$NON-NLS-1$
		if (maxColumns != null && maxColumns.length() > 0) {
			try {
				specifiedMaxColumns = Integer.parseInt(maxColumns);
			} catch(NumberFormatException nfe) {
				//ignore - specifiedMaxColumns will default to Integer.MAX_VALUE
			}
		}
		int childElementCount = countChildElements(srcElement);
		int calculatedColumns = childElementCount / specifiedRows;
		if (childElementCount % specifiedRows > 0) {
			calculatedColumns++;
		}
		columnCount = Math.min(specifiedMaxColumns, calculatedColumns);
		return columnCount;
	}

	private int countChildElements(Element srcElement) {
		int count = 0;
		List<Element> childElements = getChildElementsSkipFacets(srcElement);
		Iterator<Element> itChildElements = childElements.iterator();
		while (itChildElements.hasNext()) {
			Element childElement = itChildElements.next();
			if (ITrinidadConstants.TAG_IDENTIFIER_GROUP.isSameTagType(
					TagIdentifierFactory.createDocumentTagWrapper(childElement))) {
				count += countChildElements(childElement);
			} else {
				count++;
			}
		}
		return count;
	}

	private String calculateFieldWidth(Element srcElement) {
		String width = null;
		String fieldWidth = srcElement.getAttribute("fieldWidth"); //$NON-NLS-1$
		if (fieldWidth != null && fieldWidth.length() > 0) {
			width = fieldWidth;
		} else {
			String labelWidth = srcElement.getAttribute("labelWidth"); //$NON-NLS-1$
			if (labelWidth != null && labelWidth.length() > 1) {
				if (labelWidth.endsWith("%")) { //$NON-NLS-1$
					try {
						int iLabelWidth = Integer.parseInt(labelWidth.substring(0, labelWidth.length() - 1));
						if (iLabelWidth <= 100) {
							width = String.valueOf(100 - iLabelWidth) + "%"; //$NON-NLS-1$
						}
					} catch(NumberFormatException nfe) {
						//ignore - cannot calculate and so will return null
					}
				}
			}
		}
		return width;
	}

	private String calculateLabelWidth(Element srcElement) {
		String width = null;
		String labelWidth = srcElement.getAttribute("labelWidth"); //$NON-NLS-1$
		if (labelWidth != null && labelWidth.length() > 0) {
			width = labelWidth;
		} else {
			String fieldWidth = srcElement.getAttribute("fieldWidth"); //$NON-NLS-1$
			if (fieldWidth != null && fieldWidth.length() > 1) {
				if (fieldWidth.endsWith("%")) { //$NON-NLS-1$
					try {
						int iFieldWidth = Integer.parseInt(fieldWidth.substring(0, fieldWidth.length() - 1));
						if (iFieldWidth <= 100) {
							width = String.valueOf(100 - iFieldWidth) + "%"; //$NON-NLS-1$
						}
					} catch(NumberFormatException nfe) {
						//ignore - cannot calculate and so will return null
					}
				}
			}
		}
		return width;
	}

	private Element buildColumnStart(
			Element parentElement, int columnCount, int currentColumn,
			String labelWidth, String fieldWidth) {
		Element tdElement = appendChildElement("td", parentElement); //$NON-NLS-1$
		appendAttribute(tdElement, "style", "vertical-align:top;"); //$NON-NLS-1$ //$NON-NLS-2$
		if (currentColumn < columnCount) {
			String width = String.valueOf(100 / columnCount) + "%"; //$NON-NLS-1$
			appendAttribute(tdElement, "width", width); //$NON-NLS-1$
		}
		Element tableElement = appendChildElement("table", tdElement); //$NON-NLS-1$
		appendAttribute(tableElement, "cellpadding", "0"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tableElement, "cellspacing", "0"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tableElement, "border", "0"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tableElement, "width", "100%"); //$NON-NLS-1$ //$NON-NLS-2$
		Element tBodyElement = appendChildElement("tbody", tableElement); //$NON-NLS-1$
		Element trElement = appendChildElement("tr", tBodyElement); //$NON-NLS-1$
		Element tdLabelElement = appendChildElement("td", trElement); //$NON-NLS-1$
		if (labelWidth != null && labelWidth.length() > 0) {
			appendAttribute(tdLabelElement, "style", "width:" + labelWidth); //$NON-NLS-1$ //$NON-NLS-2$
		}
		Element tdFieldElement = appendChildElement("td", trElement); //$NON-NLS-1$
		if (fieldWidth != null && fieldWidth.length() > 0) {
			appendAttribute(tdFieldElement, "style", "width:" + fieldWidth); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return tBodyElement;
	}

	private void buildControlRow(Element srcElement, Element parentElement, boolean alignLabelsTop) {
		Element trElement = appendChildElement("tr", parentElement); //$NON-NLS-1$
		Element tdLabelElement = appendChildElement("td", trElement); //$NON-NLS-1$
		appendAttribute(tdLabelElement, "class", STYLECLASS_LABELCELL); //$NON-NLS-1$
		if (alignLabelsTop) {
			appendAttribute(tdLabelElement, "valign", "top"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		appendAttribute(tdLabelElement, "nowrap", ""); //$NON-NLS-1$ //$NON-NLS-2$
		buildLabel(srcElement, tdLabelElement);
		Element tdFieldElement = appendChildElement("td", trElement); //$NON-NLS-1$
		appendAttribute(tdFieldElement, "class", STYLECLASS_FIELDCELL); //$NON-NLS-1$
		appendAttribute(tdFieldElement, "valign", "top"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tdFieldElement, "nowrap", ""); //$NON-NLS-1$ //$NON-NLS-2$
		tagConverterContext.addChild(srcElement, new ConvertPosition(tdFieldElement, 0));
	}

	private void buildControlRow(Element srcElement, Element parentElement) {
		buildControlRow(srcElement, parentElement, false);
	}

	private void buildLabel(Element srcElement, Element parentElement) {
		TagIdentifier tagID = TagIdentifierFactory.createDocumentTagWrapper(srcElement);
		if (
				tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_INPUTCOLOR) ||
				tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_INPUTDATE) ||
				tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_INPUTFILE) ||
				tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_INPUTLISTOFVALUES) ||
				tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_INPUTNUMBERSPINBOX) ||
				tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_INPUTTEXT) ||
				tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_SELECTBOOLEANCHECKBOX) ||
				tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_SELECTBOOLEANRADIO) ||
				tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_SELECTMANYCHECKBOX) ||
				tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_SELECTMANYLISTBOX) ||
				tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_SELECTONECHOICE) ||
				tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_SELECTONELISTBOX) ||
				tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_SELECTONERADIO) ||
				tagID.isSameTagType(ITrinidadConstants.TAG_IDENTIFIER_PANELLABELANDMESSAGE)) {
			String required = srcElement.getAttribute("required"); //$NON-NLS-1$
			String showRequired = srcElement.getAttribute("showRequired"); //$NON-NLS-1$
			if (Boolean.parseBoolean(required) || Boolean.parseBoolean(showRequired)) {
				Element spanElement = appendChildElement("span", parentElement); //$NON-NLS-1$
				appendAttribute(spanElement, "title", "Required"); //$NON-NLS-1$ //$NON-NLS-2$
				appendAttribute(spanElement, "class", STYLECLASS_REQUIREDSPAN); //$NON-NLS-1$
				appendChildText("* ", spanElement); //$NON-NLS-1$
			}
			String label = srcElement.getAttribute("labelAndAccessKey"); //$NON-NLS-1$
			if (label == null || label.length() < 1) {
				label = srcElement.getAttribute("label"); //$NON-NLS-1$
			}
			if (label != null && label.length() > 0) {
				Element labelElement = appendChildElement("label", parentElement); //$NON-NLS-1$
				appendChildText(label, labelElement);
			}
		}
	}

	private void buildGroupSeparatorRow(Element parentElement) {
		Element trElement = appendChildElement("tr", parentElement); //$NON-NLS-1$
		Element tdElement = appendChildElement("td", trElement); //$NON-NLS-1$
		appendAttribute(tdElement, "colspan", "2"); //$NON-NLS-1$ //$NON-NLS-2$
		Element divElement = appendChildElement("div", tdElement); //$NON-NLS-1$
		appendAttribute(divElement, "class", STYLECLASS_GROUPSEPARATOR); //$NON-NLS-1$
	}

	private Element buildFooterStart(
			Element parentElement, int columnCount, String labelWidth) {
		Element tdElement = appendChildElement("td", parentElement); //$NON-NLS-1$
		appendAttribute(tdElement, "style", "vertical-align:top;"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tdElement, "colspan", String.valueOf(columnCount)); //$NON-NLS-1$
		Element tableElement = appendChildElement("table", tdElement); //$NON-NLS-1$
		appendAttribute(tableElement, "cellpadding", "0"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tableElement, "cellspacing", "0"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tableElement, "border", "0"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tableElement, "width", "100%"); //$NON-NLS-1$ //$NON-NLS-2$
		Element tBodyElement = appendChildElement("tbody", tableElement); //$NON-NLS-1$
		Element trElement = appendChildElement("tr", tBodyElement); //$NON-NLS-1$
		String footerLabelWidth = null;
		String footerFieldWidth = null;
		if (labelWidth != null && labelWidth.length() > 0) {
			if (labelWidth.endsWith("%")) { //$NON-NLS-1$
				try {
					int iLabelWidth = Integer.parseInt(labelWidth.substring(0, labelWidth.length() - 1));
					iLabelWidth = iLabelWidth / columnCount;
					footerLabelWidth = String.valueOf(iLabelWidth) + "%"; //$NON-NLS-1$
					footerFieldWidth = String.valueOf(100 - iLabelWidth) + "%"; //$NON-NLS-1$
				} catch(NumberFormatException nfe) {
					//ignore - cannot calculate, widths remain null
				}
			} else {
				footerLabelWidth = labelWidth;
			}
		}
		Element tdLabelElement = appendChildElement("td", trElement); //$NON-NLS-1$
		if (footerLabelWidth != null && footerLabelWidth.length() > 0) {
			//appendAttribute(tdLabelElement, "style", "width:" + footerLabelWidth); //$NON-NLS-1$ //$NON-NLS-2$
			appendAttribute(tdLabelElement, "width", footerLabelWidth); //$NON-NLS-1$
		}
		Element tdFieldElement = appendChildElement("td", trElement); //$NON-NLS-1$
		if (footerFieldWidth != null && footerFieldWidth.length() > 0) {
			//appendAttribute(tdFieldElement, "style", "width:" + footerFieldWidth); //$NON-NLS-1$ //$NON-NLS-2$
			appendAttribute(tdFieldElement, "width", footerFieldWidth); //$NON-NLS-1$
		}
		return tBodyElement;
	}

}
