/**************************************************************
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 *
 *************************************************************/



package complex.dataPilot;

import com.sun.star.beans.XPropertySet;
import com.sun.star.container.XIndexAccess;
import com.sun.star.container.XNamed;
import com.sun.star.lang.XMultiServiceFactory;
// import com.sun.star.sheet.TableFilterField;
import com.sun.star.sheet.XDataPilotDescriptor;
import com.sun.star.sheet.XDataPilotTable;
import com.sun.star.sheet.XDataPilotTables;
import com.sun.star.sheet.XDataPilotTablesSupplier;
// import com.sun.star.sheet.XSheetFilterDescriptor;
import com.sun.star.sheet.XSpreadsheet;
import com.sun.star.sheet.XSpreadsheetDocument;
import com.sun.star.sheet.XSpreadsheets;
import com.sun.star.table.CellAddress;
import com.sun.star.table.CellRangeAddress;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.Type;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XInterface;
import com.sun.star.util.XCloseable;
import complex.dataPilot._XPropertySet;
import complex.dataPilot._XNamed;
import complex.dataPilot._XDataPilotDescriptor;
import complex.dataPilot._XDataPilotTable;
import lib.StatusException;
import lib.TestParameters;
import util.SOfficeFactory;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.openoffice.test.OfficeConnection;
import static org.junit.Assert.*;


/**
 * check the DataPilot of Calc.
 */
public class CheckDataPilot {
    /** The data pilot field object **/
    private XInterface mDataPilotFieldObject = null;
    /** The data pilot table object **/
    private XInterface mDataPilotTableObject = null;


    private XSpreadsheetDocument xSheetDoc = null;

    /**
     * A field is filled some values. This integer determines the size of the
     * field in x and y direction.
     */
    private int mMaxFieldIndex = 6;

    /**
     * The test parameters
     */
    private static TestParameters param = null;

    /**
     * Test the data pilot field object:
     * simply execute the interface tests in a row
     */
    @Test public void testDataPilotFieldObject() {
        System.out.println("Starting 'testDataPilotFieldObject'");
        // _XNamed
        XNamed xNamed = UnoRuntime.queryInterface(
                                    XNamed.class, mDataPilotFieldObject);

        _XNamed _xNamed = new _XNamed(xNamed/*, log*/, param);
        assertTrue("_getName failed.",_xNamed._getName());
        assertTrue("_setName failed.",_xNamed._setName());

        // _XPropertySet
        XPropertySet xProp = UnoRuntime.queryInterface(
                                    XPropertySet.class, mDataPilotFieldObject);
        _XPropertySet _xProp = new _XPropertySet(xProp/*, log*/, param);
        assertTrue("_getPropertySetInfo failed.",_xProp._getPropertySetInfo());
        assertTrue("_addPropertyChangeListener failed.",_xProp._addPropertyChangeListener());
        assertTrue("_addVetoableChangeListener failed.",_xProp._addVetoableChangeListener());
        assertTrue("_setPropertyValue failed.",_xProp._setPropertyValue());
        assertTrue("_getPropertyValue failed.",_xProp._getPropertyValue());
        assertTrue("_removePropertyChangeListener failed.",_xProp._removePropertyChangeListener());
        assertTrue("_removeVetoableChangeListener failed.",_xProp._removeVetoableChangeListener());

    }

    /**
     * Test the data pilot table object:
     * simply execute the interface tests in a row
     */
    @Test public void testDataPilotTableObject() {
        System.out.println("Starting 'testDataPilotTableObject'");
        // _XNamed
        XNamed xNamed = UnoRuntime.queryInterface(
                                    XNamed.class, mDataPilotTableObject);
        _XNamed _xNamed = new _XNamed(xNamed/*, log*/, param);
        assertTrue("_getName failed.",_xNamed._getName());
        assertTrue("_setName failed.",_xNamed._setName());

        // _XDataPilotTable
        XDataPilotTable xDataPilotTable =
                    UnoRuntime.queryInterface(XDataPilotTable.class,
                    mDataPilotTableObject);
        _XDataPilotTable _xDataPilotTable =
                    new _XDataPilotTable(xDataPilotTable/*, log*/, param);
        assertTrue("before failed.", _xDataPilotTable.before());
        assertTrue("_getOutputRange failed.", _xDataPilotTable._getOutputRange()) ;
//        assertTrue("_refresh failed.", _xDataPilotTable._refresh()) ;

        // _XDataPilotDescriptor
        XDataPilotDescriptor xDataPilotDescriptor =
                    UnoRuntime.queryInterface(XDataPilotDescriptor.class,
                    mDataPilotTableObject);
        _XDataPilotDescriptor _xDataPilotDescriptor =
                    new _XDataPilotDescriptor(xDataPilotDescriptor/*, log*/, param);
        assertTrue("before failed.", _xDataPilotDescriptor.before());
        assertTrue("_setTag failed.", _xDataPilotDescriptor._setTag()) ;
        assertTrue("_getTag failed.", _xDataPilotDescriptor._getTag()) ;
        assertTrue("_getFilterDescriptor failed.", _xDataPilotDescriptor._getFilterDescriptor()) ;
        assertTrue("_getDataPilotFields failed.", _xDataPilotDescriptor._getDataPilotFields()) ;
        assertTrue("_getColumnFields failed.", _xDataPilotDescriptor._getColumnFields()) ;
        assertTrue("_getRowFields failed.", _xDataPilotDescriptor._getRowFields()) ;
        assertTrue("_getDataFields failed.", _xDataPilotDescriptor._getDataFields()) ;
        assertTrue("_getHiddenFields failed.", _xDataPilotDescriptor._getHiddenFields()) ;
        assertTrue("_getPageFields failed.", _xDataPilotDescriptor._getPageFields()) ;
        assertTrue("_setSourceRange failed.", _xDataPilotDescriptor._setSourceRange()) ;
        assertTrue("_getSourceRange failed.", _xDataPilotDescriptor._getSourceRange()) ;
    }

