package unoofc.demo;

import java.io.*;
import unoofc.*;

/* This class demonstrates Calc document programming using unoofc, including charts. The program
 * opens a "shell" one-sheet document and operates on it, building a five-sheet document that is
 * saved. The single input argument is the pathname of the unoofc.demo folder. This folder contains
 * input files required by this program, and the five-sheet Calc document, unoofc.ods, is written to
 * this folder. The program also writes logging information to the console.
 */
public class OCalcDocDemo {
	private OCalcDoc iDoc = null;
	private OCalcDoc.Sheet iDataSheet = null;
	private OCalcDoc.Sheet.CellRange[] iDataRanges = new OCalcDoc.Sheet.CellRange[1];

	public static void main(String[] args) {
		try {
			File folder = new File(args[0]);
			OCalcDocDemo demo = new OCalcDocDemo(folder);
			demo.doCells();
			demo.doBitmap(folder);
			
			// make five charts, each on a separate sheet but using the same sheet 0 data range
			demo.doSheet0Chart();
			demo.doSheet1Chart();
			demo.doSheet2Chart();
			demo.doSheet3Chart();
			demo.doSheet4Chart();
			demo.end(folder);
		} catch (java.lang.Exception xcp) {
			xcp.printStackTrace();
		}
	}
	
	private OCalcDocDemo(File folder) throws Exception {
		// open example Calc document
		String url = OUtil.urlFromPath(folder.getAbsolutePath());
		iDoc = new OCalcDoc(url + "/calc-shell.ods");
		iDataSheet = iDoc.sheet((short) 0);
		iDataSheet.setName("Zero");
		
		// create data range for all charts -- all data cells used for charts are on sheet 0
		iDataRanges[0] = iDataSheet.areaRange("C3:E10");
		iDataRanges[0].setProp(OProps.Cell.CellBackColor, OColor.RED);
	}
	
	private void doCells() throws Exception {
		// operate on rows and columns
		iDataSheet.insertRowsBelow(1, 2);
		iDataSheet.deleteColumns(5, 2);
		
		// operate on ranges
		OCalcDoc.Sheet.CellRange range = iDataSheet.columnRange(0);
		range.setProp(OProps.Cell.CellBackColor, OColor.BLUE);
		range = iDataSheet.areaRange(5, 5, 8, 7);
		range.setProp(OProps.Cell.CellBackColor, OColor.GREEN);
		String[][] text = {{"a1", "a2", "a3", "a4"}, {"b1", "b2", "b3", "b4"}, {"c1", "c2", "c3", "c4"}};
		range.putCellText(text);
		range.logCellContents();
		Double[][] doubles = {{1.0, 2.0}, {3.0, 4.0}};
		range = iDataSheet.areaRange("F2:G3");
		range.putCellNumbers(doubles);
		OStyle.Cell style = new OStyle.Cell(iDoc, "Accent");	// built-in style
		style.setProp(OProps.Char.CharFontName, "Times New Roman");
		range.putStyle(style);
		range.putFormat(OTable.CellNumberFormat.SCIENTIFIC);
		
		// operate on a cell
		OTable.Cell cell = iDataSheet.cell("H10");
		cell.setFormula("cell H10");
		cell.setProp(OProps.Char.CharColor, OColor.CYAN);

		// add a calculation
		cell = iDataSheet.cell(1, 12);
		cell.setFormula("H00A");
		cell = iDataSheet.cell(2, 12);
		cell.setFormula("9");
		cell = iDataSheet.cell(3, 12);
		cell.setFormula("=$A$7 * C13");
		cell = iDataSheet.cell(4, 12);
		cell.setFormula("=D13 * (RAND() + $A$10");
	}		

	private void doBitmap(File folder) throws Exception {
		String url = OUtil.urlFromPath(folder.getAbsolutePath()) + "/example.jpg";
		ODrawArea area = new ODrawArea(new com.sun.star.awt.Point(14000, 6000), 
				new com.sun.star.awt.Size(4000, 4000));
		iDoc.insertBitmap(iDataSheet, area, url);
	}
	
	private void doSheet0Chart() throws Exception {
		// create Column chart
		ODrawArea drawArea = new ODrawArea(new com.sun.star.awt.Point(1000, 7000), 
				new com.sun.star.awt.Size(12000, 9000));
		OChartDoc chartDoc = new OChartDoc(OChartDoc.BasicType.Column, iDoc.sheet((short) 0), iDataSheet,
				iDataRanges, drawArea, OChartDoc.LabelsLocation.NEITHER, "Chart 0");
		
		// setup title
		OChartDoc.Title title = chartDoc.title();
		title.setText(chartDoc.name());
		title.setProp(OProps.Char.CharHeight, 28);
		title.setProp(OProps.Char.CharColor, OColor.BLUE);
		
		// change background
		OUtil.FillProps fillProps = new OUtil.FillProps();
		fillProps.setProp(OProps.Fill.FillColor, OColor.YELLOW);
		fillProps.applyTo(chartDoc.background());
		
		// setup x axis
		OChartDoc.Axis axis = chartDoc.axis(OChartDoc.AxisId.X);
		title = axis.title();
		title.setText("X Axis");
		OUtil.CharProps cProps = new OUtil.CharProps();
		cProps.setProp(OProps.Char.CharHeight, 7);
		cProps.applyTo(title);
		
		// setup y axis
		axis = chartDoc.axis(OChartDoc.AxisId.Y);
		title = axis.title();
		title.setText("Y Axis");
		cProps.applyTo(title);
	}
	
