/*******************************************************************************
 * 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.dom.html;

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

import org.eclipse.jst.pagedesigner.IHTMLConstants;
import org.eclipse.jst.pagedesigner.utils.DOMUtil;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
 * @author mengbo
 * @version 1.5
 */
public class TableUtil {
	private Element _fakeCell = null;

	private Element _table = null;

	private List[] _trCellLists = null;

	/**
	 * judge whether there is rowspan>1 cell in the tr
	 * 
	 * @param tr
	 *            TR element in a table
	 * @return true if there is rowspan>1 cell in the tr
	 */
	public static boolean hasRowSpanElement(Element tr) {
		List list = DOMUtil.getElementChildren(tr);
		Iterator itr = list.iterator();
		while (itr.hasNext()) {
			Element ele = (Element) itr.next();
			int value = DOMUtil.getIntAttributeIgnoreCase(ele,
					IHTMLConstants.ATTR_ROWSPAN, 1);
			if (value > 1) {
				return true;
			}
		}
		return false;
	}

	/**
	 * judge whether a tr is affected by row span cell in the previous trs.
	 * 
	 * @param trList
	 *            list holds all tr elements in a table
	 * @param tr
	 * @param index
	 *            tr index in the DOM tree
	 * @return true if tr is affected by row span cell in the previous trs
	 */
	public static boolean isAffectedByRowSpan(List trList, Element tr, int index) {
		Node parent = tr.getParentNode();
		int dex = index;
		while (--dex >= 0) {
			Element preTr = (Element) trList.get(dex);
			if (preTr.getParentNode() != parent) {
				break;
			}
            int maxRowSpan = countMaxRowSpan(preTr);
            if (maxRowSpan > (index - dex)) {
            	return true;
            }
		}
		return false;
	}