    /**
     * create an environment for the test
     */
    @Before public void before() {
//        Object oInterface = null;

        final XMultiServiceFactory xMsf = UnoRuntime.queryInterface(XMultiServiceFactory.class, connection.getComponentContext().getServiceManager());
        SOfficeFactory SOF = SOfficeFactory.getFactory(xMsf);

        param = new TestParameters();
        param.put("ServiceFactory", xMsf);

        // the cell range
        CellRangeAddress sCellRangeAdress = new CellRangeAddress();
        sCellRangeAdress.Sheet = 0;
        sCellRangeAdress.StartColumn = 1;
        sCellRangeAdress.StartRow = 0;
        sCellRangeAdress.EndColumn = mMaxFieldIndex-1;
        sCellRangeAdress.EndRow = mMaxFieldIndex - 1;

        // position of the data pilot table
        CellAddress sCellAdress = new CellAddress();
        sCellAdress.Sheet = 0;
        sCellAdress.Column = 7;
        sCellAdress.Row = 8;

        try {
            System.out.println( "Creating a Spreadsheet document" );
            xSheetDoc = SOF.createCalcDoc(null);
        } catch (com.sun.star.uno.Exception e) {
            // Some exception occurred. FAILED
            e.printStackTrace();
            throw new StatusException( "Couldn't create document", e );
        }

        System.out.println("Getting a sheet");
        XSpreadsheets xSpreadsheets = xSheetDoc.getSheets();
        XSpreadsheet oSheet = null;
        XSpreadsheet oSheet2 = null;
        XIndexAccess oIndexAccess =
            UnoRuntime.queryInterface(XIndexAccess.class, xSpreadsheets);

        try {
            oSheet = (XSpreadsheet) AnyConverter.toObject(
                    new Type(XSpreadsheet.class),oIndexAccess.getByIndex(0));
            oSheet2 = (XSpreadsheet) AnyConverter.toObject(
                    new Type(XSpreadsheet.class),oIndexAccess.getByIndex(1));
        } catch (com.sun.star.lang.WrappedTargetException e) {
            e.printStackTrace();
            throw new StatusException( "Couldn't get a spreadsheet", e);
        } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
            e.printStackTrace();
            throw new StatusException( "Couldn't get a spreadsheet", e);
        } catch (com.sun.star.lang.IllegalArgumentException e) {
            e.printStackTrace();
            throw new StatusException( "Couldn't get a spreadsheet", e);
        }

