/**************************************************************
 * 
 * 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 ifc.sheet;

import java.util.ArrayList;

import com.sun.star.beans.XPropertySet;
import com.sun.star.container.XIndexAccess;
import com.sun.star.container.XNamed;
import com.sun.star.lang.IllegalArgumentException;
import com.sun.star.sheet.*;
import com.sun.star.table.CellAddress;
import com.sun.star.table.CellRangeAddress;
import com.sun.star.table.XCell;
import com.sun.star.table.XCellCursor;
import com.sun.star.table.XCellRange;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.UnoRuntime;

import lib.MultiMethodTest;
import lib.Status;
import lib.StatusException;

/** 
 * Testing <code>com.sun.star.sheet.XDataPilotTable2</code>
 * interface methods :
 * <ul>
 *  <li><code> getDrillDownData()</code><li>
 *  <li><code> getPositionData()</code></li>
 *  <li><code> insertDrillDownSheet()</code></li>
 *  <li><code> getOutputRangeByType</code></li>
 * </ul>
 * 
 * @see com.sun.star.sheet.XDataPilotTable2
 * @see com.sun.star.table.CellAddress
 * 
 */
public class _XDataPilotTable2 extends MultiMethodTest 
{
    private XSpreadsheetDocument xSheetDoc = null;
    private XDataPilotTable2 xDPTab2 = null;
    private CellRangeAddress mRangeWhole = null;
    private CellRangeAddress mRangeTable = null;
    private CellRangeAddress mRangeResult = null;
    private ArrayList mDataFieldDims = null;
    private ArrayList mResultCells = null;

    /** 
     * exception to be thrown when obtaining a result data for a cell fails
     * (probably because the cell is not a result cell).
     */
    private class ResultCellFailure extends com.sun.star.uno.Exception {}

    protected void before() 
    {
        Object o = tEnv.getObjRelation("DATAPILOTTABLE2");
        xDPTab2 = (XDataPilotTable2)UnoRuntime.queryInterface(
            XDataPilotTable2.class, o);

        if (xDPTab2 == null)
            throw new StatusException(Status.failed("Relation not found"));

        xSheetDoc = (XSpreadsheetDocument)tEnv.getObjRelation("SHEETDOCUMENT");

        getOutputRanges();
        buildDataFields();
        try
        {
            buildResultCells();
        }
        catch (ResultCellFailure e)
        {
            e.printStackTrace(log);
            throw new StatusException( "Failed to build result cells.", e);
        }
    }

    public void _getDrillDownData() 
    {
        boolean testResult = true;
        int cellCount = mResultCells.size();
        for (int i = 0; i < cellCount; ++i)
        {
            CellAddress addr = (CellAddress)mResultCells.get(i);
            DataPilotTablePositionData posData = xDPTab2.getPositionData(addr);
            DataPilotTableResultData resData = (DataPilotTableResultData)posData.PositionData;
            int dim = ((Integer)mDataFieldDims.get(resData.DataFieldIndex)).intValue();
            DataResult res = resData.Result;
            double val = res.Value;

            Object[][] data = xDPTab2.getDrillDownData(addr);
            double sum = 0.0;
            if (data.length > 1)
            {
                for (int row = 1; row < data.length; ++row)
                {
                    Object o = data[row][dim];
                    if (AnyConverter.isDouble(o))
                        sum += ((Double)o).doubleValue();
                }
            }
            log.println(formatCell(addr) + ": " + data.length + " rows (" + (data.length-1) + " records)");

            if (val != sum)
                testResult = false;
        }
        tRes.tested("getDrillDownData()", testResult);
    }

