/*

 * Delivered to the U.S. Government in Accordance with Contract FA8650-10-C-7080.

 *

 * EXPORT CONTROLLED

 * ECCN#   EAR99

 * Warning: This document contains technical data which is controlled under the

 * Bureau of Industry & Security's Export Administration Regulations and may not be

 * exported or re-exported without authorization by the Bureau of Industry & Security.

 * Diversion contrary to US law is prohibited.

 *

 * (c) 2011 United Technologies Corp.

 * Developed with the sponsorship of the Defense Advanced Research Projects Agency (DARPA).

 *

 * Permission is hereby granted, free of charge, to any person obtaining a copy of this data,

 * including any software or models in source or binary form, as well as any drawings, 

 * specifications, and documentation (collectively "the Data"), to deal in the Data without 

 * restriction, including without limitation the rights to use, copy, modify, merge, publish,

 * distribute, sublicense, and/or sell copies of the Data, and to permit persons to whom the Data

 * is furnished to do so, subject to the following conditions:

 * 

 * The above copyright notice and this permission notice shall be included in all copies or

 * substantial portions of the Data.

 *

 * THE DATA IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING

 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND

 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS, SPONSORS, DEVELOPERS, CONTRIBUTORS, OR

 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION

 * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE DATA OR THE

 * USE OR OTHER DEALINGS IN THE DATA.

*/



package aee.excel;



import org.eclipse.swt.SWT;

import org.eclipse.swt.SWTError;

import org.eclipse.swt.ole.win32.OleAutomation;

import org.eclipse.swt.ole.win32.OleControlSite;

import org.eclipse.swt.ole.win32.OleFrame;

import org.eclipse.swt.ole.win32.Variant;

import org.eclipse.swt.widgets.Display;

import org.eclipse.swt.widgets.Shell;



import aee.exception.AeeException;



/**

 * Represents the Excel Application object

 */

public class ExcelApplication extends ComAutomation {

	private Display display;

	

	/**

	 * Constructor builds an Excel Application

	 * @throws AeeException if any SWT/COM error

	 */

	public ExcelApplication() throws AeeException {

		display              = new Display();

		Shell          shell = new Shell(display);

		try {

			OleFrame       frame = new OleFrame(shell, SWT.NONE);

			OleControlSite site  = new OleControlSite(frame, SWT.NONE,

		 																					"Excel.Application");

			setAutomation(new OleAutomation(site));



		} catch (SWTError swterr) {

			throw new AeeException("Error creating %s: %s", this.getClass()

					                                                .getSimpleName(),

					                                            swterr);

		}

	}

	

	/* (non-Javadoc)

	 * @see com.csc.aee.excel.ComAutomation#dispose()

	 */

	@Override

	public void dispose() {

		super.dispose();

		display.dispose();

	}



	/**

	 * Get the Workbooks property

	 * @return A Workbooks object

	 * @throws AeeException if any SWT/COM error

	 */

	public Workbooks getWorkbooks() throws AeeException {

		OleAutomation oleauto = getProperty("Workbooks");

		if (oleauto == null)

			throw new AeeException("Error getting the \"Workbooks\" property in an Application");

		return new Workbooks(oleauto);

	}



	/**

	 * Set the application's visibility

	 * @param visibility  true if visible; false if invisible

	 * @throws AeeException if any SWT/COM error

	 */

	public void setVisible(boolean visibility) throws AeeException {

		setBooleanProperty("Visible", visibility);

	}



	/**

	 * Set the application's interactive property

	 * @param interactive  true if interactive; false if not

	 * @throws AeeException if any SWT/COM error

	 */

	public void setInteractive(boolean interactive) throws AeeException {

		setBooleanProperty("Interactive", interactive);

	}

	

	/**

	 * Set a boolean property

	 * @param property The property name

	 * @param value    The property value

	 * @throws AeeException if any SWT/COM error

	 */

	private void setBooleanProperty(String property, boolean value) throws AeeException {

		Variant arg = null;

		try {

			arg = new Variant(value);

			setProperty(property, arg);

			

		} finally {

			if (arg != null) arg.dispose();

		}

	}

	

	/**

	 * Run a macro

	 * @param macroName The name of the macro

	 * @throws AeeException if any SWT/COM error

	 */

	public void executeMacro(final String macroName) throws AeeException {

		Variant arg    = null;

		Variant result = null;

		try {

			int[]     dispMIDs  = getAutomation().getIDsOfNames(new String[]{"Run"});

			arg                 = new Variant(macroName);

			Variant[] arguments = new Variant[]{arg}; 

			result              = getAutomation().invoke(dispMIDs[0],arguments);

		

		} catch (SWTError swterr) {

			throw new AeeException("Error running macro %s: %s", macroName, swterr);

		} finally {

			if (arg    != null) arg.dispose();

			if (result != null) result.dispose();

		}

	}

	

	/**

	 * Quit Excel

	 * @param ignorePrompts if true, then all alerts are ignored

	 * @throws AeeException if any SWT/COM error

	 */

	public void quit(boolean ignorePrompts) throws AeeException {

		Variant arg    = null;

		Variant result = null;

		try {

			if (ignorePrompts) {

				arg = new Variant(false);

				setProperty("DisplayAlerts", arg);

			}

		

			int[] dispMIDs = getAutomation().getIDsOfNames(new String[] {"Quit"}); 

			result         = getAutomation().invoke(dispMIDs[0]); 

			

		} finally {

			if (arg    != null) arg.dispose();

			if (result != null) result.dispose();

		}

	}

	

	/**

	 * Unit test

	 * @param args Unused

	 */

	public static void main(String[] args) {

		ExcelApplication excel      = null;

		Workbooks        workbooks  = null;

		Workbook         workbook   = null;

		Worksheets       worksheets = null;

		Worksheet        worksheet  = null;

		Cell             cell       = null;

		

		try {

			excel     = new ExcelApplication();

			workbooks = excel.getWorkbooks();

			workbook  = workbooks.open("h:\\Darpa\\j.xls");

			excel.setVisible(true);

			excel.executeMacro("UseGUI");

			worksheets   = workbook.getWorksheets();

			long nsheets = worksheets.getSheetCount();

			System.out.format("There are %d sheets%n", nsheets);

			worksheet = worksheets.getSheet("Sheet1");

			cell      = worksheet.getCell("A1");

			String cellValue = cell.getValue();

			System.out.format("The cell value is \"%s\"%n", cellValue);

			

		} catch (AeeException aeex) {

			aeex.printStackTrace();

			

		} finally {

			try {

				excel.quit(true);

			} catch (AeeException e) {

				e.printStackTrace();

			}

			if (excel      != null) excel.dispose();

			if (workbooks  != null) workbooks.dispose();

			if (workbook   != null) workbook.dispose();

			if (worksheets != null) worksheets.dispose();

			if (worksheet  != null) worksheet.dispose();

			if (cell       != null) cell.dispose();

		}

	}

}

