/**
 * 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.apache.trinidad.tagsupport.Messages;
import org.eclipse.jst.jsf.apache.trinidad.tagsupport.TrinidadUtils;
import org.eclipse.jst.pagedesigner.converter.ConvertPosition;
import org.eclipse.jst.pagedesigner.dtmanager.converter.ITransformOperation;
import org.eclipse.jst.pagedesigner.dtmanager.converter.operations.TransformOperationFactory;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * ITransformOperation implementation specifically for the "panelTabbed" 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 PanelTabbedOperation extends AbstractTrinidadTransformOperation {

	private static final int SEP_POS_BETWEEN = -1;
	private static final int SEP_POS_START = 0;
	private static final int SEP_POS_END = 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) {
		//create outer span element and set style and class attributes
		Element spanElement = createElement("span"); //$NON-NLS-1$
		ITransformOperation operation =
			TransformOperationFactory.getInstance().getTransformOperation(
					TransformOperationFactory.OP_CopyAttributeWithRenameOperation,
					new String[]{"styleClass", "class"}); //$NON-NLS-1$  //$NON-NLS-2$
		operation.transform(srcElement, spanElement);
		operation =
			TransformOperationFactory.getInstance().getTransformOperation(
					TransformOperationFactory.OP_CopyAttributeWithRenameOperation,
					new String[]{"inlineStyle", "style"}); //$NON-NLS-1$  //$NON-NLS-2$
		operation.transform(srcElement, spanElement);

		//get child showDetailItem elements
		@SuppressWarnings("unchecked")
		List<Node> showDetailItems = getChildElements(
				srcElement, "showDetailItem"); //$NON-NLS-1$
		if (showDetailItems.size() > 0) {

			//determine tabs position ("both", "above", or "below" - default "both")
			String tabsPosition = srcElement.getAttribute("position"); //$NON-NLS-1$
			if (tabsPosition == null ||
					!(tabsPosition.equalsIgnoreCase("above") || //$NON-NLS-1$
					tabsPosition.equalsIgnoreCase("below"))) { //$NON-NLS-1$
				tabsPosition = "both"; //$NON-NLS-1$
			}

			//need to track where showDetailItem is in relation to "tabs"
			int showDetailItemConvertPosition = 0;

			//write tabs "above" if specified
			if ("above".equalsIgnoreCase(tabsPosition) || //$NON-NLS-1$
					"both".equalsIgnoreCase(tabsPosition)) { //$NON-NLS-1$
				appendTabs(srcElement, showDetailItems, spanElement, true);
				showDetailItemConvertPosition++;
			}

			//copy current child showDetailItem
			int currentEditorItem =
				getCurrentShowDetailItem(srcElement, showDetailItems);
			int curItem = 0;
			Iterator<Node> itItems = showDetailItems.iterator();
			while (itItems.hasNext()) {
				Node nodeItem = itItems.next();
				if (currentEditorItem == curItem) {
					if (nodeItem instanceof Element) {
						Element elemItem = (Element)nodeItem;
						tagConverterContext.addChild(
								elemItem,
								new ConvertPosition(
										spanElement,
										showDetailItemConvertPosition));
						break;
					}
				}
				curItem++;
			}

			//write tabs "below" if specified
			if ("below".equalsIgnoreCase(tabsPosition) || //$NON-NLS-1$
					"both".equalsIgnoreCase(tabsPosition)) { //$NON-NLS-1$
				appendTabs(srcElement, showDetailItems, spanElement, false);
			}
		} else {
			appendAttribute(
					spanElement,
					"style", //$NON-NLS-1$
					ITrinidadConstants.STYLE_EMPTYELEMENT);
			appendChildText(
					Messages.PanelTabbedOperation_EmptyPanelTabbedTag,
					spanElement);
		}
			
		return spanElement;
	}

	private void appendTabs(Element srcElement, List<Node> showDetailItems, Element spanElement, boolean above) {
		Element tableElement = appendChildElement("table", spanElement); //$NON-NLS-1$
		String tableStyle;
		if (above) {
			tableStyle = "background-color:#e9e8e8;border-color:#99cc99;text-align:center;border-style:solid;padding:2px 0px;margin:4px 0px;border-width:1px 0px 0px;"; //$NON-NLS-1$
		} else {
			tableStyle = "background-color:#e9e8e8;border-color:#99cc99;text-align:center;border-style:solid;padding:2px 0px;margin:4px 0px;border-width:0px 0px 1px;"; //$NON-NLS-1$
		}
		appendAttribute(tableElement, "style", tableStyle); //$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$
		appendAttribute(tableElement, "summary", ""); //$NON-NLS-1$ //$NON-NLS-2$
		Element trElement = appendChildElement("tr", tableElement); //$NON-NLS-1$

		//append first separator
		appendSeparatorTD(trElement, SEP_POS_START);

		int currentItem = getCurrentShowDetailItem(srcElement, showDetailItems);
		int disclosedItem = calculateDisclosedShowDetailItem(showDetailItems);
		int curItem = 0;

		//iterate over showDetailItem elements
		Iterator<Node> itItems = showDetailItems.iterator();
		while (itItems.hasNext()) {
			Node nodeItem = itItems.next();
			if (nodeItem instanceof Element) {
				Element elemItem = (Element)nodeItem;
				appendShowDetailItemTD(
						trElement,
						elemItem,
						currentItem == curItem,
						disclosedItem == curItem);
				if (curItem < showDetailItems.size() - 1) {
					appendSeparatorTD(trElement);
				}
				curItem++;
			}
		}

		//append last separator
		appendSeparatorTD(trElement, SEP_POS_END);
	}

	private void appendSeparatorTD(Element trElement, int sepPosition) {
		Element tdElement = appendChildElement("td", trElement); //$NON-NLS-1$
		if (sepPosition == SEP_POS_START) {
			appendAttribute(tdElement, "style", "width:0%;"); //$NON-NLS-1$ //$NON-NLS-2$
		} else if (sepPosition == SEP_POS_END) {
			appendAttribute(tdElement, "style", "width:100%;"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		Element bElement = appendChildElement("b", tdElement); //$NON-NLS-1$
		appendAttribute(bElement, "style", "margin-left:0px;"); //$NON-NLS-1$ //$NON-NLS-2$
	}

	private void appendSeparatorTD(Element trElement) {
		appendSeparatorTD(trElement, SEP_POS_BETWEEN);
	}

	private void appendShowDetailItemTD(Element trElement, Element showDetailItem, boolean isCurrent, boolean isDisclosed) {
		boolean isDisabled = false;
		String attrShowDetailItemDisabled = showDetailItem.getAttribute("disabled"); //$NON-NLS-1$
		if (Boolean.TRUE.toString().equalsIgnoreCase(attrShowDetailItemDisabled)) {
			isDisabled = true;
		}
		Element tdElement = appendChildElement("td", trElement); //$NON-NLS-1$
		appendAttribute(tdElement, "height", "1"); //$NON-NLS-1$ //$NON-NLS-2$
		appendAttribute(tdElement, "nowrap", "nowrap"); //$NON-NLS-1$ //$NON-NLS-2$
		String tdStyle;
		if (isDisclosed && !isDisabled) {
			tdStyle = "font-family:Arial,Helvetica,Geneva,sans-serif;font-size:10pt;font-weight:bold;padding:0px 8px;"; //$NON-NLS-1$
		} else {
			tdStyle = "font-family:Arial,Helvetica,Geneva,sans-serif;font-size:10pt;font-weight:normal;padding:0px 8px;"; //$NON-NLS-1$
		}
		appendAttribute(tdElement, "style", tdStyle); //$NON-NLS-1$
		Element aElement = appendChildElement("a", tdElement); //$NON-NLS-1$
		String aStyle;
		if (isDisabled) {
			appendAttribute(aElement, "name", "name"); //$NON-NLS-1$ //$NON-NLS-2$
			aStyle = "color:#999999;"; //$NON-NLS-1$
		} else {
			appendAttribute(aElement, "href", "#"); //$NON-NLS-1$ //$NON-NLS-2$
			if (isDisclosed) {
				aStyle = "color:#669966;text-decoration:none;"; //$NON-NLS-1$
			} else {
				aStyle = "color:#003333;"; //$NON-NLS-1$
			}
		}
		if (isCurrent) {
			aStyle += "border:1px solid #99cc99;padding:2px;"; //$NON-NLS-1$
		}
		String attrShowDetailItemInlineStyle = showDetailItem.getAttribute("inlineStyle"); //$NON-NLS-1$
		if (attrShowDetailItemInlineStyle != null &&
				attrShowDetailItemInlineStyle.length() > 0) {
			aStyle += attrShowDetailItemInlineStyle;
		}
		if (aStyle.length() > 0) {
			appendAttribute(aElement, "style", aStyle); //$NON-NLS-1$
		}
		ITransformOperation operation =
			TransformOperationFactory.getInstance().getTransformOperation(
					TransformOperationFactory.OP_CopyAttributeWithRenameOperation,
					new String[]{"styleClass", "class"}); //$NON-NLS-1$ //$NON-NLS-2$
		operation.transform(showDetailItem, aElement);
		String attrShowDetailItemTextAndAccessKey = showDetailItem.getAttribute("textAndAccessKey"); //$NON-NLS-1$
		if (attrShowDetailItemTextAndAccessKey != null &&
				attrShowDetailItemTextAndAccessKey.length() > 0) {
			appendChildText(attrShowDetailItemTextAndAccessKey, aElement);
		} else {
			String attrShowDetailItemText = showDetailItem.getAttribute("text"); //$NON-NLS-1$
			if (attrShowDetailItemText != null && attrShowDetailItemText.length() > 0) {
				appendChildText(attrShowDetailItemText, aElement);
			}
		}
	}

	private int getCurrentShowDetailItem(
			Element srcElement, List<Node> showDetailItems) {
		int disclosedItem = TrinidadUtils.getCurrentChildIndex(srcElement);
		if (disclosedItem == -1) {
			disclosedItem = calculateDisclosedShowDetailItem(showDetailItems);
			TrinidadUtils.setCurrentChildIndex(srcElement, disclosedItem);
		}
		return disclosedItem;
	}

	private int calculateDisclosedShowDetailItem(List<Node> showDetailItems) {
		int disclosedItem = -1;
		int curItem = 0;
		Iterator<Node> itItems = showDetailItems.iterator();
		while (itItems.hasNext()) {
			Node item = itItems.next();
			if (item instanceof Element) {
				Element elemItem = (Element)item;
				String attrDisclosedVal = elemItem.getAttribute("disclosed"); //$NON-NLS-1$
				if (Boolean.TRUE.toString().equalsIgnoreCase(
						attrDisclosedVal)) {
					disclosedItem = curItem;
					break;
				}
			}
			curItem++;
		}
		//if none explicitly disclosed, consider first non-disabled tab disclosed
		if (disclosedItem == -1) {
			curItem = 0;
			itItems = showDetailItems.iterator();
			while (itItems.hasNext()) {
				Node item = itItems.next();
				if (item instanceof Element) {
					Element elemItem = (Element)item;
					String attrDisabledVal = elemItem.getAttribute("disabled"); //$NON-NLS-1$
					if (!(Boolean.TRUE.toString().equalsIgnoreCase(attrDisabledVal))) {
						disclosedItem = curItem;
						break;
					}
				}
				curItem++;
			}
		}
		//if none explicitly disclosed and all disabled, consider first tab disclosed
		if (disclosedItem == -1) {
			disclosedItem = 0;
		}
		return disclosedItem;
	}

}