    public void _getPositionData() 
    {
        boolean testResult = false;

        do
        {
            CellAddress addr = new CellAddress();
            addr.Sheet  = mRangeTable.Sheet;

            boolean rangeGood = true;
            for (int x = mRangeTable.StartColumn; x <= mRangeTable.EndColumn && rangeGood; ++x)
            {
                for (int y = mRangeTable.StartRow; y <= mRangeTable.EndRow && rangeGood; ++y)
                {
                    addr.Column = x;
                    addr.Row = y;
                    log.println("checking " + formatCell(addr));
                    DataPilotTablePositionData posData = xDPTab2.getPositionData(addr);
                    if (posData.PositionType == DataPilotTablePositionType.NOT_IN_TABLE)
                    {
                        log.println("specified cell address not in table: " + formatCell(addr));
                        rangeGood = false;
                        continue;
                    }

                    switch (posData.PositionType)
                    {
                    case DataPilotTablePositionType.NOT_IN_TABLE:
                        break;
                    case DataPilotTablePositionType.COLUMN_HEADER:
                        printHeaderData(posData);
                        break;
                    case DataPilotTablePositionType.ROW_HEADER:
                        printHeaderData(posData);
                        break;
                    case DataPilotTablePositionType.RESULT:
                        printResultData(posData);
                        break;
                    case DataPilotTablePositionType.OTHER:
                        break;
                    default:
                        log.println("unknown position");
                    }
                }
            }

            if (!rangeGood)
            {
                log.println("table range check failed");
                break;
            }

            testResult = true;
        }
        while (false);

        tRes.tested("getPositionData()", testResult);
    }

    public void _insertDrillDownSheet() 
    {
        boolean testResult = true;
        int cellCount = mResultCells.size();
        XSpreadsheets xSheets = xSheetDoc.getSheets();
        XIndexAccess xIA = (XIndexAccess)UnoRuntime.queryInterface(
            XIndexAccess.class, xSheets);
        int sheetCount = xIA.getCount();
        for (int i = 0; i < cellCount && testResult; ++i)
        {
            CellAddress addr = (CellAddress)mResultCells.get(i);

            Object[][] data = xDPTab2.getDrillDownData(addr);

            // sheet is always inserted at the current sheet position.
            xDPTab2.insertDrillDownSheet(addr);

            int newSheetCount = xIA.getCount();
            if (newSheetCount == sheetCount + 1)
            {
                log.println("drill-down sheet for " + formatCell(addr) + " inserted");
                if (data.length < 2)
                {
                    // There is no data for this result.  It should never have
                    // inserted a drill-down sheet.
                    log.println("new sheet inserted; however, there is no data for this result");
                    testResult = false;
                    continue;
                }

                // Retrieve the object of the sheet just inserted.
                XSpreadsheet xSheet = null;
                try
                {
                    xSheet = (XSpreadsheet)UnoRuntime.queryInterface(
                        XSpreadsheet.class, xIA.getByIndex(addr.Sheet));
                }
                catch (com.sun.star.uno.Exception e)
                {
                    e.printStackTrace();
                    throw new StatusException("Failed to get the spreadsheet object.", e);
                }

                // Check the integrity of the data on the inserted sheet.
                if (!checkDrillDownSheetContent(xSheet, data))
                {
                    log.println("dataintegrity check on the inserted sheet failed");
                    testResult = false;
                    continue;
                }

                log.println("  sheet data integrity check passed");

                // Remove the sheet just inserted.

                XNamed xNamed = (XNamed)UnoRuntime.queryInterface(XNamed.class, xSheet);
                String name = xNamed.getName();
                try
                {
                    xSheets.removeByName(name);    
                }
                catch (com.sun.star.uno.Exception e)
                {
                    e.printStackTrace();
                    throw new StatusException("Failed to removed the inserted sheet named " + name + ".", e);
                }
            }
            else if (newSheetCount == sheetCount)
            {
                if (data.length > 1)
                {
                    // There is data for this result.  It should have inserted
                    // a new sheet.
                    log.println("no new sheet is inserted, despite the data being present.");
                    testResult = false;
                }
            }
            else
            {
                log.println("what just happened!?");
                testResult = false;
            }
        }

        tRes.tested("insertDrillDownSheet()", testResult);
    }