	private void doSheet1Chart() throws Exception {
		// create StackedColumn chart
		ODrawArea drawArea = new ODrawArea(new com.sun.star.awt.Point(1000, 1000), 
				new com.sun.star.awt.Size(12000, 9000));
		OCalcDoc.Sheet chartSheet = iDoc.insertSheet((short) 1, "Chart 1");
		OChartDoc chartDoc = new OChartDoc(OChartDoc.BasicType.StackedColumn, chartSheet, iDataSheet,
				iDataRanges, drawArea, OChartDoc.LabelsLocation.NEITHER, chartSheet.name());
		
		// setup title
		OChartDoc.Title title = chartDoc.title();
		title = chartDoc.title();
		title.setText(chartSheet.name());
		
		// change wall
		OUtil.LineProps lineProps = new OUtil.LineProps();
		lineProps.setProp(OProps.Line.LineWidth, 100);
		lineProps.applyTo(chartDoc.wall());
		
		// set color for first data series
		OUtil.FillProps fillProps = new OUtil.FillProps();
		fillProps.setProp(OProps.Fill.FillColor, OColor.YELLOW);
		OChartDoc.DataSeries[] series = chartDoc.allDataSeries();
		fillProps.applyTo(series[0]);
	}

	private void doSheet2Chart() throws Exception {
		// create ScatterSymbol chart
		ODrawArea drawArea = new ODrawArea(new com.sun.star.awt.Point(1000, 1000), 
				new com.sun.star.awt.Size(12000, 9000));
		OCalcDoc.Sheet chartSheet = iDoc.insertSheet((short) 2, "Chart 2");
		OChartDoc chartDoc = new OChartDoc(OChartDoc.BasicType.ScatterSymbol, chartSheet, iDataSheet,
				iDataRanges, drawArea, OChartDoc.LabelsLocation.NEITHER, chartSheet.name());
		
		// setup title
		OChartDoc.Title title = chartDoc.title();
		title.setText(chartSheet.name());
		
		// setup X axis
		OChartDoc.Axis axis = chartDoc.axis(OChartDoc.AxisId.X);
		axis.setScaleMax(200);
		OUtil.LineProps lineProps = new OUtil.LineProps();
		lineProps.setProp(OProps.Line.LineColor, OColor.BLUE);
		lineProps.applyTo(axis);
		axis.setGridProps(lineProps, true);
	
		// setup Y axis
		axis = chartDoc.axis(OChartDoc.AxisId.Y);
		axis.setScaling(OChartDoc.AxisScalingType.LOGARITHMIC);
		
		// set data series symbols
		OChartDoc.DataSeries[] series = chartDoc.allDataSeries();
		series[0].setPointSymbol(OChartDoc.DataPointSymbol.SQUARE, null);
		series[1].setPointSymbol(OChartDoc.DataPointSymbol.TRIANGLE, new com.sun.star.awt.Size(200, 200));
		
		// put red error bars on Column D series
		OCalcDoc.Sheet.CellRange errorRange = iDataSheet.areaRange("C5:C13");
		OUtil.LineProps props = new OUtil.LineProps();
		props.setProp(OProps.Line.LineColor, OColor.RED);
		chartDoc.showYErrorBars("Column D", iDataSheet, errorRange, props);
	}
	
	private void doSheet3Chart() throws Exception {
		// create Pie chart
		ODrawArea drawArea = new ODrawArea(new com.sun.star.awt.Point(1000, 1000), 
				new com.sun.star.awt.Size(12000, 9000));
		OCalcDoc.Sheet chartSheet = iDoc.insertSheet((short) 3, "Chart 3");
		OChartDoc chartDoc = new OChartDoc(OChartDoc.BasicType.Pie, chartSheet, iDataSheet,
				iDataRanges, drawArea, OChartDoc.LabelsLocation.NEITHER, chartSheet.name());
		
		// setup title and legend
		OChartDoc.Title title = chartDoc.title();
		title.setText(chartSheet.name());
		OChartDoc.Legend legend = chartDoc.legend();
		legend.setProp(OProps.Legend.Show, false);
	}
	
	private void doSheet4Chart() throws Exception {
		// create ThreeDColumnDeep
		ODrawArea drawArea = new ODrawArea(new com.sun.star.awt.Point(1000, 1000), 
				new com.sun.star.awt.Size(12000, 9000));
		OCalcDoc.Sheet chartSheet = iDoc.insertSheet((short) 4, "Chart 4");
		OChartDoc chartDoc = new OChartDoc("ThreeDColumnFlat", chartSheet, iDataSheet,
				iDataRanges, drawArea, OChartDoc.LabelsLocation.NEITHER, chartSheet.name());
		
		// setup title
		OChartDoc.Title title = chartDoc.title();
		title.setText(chartSheet.name());
		
		// setup first data series
		OChartDoc.DataSeries[] series = chartDoc.allDataSeries();
		series[0].set3DShape(OChartDoc.Shape3D.CYLINDER);
		OUtil.FillProps fillProps = new OUtil.FillProps();
		fillProps.setProp(OProps.Fill.FillColor, OColor.CYAN);
		fillProps.applyTo(series[0]);
	}
	
	private void end(File folder) throws Exception {
		// list chart names and summary
		OEnv.obj().log(iDoc.chartNames(), "Document ChartNames");
		iDoc.logSummary();
		String url = OUtil.urlFromPath(folder.getAbsolutePath()) + "/unoofc";
		iDoc.writeOds(url);
	}
}