        try {
            System.out.println("Filling a table");
            for (int i = 1; i < mMaxFieldIndex; i++) {
                oSheet.getCellByPosition(i, 0).setFormula("Col" + i);
                oSheet.getCellByPosition(0, i).setFormula("Row" + i);
                oSheet2.getCellByPosition(i, 0).setFormula("Col" + i);
                oSheet2.getCellByPosition(0, i).setFormula("Row" + i);
            }

            for (int i = 1; i < mMaxFieldIndex; i++)
            {
                for (int j = 1; j < mMaxFieldIndex; j++)
                {
                    oSheet.getCellByPosition(i, j).setValue(i * (j + 1));
                    oSheet2.getCellByPosition(i, j).setValue(i * (j + 2));
                }
            }
        } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
            e.printStackTrace();
            throw new StatusException("Couldn't fill some cells", e);
        }

        // change a value of a cell and check the change in the data pilot
        // (for the XDataPilotTable.refresh() test)
        Object oChangeCell = null;
        Object oCheckCell = null;
        Integer aChangeValue = null;
        try {
            // cell of data
            oChangeCell = oSheet.getCellByPosition(1, 5);
            int x = sCellAdress.Column;
            int y = sCellAdress.Row + 3;
            // cell of the data pilot output
            oCheckCell = oSheet.getCellByPosition(x, y);
            aChangeValue = new Integer(27);
        } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
            e.printStackTrace();
            throw new StatusException( "Couldn't get cells for changeing.", e);
        }


        // create the test objects
        System.out.println("Getting test objects") ;
        XDataPilotTablesSupplier DPTS =
            UnoRuntime.queryInterface(XDataPilotTablesSupplier.class, oSheet);
        XDataPilotTables DPT = DPTS.getDataPilotTables();
        XDataPilotDescriptor DPDsc = DPT.createDataPilotDescriptor();
        DPDsc.setSourceRange(sCellRangeAdress);

        XPropertySet fieldPropSet = null;
        try {
            Object oDataPilotField = DPDsc.getDataPilotFields().getByIndex(0);
            fieldPropSet =
                UnoRuntime.queryInterface(XPropertySet.class, oDataPilotField);
        } catch (com.sun.star.lang.WrappedTargetException e) {
            e.printStackTrace();
            throw new StatusException("Couldn't create a test environment", e);
        } catch(com.sun.star.lang.IndexOutOfBoundsException e) {
            e.printStackTrace();
            throw new StatusException("Couldn't create a test environment", e);
        }

        try {
            fieldPropSet.setPropertyValue("Function",
                com.sun.star.sheet.GeneralFunction.SUM);
            fieldPropSet.setPropertyValue("Orientation",
                com.sun.star.sheet.DataPilotFieldOrientation.DATA);
        } catch(com.sun.star.lang.WrappedTargetException e) {
            e.printStackTrace();
            throw new StatusException("Couldn't create a test environment", e);
        } catch(com.sun.star.lang.IllegalArgumentException e) {
            e.printStackTrace();
            throw new StatusException("Couldn't create a test environment", e);
        } catch(com.sun.star.beans.PropertyVetoException e) {
            e.printStackTrace();
            throw new StatusException("Couldn't create a test environment", e);
        } catch(com.sun.star.beans.UnknownPropertyException e) {
            e.printStackTrace();
            throw new StatusException("Couldn't create a test environment", e);
        }

        System.out.println("Insert the DataPilotTable");
        if (DPT.hasByName("DataPilotTable")) {
            DPT.removeByName("DataPilotTable");
        }
        DPT.insertNewByName("DataPilotTable", sCellAdress, DPDsc);
        try {
            mDataPilotTableObject = (XInterface) AnyConverter.toObject(
                new Type(XInterface.class),DPT.getByName(DPT.getElementNames()[0]));
        } catch (com.sun.star.lang.WrappedTargetException e) {
            e.printStackTrace();
            throw new StatusException("Couldn't create a test environment", e);
        } catch (com.sun.star.container.NoSuchElementException e) {
            e.printStackTrace();
            throw new StatusException("Couldn't create a test environment", e);
        } catch (com.sun.star.lang.IllegalArgumentException e) {
            e.printStackTrace();
            throw new StatusException("Couldn't create a test environment", e);
        }

        XIndexAccess IA = DPDsc.getDataPilotFields();
        try {
            mDataPilotFieldObject = (XInterface)AnyConverter.toObject(
                                new Type(XInterface.class),IA.getByIndex(0));
        } catch (com.sun.star.lang.WrappedTargetException e) {
            e.printStackTrace();
            throw new StatusException("Couldn't get data pilot field", e);
        } catch (com.sun.star.lang.IndexOutOfBoundsException e) {
            e.printStackTrace();
            throw new StatusException("Couldn't get data pilot field", e);
        } catch (com.sun.star.lang.IllegalArgumentException e) {
            e.printStackTrace();
            throw new StatusException("Couldn't get data pilot field", e);
        }

        // Other parameters required for interface tests
        param.put("OUTPUTRANGE", sCellAdress);
        param.put("CELLFORCHANGE", oChangeCell);
        param.put("CELLFORCHECK", oCheckCell);
        param.put("CHANGEVALUE", aChangeValue);
        param.put("FIELDSAMOUNT", new Integer(5));

    }

        /*
     * this method closes a calc document and resets the corresponding class variable xSheetDoc
     */
    protected boolean closeSpreadsheetDocument() {
        boolean worked = true;

        System.out.println("    disposing xSheetDoc ");

        try {
            XCloseable oCloser =  UnoRuntime.queryInterface(
                                         XCloseable.class, xSheetDoc);
            oCloser.close(true);
        } catch (com.sun.star.util.CloseVetoException e) {
            worked = false;
            System.out.println("Couldn't close document");
        } catch (com.sun.star.lang.DisposedException e) {
            worked = false;
            System.out.println("Document already disposed");
        } catch (java.lang.NullPointerException e) {
            worked = false;
            System.out.println("Couldn't get XCloseable");
        }

        xSheetDoc = null;

        return worked;
    }

    @After public void after()
        {
            closeSpreadsheetDocument();
        }


    @BeforeClass public static void setUpConnection() throws Exception {
        System.out.println("setUpConnection()");
        connection.setUp();
    }

    @AfterClass public static void tearDownConnection()
        throws InterruptedException, com.sun.star.uno.Exception
    {
        System.out.println("tearDownConnection()");
        connection.tearDown();
    }

    private static final OfficeConnection connection = new OfficeConnection();


}