    public void _getOutputRangeByType() 
    {
        boolean testResult = false;

        do
        {
            // Let's make sure this doesn't cause a crash.  A range returned for an 
            // out-of-bound condition is undefined.
            try
            {
                CellRangeAddress rangeOutOfBound = xDPTab2.getOutputRangeByType(-1);
                log.println("exception not raised");
                break;
            }
            catch (IllegalArgumentException e)
            {
                log.println("exception raised on invalid range type (good)");
            }

            try
            {
                CellRangeAddress rangeOutOfBound = xDPTab2.getOutputRangeByType(100);
                log.println("exception not raised");
                break;
            }
            catch (IllegalArgumentException e)
            {
                log.println("exception raised on invalid range type (good)");
            }

            // Check to make sure the whole range is not empty.
            if (mRangeWhole.EndColumn - mRangeWhole.StartColumn <= 0 || 
                mRangeWhole.EndRow - mRangeWhole.EndColumn <= 0)
            {
                log.println("whole range is empty");
                break;
            }

            log.println("whole range is not empty (good)");

            // Table range must be of equal width with the whole range, and the same
            // bottom.
            if (mRangeTable.Sheet != mRangeWhole.Sheet ||
                mRangeTable.StartColumn != mRangeWhole.StartColumn ||
                mRangeTable.EndColumn != mRangeWhole.EndColumn ||
                mRangeTable.EndRow != mRangeWhole.EndRow)
            {
                log.println("table range is incorrect");
                break;
            }

            log.println("table range is correct");

            // Result range must be smaller than the table range, and must share the
            // same lower-right corner.
            if (mRangeResult.Sheet != mRangeTable.Sheet ||
                mRangeResult.StartColumn < mRangeTable.StartColumn ||
                mRangeResult.StartRow < mRangeTable.StartRow ||
                mRangeResult.EndColumn != mRangeTable.EndColumn ||
                mRangeResult.EndRow != mRangeTable.EndRow)
                break;

            log.println("result range is correct");

            testResult = true;
        }
        while (false);

        tRes.tested("getOutputRangeByType()", testResult);
    }

    private void printHeaderData(DataPilotTablePositionData posData)
    {
        DataPilotTableHeaderData header = (DataPilotTableHeaderData)posData.PositionData;
        String posType = "";
        if (posData.PositionType == DataPilotTablePositionType.COLUMN_HEADER)
            posType = "column header";
        else if (posData.PositionType == DataPilotTablePositionType.ROW_HEADER)
            posType = "row header";

        log.println(posType + "; member name: " + header.MemberName + "; dimension: " + 
                    header.Dimension + "; hierarchy: " + header.Hierarchy + 
                    "; level: " + header.Level);
    }

    private void printResultData(DataPilotTablePositionData posData)
    {
        DataPilotTableResultData resultData = (DataPilotTableResultData)posData.PositionData;
        int dataId = resultData.DataFieldIndex;
        DataResult res = resultData.Result;
        double val = res.Value;
        int flags = res.Flags;
        int filterCount = resultData.FieldFilters.length;
        log.println("result; data field index: " + dataId + "; value: " + val + "; flags: " + flags + 
                    "; filter count: " + filterCount);

        for (int i = 0; i < filterCount; ++i)
        {
            DataPilotFieldFilter fil = resultData.FieldFilters[i];
            log.println("  field name: " + fil.FieldName + "; match value: " + fil.MatchValue);
        }
    }

    private String formatCell(CellAddress addr)
    {
        String str = "(" + addr.Column + "," + addr.Row + ")";
        return str;
    }

    private void printRange(String text, CellRangeAddress rangeAddr)
    {
        log.println(text + ": (" + rangeAddr.StartColumn + "," + rangeAddr.StartRow + ") - (" +
                    rangeAddr.EndColumn + "," + rangeAddr.EndRow + ")");
    }

    private void buildResultCells() throws ResultCellFailure
    {
        if (mResultCells != null)
            return;

        getOutputRanges();

        mResultCells = new ArrayList();
        for (int x = mRangeResult.StartColumn; x <= mRangeResult.EndColumn; ++x)
        {
            for (int y = mRangeResult.StartRow; y <= mRangeResult.EndRow; ++y)
            {
                CellAddress addr = new CellAddress();
                addr.Sheet = mRangeResult.Sheet;
                addr.Column = x;
                addr.Row = y;
                DataPilotTablePositionData posData = xDPTab2.getPositionData(addr);
                if (posData.PositionType != DataPilotTablePositionType.RESULT)
                {
                    log.println(formatCell(addr) + ": this is not a result cell");
                    throw new ResultCellFailure();
                }
                mResultCells.add(addr);
            }
        }
    }

    private void buildDataFields()
    {
        mDataFieldDims = new ArrayList();
        XDataPilotDescriptor xDesc = (XDataPilotDescriptor)UnoRuntime.queryInterface(
            XDataPilotDescriptor.class, xDPTab2);

        XIndexAccess xFields = xDesc.getDataPilotFields();
        int fieldCount = xFields.getCount();
        for (int i = 0; i < fieldCount; ++i)
        {
            try
            {
                Object field = xFields.getByIndex(i);
                XPropertySet propSet = (XPropertySet)UnoRuntime.queryInterface(
                    XPropertySet.class, field);
                DataPilotFieldOrientation orient = 
                    (DataPilotFieldOrientation)propSet.getPropertyValue("Orientation");
                if (orient == DataPilotFieldOrientation.DATA)
                {
                    Integer item = new Integer(i);
                    mDataFieldDims.add(item);
                }
            }
            catch (com.sun.star.uno.Exception e)
            {
                e.printStackTrace(log);
                throw new StatusException( "Failed to get a field.", e);
            }
        }
    }

