/*****************************************************************************
 * Copyright (c) 2017 Atos.
 * 
 * 
 * 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:
 * Mohamed Ali Bach Tobji (Atos) mohamed-ali.bachtobji@atos.net - Initial API and implementation
 *****************************************************************************/

package org.eclipse.gendoc.services.docx;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.eclipse.emf.common.util.EList;
import org.eclipse.gendoc.documents.AbstractTableService;
import org.eclipse.gendoc.documents.IDocumentService;
import org.eclipse.gendoc.services.exception.InvalidContentException;
import org.eclipse.gendoc.tags.ITag;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import org.eclipse.gendoc.table.Cell;
import org.eclipse.gendoc.table.Row;
import org.eclipse.gendoc.table.Table;

public class DOCXTableService extends AbstractTableService {

	/*
	 * 
	 * @see
	 * org.eclipse.gendoc.documents.ITableService#manageTable(org.eclipse.gendoc
	 * .tags.ITag, org.eclipse.gendoc.documents.IDocumentService,
	 * java.lang.StringBuffer, java.lang.Object, org.w3c.dom.Node)
	 */
	public String manageTable(ITag tag, IDocumentService documentService, StringBuffer returnValue, Object tableModel,
			Node tableNode) throws InvalidContentException {
		Node mainTable = tableNode.getFirstChild();
		if (documentService.isTable(mainTable.getNodeName())) {
			if (tableModel instanceof Table) {

				// extract width of the table to generate
				String wdth = getChildNode("w:gridCol", getChildNode("w:tblGrid", mainTable)).getAttributes()
						.getNamedItem("w:w").getNodeValue();
				Node rowNode = getChildNode(documentService.getRowLabel(), mainTable);
				String rowLabel = documentService.getRowLabel();
				/**
				 * FIXME find a better way to get the row label index
				 */
				Pattern rowPattern = Pattern.compile("<" + rowLabel + "[^<>]*>.*</" + rowLabel + ">");
				Matcher rowm = rowPattern.matcher(returnValue);
				int index_row_start = 0;
				int index_row_end = 0;
				if (rowm.find()) {
					index_row_start = rowm.start();
					index_row_end = returnValue.lastIndexOf("</" + rowLabel + ">");
					String row = returnValue.substring(index_row_start, index_row_end + rowLabel.length() + 3);
					String colLabel = documentService.getCellLabel();
					int index_col_start = row.lastIndexOf("<" + colLabel + ">");
					int index_col_end = row.lastIndexOf("</" + colLabel + ">");
					Node colNode = getChildNode(documentService.getCellLabel(), rowNode);
					int nbCol = ((Table) tableModel).getColCount();
					int colWidth = Math.round(Integer.parseInt(wdth) / nbCol);
					getChildNode("w:tcW", getChildNode("w:tcPr", colNode)).getAttributes().getNamedItem("w:w")
							.setNodeValue(String.valueOf(colWidth));
					StringBuffer colNodetxt = new StringBuffer(documentService.asText(colNode));
					String txtLabel = "w:p";
					String txtstyleLabel = "w:rPr";
					Pattern txtPattern = Pattern.compile("<" + txtLabel + "[^<>]*>.*</" + txtLabel + ">");
					Pattern txtstylePattern = Pattern
							.compile("<" + txtstyleLabel + "[^<>]*>.*</" + txtstyleLabel + ">");
					Matcher txtm = txtPattern.matcher(colNodetxt);
					Matcher txtstylem = txtstylePattern.matcher(colNodetxt);
					if (txtm.find()) {
						String style = "";
						if (txtstylem.find()) {
							style = colNodetxt.substring(txtstylem.start(),
									txtstylem.end() + txtstyleLabel.length() + 3);
						}

						return generateTable(returnValue, tableModel, rowLabel, index_row_start, index_row_end, row,
								colLabel, index_col_start, index_col_end, colNodetxt, txtm, style, txtLabel);
					}
				}
			}

		}
		return null;
	}

	/**
	 * Get a node from the parent node given as parameter
	 * 
	 * @param label
	 *            of the node to fetch
	 * @param parentnode
	 * @return
	 */
	private Node getChildNode(String label, Node parentnode) {

		NodeList rowChildNodes = parentnode.getChildNodes();
		for (int i = 0; i < rowChildNodes.getLength(); i++) {
			Node current = rowChildNodes.item(i);
			if (current.getNodeName() == label) {
				return current;
			}
		}
		return null;
	}

	/**
	 * Generates the table
	 * 
	 * @param returnValue
	 * @param tableModel
	 * @param rowLabel
	 * @param index_row_start
	 * @param index_row_end
	 * @param row
	 * @param colLabel
	 * @param index_col_start
	 * @param index_col_end
	 * @param colNodetxt
	 * @param txtm
	 * @param rows
	 * @param style
	 * @param txtLabel
	 * @return
	 */
	private String generateTable(StringBuffer returnValue, Object tableModel, String rowLabel, int index_row_start,
			int index_row_end, String row, String colLabel, int index_col_start, int index_col_end,
			StringBuffer colNodetxt, Matcher txtm, String style, String txtLabel) {
		String rows = "";
		String cells = "";
		// generate table header
		StringBuffer newRow = new StringBuffer(row);
		cells = generateCells(((Table) tableModel).getTableheader().getCells(), colNodetxt, txtm, style, txtLabel);
		newRow.replace(index_col_start, index_col_end + colLabel.length() + 3, cells);
		rows += newRow.toString();
		// generate table body
		for (Row r : ((Table) tableModel).getRows()) {
			newRow = new StringBuffer(row);
			cells = generateCells(r.getCells(), colNodetxt, txtm, style, txtLabel);
			newRow.replace(index_col_start, index_col_end + colLabel.length() + 3, cells);
			rows += newRow.toString();
		}
		return returnValue.replace(index_row_start, index_row_end + rowLabel.length() + 3, rows).toString();
	}

	/**
	 * Generates a row
	 * 
	 * @param modelCells
	 * @param colNodetxt
	 * @param txtm
	 * @param style
	 * @param txtLabel
	 * @param cols
	 * @return
	 */
	private String generateCells(EList<Cell> modelCells, StringBuffer colNodetxt, Matcher txtm, String style,
			String txtLabel) {
		String cols = "";
		for (Cell cell : modelCells) {
			StringBuffer newCol;
			int txtindex = txtm.end() - txtLabel.length() - 3;
			newCol = new StringBuffer(colNodetxt.toString());
			newCol.insert(txtindex, "<w:r>" + style + "<w:t>" + cell.getLabel() + "</w:t></w:r>");
			cols += newCol.toString();

		}
		return cols;
	}

}
