/*******************************************************************************
 * Copyright (C) 2007 The University of Manchester
 *
 *  Modifications to the initial code base are copyright of their
 *  respective authors, or their employers as appropriate.
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public License
 *  as published by the Free Software Foundation; either version 2.1 of
 *  the License, or (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 ******************************************************************************/
package net.sf.taverna.t2.workbench.views.results.saveactions;

import static java.lang.Math.max;
import static java.util.Arrays.asList;
import static net.sf.taverna.t2.baclava.factory.DataThingFactory.bake;
import static net.sf.taverna.t2.workbench.icons.WorkbenchIcons.saveIcon;
import static org.apache.poi.ss.usermodel.CellStyle.BORDER_NONE;
import static org.apache.poi.ss.usermodel.CellStyle.BORDER_THIN;
import static org.apache.poi.ss.usermodel.CellStyle.SOLID_FOREGROUND;

import java.beans.IntrospectionException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Collection;

import javax.swing.AbstractAction;

import net.sf.taverna.t2.baclava.DataThing;
import net.sf.taverna.t2.baclava.iterator.BaclavaIterator;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;

/**
 * Stores the entire map of result objects to disk as a single XML data document.
 *
 * @author Tom Oinn
 */
public class SaveAllResultsAsExcel extends SaveAllResultsSPI {
	private static final long serialVersionUID = -2759817859804112070L;

	HSSFWorkbook wb = null;
	HSSFSheet sheet = null;
	HSSFCellStyle headingStyle = null;
	HSSFCellStyle[] styles = null;

	public SaveAllResultsAsExcel() {
		super();
		putValue(NAME, "Save as Excel");
		putValue(SMALL_ICON, saveIcon);
	}

	@Override
	public AbstractAction getAction() {
		return new SaveAllResultsAsExcel();
	}

	@Override
	protected void saveData(File f) throws IOException {
		try {
			generateSheet();
		} catch (IntrospectionException e) {
			throw new IOException("failed to generate excel sheet model", e);
		}
		saveSheet(f);
	}

	/**
	 * Generate the Excel sheet from the DataThing's in the map. All of the
	 * results are shown in the same spreadsheet, but in different columns. Flat
	 * lists are shown vertically, 2d lists as a matrix, and deeper lists are
	 * flattened to 2d.
	 * 
	 * @throws IntrospectionException
	 */
	void generateSheet() throws IntrospectionException {
		wb = new HSSFWorkbook();
		setStyles();
		sheet = wb.createSheet("Workflow results");
		sheet.setDisplayGridlines(false);
		int currentCol = 0;

		for (String portName : chosenReferences.keySet()) {
			logger.debug("Output for : " + portName);
			DataThing resultValue = bake(getObjectForName(portName));
			// Check whether there's a textual type
			Boolean textualType = isTextual(resultValue.getDataObject());
			if (textualType == null || !textualType)
				continue;
			logger.debug("Output is textual");
			getCell(currentCol, 0).setCellValue(portName);
			getCell(currentCol, 0).setCellStyle(headingStyle);
			int numCols = 1;
			int numRows = 1;
			int currentRow = 0;
			BaclavaIterator rows;
			try {
				rows = resultValue.iterator("l('')");
			} catch (IntrospectionException ex) {
				// Not a list, single value. We'll fake the iterator
				DataThing fakeValues = new DataThing(
						asList(resultValue.getDataObject()));
				rows = fakeValues.iterator("l('')");
			}
			/*
			 * If we only have one row, we'll show each value on a new row
			 * instead
			 */
			boolean isFlat = rows.size() == 1;
			while (rows.hasNext()) {
				DataThing row = (DataThing) rows.next();
				/*
				 * Even increase first time, as we don't want to overwrite our
				 * header
				 */
				currentRow++;
				BaclavaIterator bi = row.iterator("''");
				while (bi.hasNext()) {
					DataThing containedThing = (DataThing) bi.next();
					String containedValue = (String) containedThing.getDataObject();
					int columnOffset = 0;
					int[] location = bi.getCurrentLocation();
					if (!isFlat && location.length > 0) {
						columnOffset = location[location.length - 1];
						numCols = Math.max(numCols, columnOffset + 1);
					}
					logger.debug("Storing in cell " + (currentCol + columnOffset) + " "
							+ currentRow + ": " + containedValue);
					getCell(currentCol + columnOffset, currentRow).setCellValue(containedValue);
					if (isFlat)
						currentRow++;
				}
			}
			numRows = max(numRows, currentRow);

			// Set the styles
			for (int x = currentCol; x < currentCol + numCols; x++)
				for (int y = 1; y < numRows + 1; y++)
					setStyle(currentCol, x, y);
			sheet.setColumnWidth(currentCol + numCols, 200);
			currentCol += numCols + 1;
		}
	}