	/**
	 * count all tr in the table
	 * 
	 * @param element
	 *            table
	 * @param list
	 *            list to hold tr elements
	 */
	public static void getTrElements(Element element, List list) {
		NodeList nodeList = element.getChildNodes();
		for (int i = 0, size = nodeList.getLength(); i < size; i++) {
			Node node = nodeList.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				Element ele = (Element) node;
				if (ele.getNodeName().equalsIgnoreCase(IHTMLConstants.TAG_TR)) {
					list.add(ele);
				} else if (ele.getNodeName().equalsIgnoreCase(
						IHTMLConstants.TAG_THEAD)
						|| ele.getNodeName().equalsIgnoreCase(
								IHTMLConstants.TAG_TBODY)
						|| ele.getNodeName().equalsIgnoreCase(
								IHTMLConstants.TAG_TFOOT)) {
					getTrElements(ele, list);
				}
			}

		}
	}

	/**
	 * count row index in the code DOM tree according to the display index
	 * 
	 * @param table
	 * @param displayIndex
	 * @return the row index
	 */
	public static int countRowIndexInDOMTree(Element table, int displayIndex) {

		int footRows = countSectionRows(table, IHTMLConstants.TAG_TFOOT);
		if (footRows == 0) {
			return displayIndex;
		}
		int headRows = countSectionRows(table, IHTMLConstants.TAG_THEAD);
		List list = new ArrayList();
		getTrElements(table, list);
		int bodyRows = list.size() - headRows - footRows;
		// if display index is in TFOOT area
		if (displayIndex >= (list.size() - footRows)) {
			int index = displayIndex - bodyRows;
			return index;
		}
		// if display index is in TBODY area
		else if (displayIndex >= headRows) {
			int index = displayIndex + footRows;
			return index;
		}
		// if display index is in THEAD area
		else {
			return displayIndex;
		}
	}

	/**
	 * get row count in the specified section
	 * 
	 * @param table
	 * @param sectionName
	 *            child element name of table, like THEAD or TFOOT
	 * @return the row count in the section
	 */
	public static int countSectionRows(Element table, String sectionName) {
		NodeList nodeList = table.getChildNodes();
		for (int i = 0, size = nodeList.getLength(); i < size; i++) {
			Node node = nodeList.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				Element ele = (Element) node;
				if (node.getNodeName().equalsIgnoreCase(sectionName)) {
					List list = DOMUtil.getChildElementsByTagIgnoreCase(ele,
							IHTMLConstants.TAG_TR);
					if (list != null) {
						return list.size();
					}
				}
			}

		}
		return 0;
	}

	/**
	 * constructor
	 * 
	 * @param table
	 */
	public TableUtil(Element table) {
		this._table = table;
		this._trCellLists = fillTrCells();
	}

	/**
	 * get tr cells list
	 * 
	 * @return the list of tr cells
	 */
	public List[] getTrCellLists() {
		return this._trCellLists;
	}

	/**
	 * calculate row and column index for tr or td/th
	 * 
	 * @param node
	 *            tr or td/th
	 * @return the position
	 */
	public TableChildElementPosition getPosition(Node node) {
		TableChildElementPosition position = new TableChildElementPosition();
		String tagName = node.getLocalName();
		if (IHTMLConstants.TAG_TR.equalsIgnoreCase(tagName)) {
			List list = new ArrayList();
			getTrElements(this._table, list);
			for (int i = 0, size = list.size(); i < size; i++) {
				Element tr = (Element) list.get(i);
				if (tr == node) {
					position.setRowIndex(i);
					break;
				}
			}
		} else if (IHTMLConstants.TAG_TD.equalsIgnoreCase(tagName)
				|| IHTMLConstants.TAG_TH.equalsIgnoreCase(tagName)) {
			Element tr = (Element) node.getParentNode();
			TableChildElementPosition pos = getPosition(tr);
			position.setRowIndex(pos.getRowIndex());
			List[] lists = getTrCellLists();
			List list = lists[pos.getRowIndex()];
			for (int i = 0, size = list.size(); i < size; i++) {
				Element td = (Element) list.get(i);
				if (td == node) {
					position.setColumnIndex(i);
					break;
				}
			}
		} else {
			boolean hasTDParent = false;
			Node childBackup = node;
			while (!IHTMLConstants.TAG_TABLE.equalsIgnoreCase(childBackup
					.getParentNode().getLocalName())) {
				childBackup = childBackup.getParentNode();
				String localName = childBackup.getLocalName();
				if (IHTMLConstants.TAG_TD.equalsIgnoreCase(localName)
						|| IHTMLConstants.TAG_TH.equalsIgnoreCase(localName)) {
					hasTDParent = true;
					break;
				}
			}
			if (hasTDParent) {
				position = getPosition(childBackup);
			}
		}
		return position;
	}

	/**
	 * get column count
	 * 
	 * @return the column count
	 */
	public int getColumnCount() {
		List[] lists = this._trCellLists;
		if (lists != null) {
			int max = 0;
			for (int i = 0, size = lists.length; i < size; i++) {
				List list = lists[i];
				if (list.size() > max) {
					max = list.size();
				}
			}
			return max;
		}
		return 0;
	}

	/**
	 * judge whether there is columnspan>1 cell in the column
	 * 
	 * @param columnIndex
	 *            column index in a table
	 * @return true if there is columnspan>1 cell in the column
	 */
	public boolean hasColumnSpanElement(int columnIndex) {
		List cells = getColumnCells(columnIndex);
		if (cells != null) {
			Iterator itr = cells.iterator();
			while (itr.hasNext()) {
				Element cell = (Element) itr.next();
				int value = DOMUtil.getIntAttributeIgnoreCase(cell,
						IHTMLConstants.ATTR_COLSPAN, 1);
				if (value > 1) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * judge whether the column has cell affected by column span cell in
	 * privious columns
	 * 
	 * @param columnIndex
	 * @return true if the column has cell affected by column span cell in
     * privious columns 
	 */
	public boolean isAffectedByColSpan(int columnIndex) {
		int index = columnIndex;
		while (--index >= 0) {
			List cells = getColumnCells(index);
			int max = countMaxColSpan(cells);
			if (max > (columnIndex - index)) {
				return true;
			}
		}

		return false;
	}

	/**
	 * get cells in the specified column of the table
	 * 
	 * @param columnIndex
	 * @return the column cells
	 */
	public List getColumnCells(int columnIndex) {
		List list = new ArrayList();

		List[] lists = this._trCellLists;
		for (int i = 0; i < lists.length; i++) {
			List tempList = lists[i];
			if (tempList.size() <= columnIndex) {
				continue;
			}
			list.add(tempList.get(columnIndex));
		}
		return list;
	}

	/**
	 * count max row span in the tr
	 * 
	 * @param tr
	 * @return
	 */
	private static int countMaxRowSpan(Element tr) {
		List list = DOMUtil.getElementChildren(tr);
		int max = countMaxValue(list, IHTMLConstants.ATTR_ROWSPAN);
		return max;
	}

	/**
	 * count max attr value
	 * 
	 * @param list
	 * @param attr
	 * @return
	 */
	private static int countMaxValue(List list, String attr) {
		int max = 1;
		Iterator itr = list.iterator();
		while (itr.hasNext()) {
			Element ele = (Element) itr.next();
			int value = DOMUtil.getIntAttributeIgnoreCase(ele, attr, 1);
			if (value > max) {
				max = value;
			}
		}
		return max;
	}

	/**
	 * count max col span in a column
	 * 
	 * @param list
	 * @return
	 */
	private int countMaxColSpan(List list) {
		int max = countMaxValue(list, IHTMLConstants.ATTR_COLSPAN);
		return max;
	}

	/**
	 * get fake element to fill tr cell
	 * 
	 * @return
	 */
	private Element getFakeElement() {
		if (_fakeCell != null) {
			return _fakeCell;
		}
		_fakeCell = this._table.getOwnerDocument().createElement("fake"); //$NON-NLS-1$
		return _fakeCell;
	}

	/**
	 * initial every tr cells according to th and td under each tr element
	 * 
	 * @param trList
	 * @return
	 */
	private List[] initialTrCells(List trList) {
		int size = trList.size();
		List[] lists = new ArrayList[size];

		if (trList != null) {
			for (int i = 0, n = trList.size(); i < n; i++) {
				lists[i] = new ArrayList();
				Element tr = (Element) trList.get(i);
				List domCells = DOMUtil.getElementChildren(tr);
				Iterator itr = domCells.iterator();
				while (itr.hasNext()) {
					Element cell = (Element) itr.next();
					lists[i].add(cell);
					int colSpan = DOMUtil.getIntAttributeIgnoreCase(cell,
							IHTMLConstants.ATTR_COLSPAN, 1);
					while (--colSpan > 0) {
						Element fakeElement = getFakeElement();
						lists[i].add(fakeElement);
					}
				}
			}

		}

		return lists;

	}

	/**
	 * after initial tr cells,fill tr with fake cells if necessary.
	 * 
	 * @return
	 */
	private List[] fillTrCells() {
		List list = new ArrayList();
		getTrElements(this._table, list);

		List[] lists = initialTrCells(list);
		int size = lists.length;

		int headRows = countSectionRows(this._table, IHTMLConstants.TAG_THEAD);
		if (headRows > 0) {
			List[] headList = new ArrayList[headRows];
			for (int i = 0; i < headRows; i++) {
				headList[i] = lists[i];
			}
			fillSectionTrCells(headList);
		}

		int footRows = countSectionRows(this._table, IHTMLConstants.TAG_TFOOT);
		if (footRows > 0) {
			List[] footList = new ArrayList[footRows];
			for (int i = 0; i < footRows; i++) {
				footList[i] = lists[headRows + i];
			}
			fillSectionTrCells(footList);
		}

		int bodyRows = size - headRows - footRows;
		if (bodyRows > 0) {
			int bodyCount = 1;
			int k = 0;
			List bodys = new ArrayList();
			Element tr = (Element) list.get(headRows + footRows);
			Node node = tr.getParentNode();
			for (int i = 1; i < bodyRows; i++) {
				Element tempTr = (Element) list.get(headRows + footRows + i);
				if (tempTr.getParentNode() != node) {
					node = tempTr.getParentNode();
					bodys.add(new Integer(i - k));
					k = i;
					bodyCount++;
				}
			}
			bodys.add(new Integer(bodyRows - k));

			for (int j = 0; j < bodyCount; j++) {
				int num = ((Integer) bodys.get(j)).intValue();
				List[] bodyList = new ArrayList[num];
				int m = headRows + footRows;

				for (int i = 0; i < num; i++) {
					bodyList[i] = lists[m + i];
				}
				fillSectionTrCells(bodyList);
				m = m + num;
			}

		}

		return lists;
	}

	/**
	 * fill tr cells under each table section,like THEAD,TFOOT,TBODY.
	 * 
	 * @param lists
	 */
	private void fillSectionTrCells(List[] lists) {
		Element cell = null;

		if (lists != null) {
			for (int i = 1, size = lists.length; i < size; i++) {
				List insertPoints = new ArrayList();

				for (int j = 0; j < i; j++) {
					List list = lists[j];
					for (int column = 0; column < list.size(); column++) {
						cell = (Element) list.get(column);
						if (cell.getTagName().equalsIgnoreCase("fake")) { //$NON-NLS-1$
							continue;
						}
						int rowSpan = DOMUtil.getIntAttributeIgnoreCase(cell,
								IHTMLConstants.ATTR_ROWSPAN, 1);
						if (rowSpan > (i - j)) {
							int colSpan = DOMUtil.getIntAttributeIgnoreCase(
									cell, IHTMLConstants.ATTR_COLSPAN, 1);
							insertPoints.add(new ColStructure(column, colSpan));
						}
					}
				}
				// there are fake column cell need to be inserted into this tr
				if (insertPoints.size() > 0) {
					Collections.sort(insertPoints);
					List trCells = lists[i];

					Iterator itr = insertPoints.iterator();
					while (itr.hasNext()) {
						ColStructure cls = (ColStructure) itr.next();
						int loop = cls.getColSpan();
						int column = cls.getColumn();
						while (loop-- != 0) {
							trCells.add(column++, getFakeElement());
						}

					}
				}
			}
		}
	}
}