    private void getOutputRanges()
    {
        if (mRangeWhole != null && mRangeTable != null && mRangeResult != null)
            return;

        try
        {
            mRangeWhole = xDPTab2.getOutputRangeByType(DataPilotOutputRangeType.WHOLE);
            printRange("whole range ", mRangeWhole);
            mRangeTable = xDPTab2.getOutputRangeByType(DataPilotOutputRangeType.TABLE);
            printRange("table range ", mRangeTable);
            mRangeResult = xDPTab2.getOutputRangeByType(DataPilotOutputRangeType.RESULT);
            printRange("result range", mRangeResult);
        }
        catch (IllegalArgumentException e)
        {
            e.printStackTrace(log);
            throw new StatusException( "Failed to get output range by type.", e);
        }
    }

    private boolean checkDrillDownSheetContent(XSpreadsheet xSheet, Object[][] data)
    {
        CellAddress lastCell = getLastUsedCellAddress(xSheet, 0, 0);
        if (data.length <= 0 || lastCell.Row == 0 || lastCell.Column == 0)
        {
            log.println("empty data condition");
            return false;
        }

        if (data.length != lastCell.Row + 1 || data[0].length != lastCell.Column + 1)
        {
            log.println("data size differs");
            return false;
        }

        XCellRange xCR = null;
        try
        {
            xCR = xSheet.getCellRangeByPosition(0, 0, lastCell.Column, lastCell.Row);
        }
        catch (com.sun.star.lang.IndexOutOfBoundsException e)
        {
            return false;
        }

        XCellRangeData xCRD = (XCellRangeData)UnoRuntime.queryInterface(
            XCellRangeData.class, xCR);

        Object[][] sheetData = xCRD.getDataArray();
        for (int x = 0; x < sheetData.length; ++x)
        {
            for (int y = 0; y < sheetData[x].length; ++y)
            {
                Object cell1 = sheetData[x][y];
                Object cell2 = data[x][y];
                if (AnyConverter.isString(cell1) && AnyConverter.isString(cell2))
                {
                    String s1 = (String)cell1, s2 = (String)(cell2);
                    if (!s1.equals(s2))
                    {
                        log.println("string cell values differ");
                        return false;
                    }
                }
                else if (AnyConverter.isDouble(cell1) && AnyConverter.isDouble(cell2))
                {
                    double f1 = 0.0, f2 = 0.0;
                    try
                    {
                        f1 = AnyConverter.toDouble(cell1);
                        f2 = AnyConverter.toDouble(cell2);
                    }
                    catch (com.sun.star.lang.IllegalArgumentException e)
                    {
                        log.println("failed to convert cells to double");
                        return false;
                    }

                    if (f1 != f2)
                    {
                        log.println("numerical cell values differ");
                        return false;
                    }
                }
                else
                {
                    log.println("cell types differ");
                    return false;
                }
            }
        }

        return true;
    }

    private CellAddress getLastUsedCellAddress(XSpreadsheet xSheet, int nCol, int nRow)
    {
        try
        {
            XCellRange xRng = xSheet.getCellRangeByPosition(nCol, nRow, nCol, nRow);
            XSheetCellRange xSCR = (XSheetCellRange)UnoRuntime.queryInterface(
                XSheetCellRange.class, xRng);          

            XSheetCellCursor xCursor = xSheet.createCursorByRange(xSCR);
            XCellCursor xCellCursor = (XCellCursor)UnoRuntime.queryInterface(
                XCellCursor.class, xCursor);

            xCellCursor.gotoEnd();
            XCell xCell = xCursor.getCellByPosition(0, 0);
            XCellAddressable xCellAddr = (XCellAddressable)UnoRuntime.queryInterface(
                XCellAddressable.class, xCell);

            return xCellAddr.getCellAddress();
        }
        catch (com.sun.star.lang.IndexOutOfBoundsException ex)
        {
        }
        return null;
    }
}