	void setStyle(int currentCol, int column, int row) {
		if (!hasValue(column, row))
			return;
		HSSFCell cell = getCell(column, row);
		int n = 0, s = 0, w = 0, e = 0;
		if (row < 2 || !hasValue(column, row - 1))
			n = 1;
		if (column == currentCol || !hasValue(column - 1, row))
			w = 1;
		if (!hasValue(column, row + 1))
			s = 1;
		if (!hasValue(column + 1, row))
			e = 1;
		int index = n + 2 * s + 4 * e + 8 * w;
		cell.setCellStyle(styles[index]);
	}

	void setStyles() {
		headingStyle = wb.createCellStyle();
		headingStyle.setBorderTop(BORDER_THIN);
		headingStyle.setBorderBottom(BORDER_THIN);
		headingStyle.setBorderLeft(BORDER_THIN);
		headingStyle.setBorderRight(BORDER_THIN);
		headingStyle.setFillBackgroundColor(HSSFColor.LIGHT_YELLOW.index);
		headingStyle.setFillForegroundColor(HSSFColor.LIGHT_YELLOW.index);
		headingStyle.setFillPattern(SOLID_FOREGROUND);
		styles = new HSSFCellStyle[16];
		for (int n = 0; n < 2; n++)
			for (int s = 0; s < 2; s++)
				for (int e = 0; e < 2; e++)
					for (int w = 0; w < 2; w++) {
						int index = n + 2 * s + 4 * e + 8 * w;
						styles[index] = wb.createCellStyle();
						styles[index].setBorderTop(n == 1 ? BORDER_THIN
								: BORDER_NONE);
						styles[index].setBorderBottom(s == 1 ? BORDER_THIN
								: BORDER_NONE);
						styles[index].setBorderRight(e == 1 ? BORDER_THIN
								: BORDER_NONE);
						styles[index].setBorderLeft(w == 1 ? BORDER_THIN
								: BORDER_NONE);
						styles[index].setFillBackgroundColor(HSSFColor.GOLD.index);
						styles[index].setFillForegroundColor(HSSFColor.GOLD.index);
						styles[index].setFillPattern(SOLID_FOREGROUND);
					}
	}

	/**
	 * Check if o is a String or contains elements that satisfy isTextual(o)
	 * <p>
	 * Traverse down the Collection o if possible, and check the tree of collection at the deepest
	 * level.
	 * </p>
	 *
	 * @param o
	 *            Object to check
	 * @return true if o is a String or is a Collection that contains a string at the deepest level.
	 *         false if o is not a String or Collection, or if it is a collection that contains
	 *         non-strings.
	 *         null if o is a Collection, but it is empty or contains nothing but Collections.
	 */
	Boolean isTextual(Object o) {
		if (o instanceof String)
			// We dug down and found a string. Hurray!
			return true;
		if (o instanceof Collection) {
			for (Object child : (Collection<?>) o) {
				Boolean isTxt = isTextual(child);
				if (isTxt == null)
					// Unknown, try next one
					continue;
				return isTxt;
			}
			/*
			 * We looped through and found just empty collections (or we are an
			 * empty collection), we don't know.
			 */
			return null;
		}
		// No, sorry mate.. o was neither a String or Collection
		return false;
	}

	/**
	 * Get a cell at the given coordinates, create it if needed.
	 *
	 * @param column
	 * @param row
	 * @return
	 */
	HSSFCell getCell(int column, int row) {
		HSSFRow srow = sheet.getRow(row);
		if (srow == null)
			srow = sheet.createRow(row);
		HSSFCell scell = srow.getCell(column);
		if (scell == null)
			scell = srow.createCell(column);
		return scell;
	}

	/**
	 * Check if a cell has a value.
	 *
	 * @param column
	 * @param row
	 * @return
	 */
	boolean hasValue(int column, int row) {
		HSSFRow srow = sheet.getRow(row);
		if (srow == null)
			return false;
		HSSFCell scell = srow.getCell(column);
		if (scell == null)
			return false;
		return true;
	}

	/**
	 * Save the generated worksheet to a file
	 *
	 * @param file
	 *            to save to
	 * @throws FileNotFoundException
	 * @throws IOException
	 */
	void saveSheet(File file) throws IOException {
		FileOutputStream fos = new FileOutputStream(file);
		wb.write(fos);
		fos.close();
	}

	@Override
	protected String getFilter() {
		return "xls";
	}
}
