/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/



#include "oox/xls/pivotcachefragment.hxx"

#include "oox/helper/attributelist.hxx"
#include "oox/xls/addressconverter.hxx"
#include "oox/xls/biffinputstream.hxx"
#include "oox/xls/pivotcachebuffer.hxx"

namespace oox {
namespace xls {

// ============================================================================

using namespace ::com::sun::star::uno;
using namespace ::oox::core;

using ::rtl::OUString;

// ============================================================================

PivotCacheFieldContext::PivotCacheFieldContext( WorkbookFragmentBase& rFragment, PivotCacheField& rCacheField ) :
    WorkbookContextBase( rFragment ),
    mrCacheField( rCacheField )
{
}

ContextHandlerRef PivotCacheFieldContext::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
{
    switch( getCurrentElement() )
    {
        case XLS_TOKEN( cacheField ):
            if( nElement == XLS_TOKEN( sharedItems ) )  { mrCacheField.importSharedItems( rAttribs );   return this; }
            if( nElement == XLS_TOKEN( fieldGroup ) )   { mrCacheField.importFieldGroup( rAttribs );    return this; }
        break;

        case XLS_TOKEN( fieldGroup ):
            switch( nElement )
            {
                case XLS_TOKEN( rangePr ):      mrCacheField.importRangePr( rAttribs );     break;
                case XLS_TOKEN( discretePr ):   return this;
                case XLS_TOKEN( groupItems ):   return this;
            }
        break;

        case XLS_TOKEN( sharedItems ):  mrCacheField.importSharedItem( nElement, rAttribs );        break;
        case XLS_TOKEN( discretePr ):   mrCacheField.importDiscretePrItem( nElement, rAttribs );    break;
        case XLS_TOKEN( groupItems ):   mrCacheField.importGroupItem( nElement, rAttribs );         break;
    }
    return 0;
}

void PivotCacheFieldContext::onStartElement( const AttributeList& rAttribs )
{
    if( isRootElement() )
        mrCacheField.importCacheField( rAttribs );
}

ContextHandlerRef PivotCacheFieldContext::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
{
    switch( getCurrentElement() )
    {
        case BIFF12_ID_PCDFIELD:
            switch( nRecId )
            {
                case BIFF12_ID_PCDFSHAREDITEMS: mrCacheField.importPCDFSharedItems( rStrm );  return this;
                case BIFF12_ID_PCDFIELDGROUP:   mrCacheField.importPCDFieldGroup( rStrm );    return this;
            }
        break;

        case BIFF12_ID_PCDFIELDGROUP:
            switch( nRecId )
            {
                case BIFF12_ID_PCDFRANGEPR:     mrCacheField.importPCDFRangePr( rStrm );    break;
                case BIFF12_ID_PCDFDISCRETEPR:  return this;
                case BIFF12_ID_PCDFGROUPITEMS:  return this;
            }
        break;

        case BIFF12_ID_PCDFSHAREDITEMS: mrCacheField.importPCDFSharedItem( nRecId, rStrm );     break;
        case BIFF12_ID_PCDFDISCRETEPR:  mrCacheField.importPCDFDiscretePrItem( nRecId, rStrm ); break;
        case BIFF12_ID_PCDFGROUPITEMS:  mrCacheField.importPCDFGroupItem( nRecId, rStrm );      break;
    }
    return 0;
}

void PivotCacheFieldContext::onStartRecord( SequenceInputStream& rStrm )
{
    if( isRootElement() )
        mrCacheField.importPCDField( rStrm );
}

// ============================================================================

PivotCacheDefinitionFragment::PivotCacheDefinitionFragment(
        const WorkbookHelper& rHelper, const OUString& rFragmentPath, PivotCache& rPivotCache ) :
    WorkbookFragmentBase( rHelper, rFragmentPath ),
    mrPivotCache( rPivotCache )
{
}

ContextHandlerRef PivotCacheDefinitionFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
{
    switch( getCurrentElement() )
    {
        case XML_ROOT_CONTEXT:
            if( nElement == XLS_TOKEN( pivotCacheDefinition ) ) { mrPivotCache.importPivotCacheDefinition( rAttribs ); return this; }
        break;

        case XLS_TOKEN( pivotCacheDefinition ):
            switch( nElement )
            {
                case XLS_TOKEN( cacheSource ):  mrPivotCache.importCacheSource( rAttribs ); return this;
                case XLS_TOKEN( cacheFields ):  return this;
            }
        break;

        case XLS_TOKEN( cacheSource ):
            if( nElement == XLS_TOKEN( worksheetSource ) ) mrPivotCache.importWorksheetSource( rAttribs, getRelations() );
        break;

        case XLS_TOKEN( cacheFields ):
            if( nElement == XLS_TOKEN( cacheField ) ) return new PivotCacheFieldContext( *this, mrPivotCache.createCacheField() );
        break;
    }
    return 0;
}

ContextHandlerRef PivotCacheDefinitionFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
{
    switch( getCurrentElement() )
    {
        case XML_ROOT_CONTEXT:
            if( nRecId == BIFF12_ID_PCDEFINITION ) { mrPivotCache.importPCDefinition( rStrm ); return this; }
        break;

        case BIFF12_ID_PCDEFINITION:
            switch( nRecId )
            {
                case BIFF12_ID_PCDSOURCE: mrPivotCache.importPCDSource( rStrm ); return this;
                case BIFF12_ID_PCDFIELDS: return this;
            }
        break;

        case BIFF12_ID_PCDSOURCE:
            if( nRecId == BIFF12_ID_PCDSHEETSOURCE ) mrPivotCache.importPCDSheetSource( rStrm, getRelations() );
        break;

        case BIFF12_ID_PCDFIELDS:
            if( nRecId == BIFF12_ID_PCDFIELD ) return new PivotCacheFieldContext( *this, mrPivotCache.createCacheField() );
        break;
    }
    return 0;
}

const RecordInfo* PivotCacheDefinitionFragment::getRecordInfos() const
{
    static const RecordInfo spRecInfos[] =
    {
        { BIFF12_ID_PCDEFINITION,       BIFF12_ID_PCDEFINITION + 1      },
        { BIFF12_ID_PCDFDISCRETEPR,     BIFF12_ID_PCDFDISCRETEPR + 1    },
        { BIFF12_ID_PCDFGROUPITEMS,     BIFF12_ID_PCDFGROUPITEMS + 1    },
        { BIFF12_ID_PCDFIELD,           BIFF12_ID_PCDFIELD + 1          },
        { BIFF12_ID_PCDFIELDGROUP,      BIFF12_ID_PCDFIELDGROUP + 1     },
        { BIFF12_ID_PCDFIELDS,          BIFF12_ID_PCDFIELDS + 1         },
        { BIFF12_ID_PCDFRANGEPR,        BIFF12_ID_PCDFRANGEPR + 1       },
        { BIFF12_ID_PCDFSHAREDITEMS,    BIFF12_ID_PCDFSHAREDITEMS + 1   },
        { BIFF12_ID_PCITEM_ARRAY,       BIFF12_ID_PCITEM_ARRAY + 1      },
        { BIFF12_ID_PCDSHEETSOURCE,     BIFF12_ID_PCDSHEETSOURCE + 1    },
        { BIFF12_ID_PCDSOURCE,          BIFF12_ID_PCDSOURCE + 1         },
        { -1,                           -1                              }
    };
    return spRecInfos;
}

void PivotCacheDefinitionFragment::finalizeImport()
{
    // finalize the cache (check source range etc.)
    mrPivotCache.finalizeImport();

    // load the cache records, if the cache is based on a deleted or an external worksheet
    if( mrPivotCache.isValidDataSource() && mrPivotCache.isBasedOnDummySheet() )
    {
        OUString aRecFragmentPath = getRelations().getFragmentPathFromRelId( mrPivotCache.getRecordsRelId() );
        if( aRecFragmentPath.getLength() > 0 )
        {
            sal_Int16 nSheet = mrPivotCache.getSourceRange().Sheet;
            WorksheetGlobalsRef xSheetGlob = WorksheetHelper::constructGlobals( *this, ISegmentProgressBarRef(), SHEETTYPE_WORKSHEET, nSheet );
            if( xSheetGlob.get() )
                importOoxFragment( new PivotCacheRecordsFragment( *xSheetGlob, aRecFragmentPath, mrPivotCache ) );
        }
    }
}

// ============================================================================

PivotCacheRecordsFragment::PivotCacheRecordsFragment( const WorksheetHelper& rHelper,
        const OUString& rFragmentPath, const PivotCache& rPivotCache ) :
    WorksheetFragmentBase( rHelper, rFragmentPath ),
    mrPivotCache( rPivotCache ),
    mnColIdx( 0 ),
    mnRowIdx( 0 ),
    mbInRecord( false )
{
    // prepare sheet: insert column header names into top row
    rPivotCache.writeSourceHeaderCells( *this );
}

ContextHandlerRef PivotCacheRecordsFragment::onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs )
{
    switch( getCurrentElement() )
    {
        case XML_ROOT_CONTEXT:
            if( nElement == XLS_TOKEN( pivotCacheRecords ) ) return this;
        break;

        case XLS_TOKEN( pivotCacheRecords ):
            if( nElement == XLS_TOKEN( r ) ) { startCacheRecord(); return this; }
        break;

        case XLS_TOKEN( r ):
        {
            PivotCacheItem aItem;
            switch( nElement )
            {
                case XLS_TOKEN( m ):                                                        break;
                case XLS_TOKEN( s ):    aItem.readString( rAttribs );                       break;
                case XLS_TOKEN( n ):    aItem.readNumeric( rAttribs );                      break;
                case XLS_TOKEN( d ):    aItem.readDate( rAttribs );                         break;
                case XLS_TOKEN( b ):    aItem.readBool( rAttribs );                         break;
                case XLS_TOKEN( e ):    aItem.readError( rAttribs, getUnitConverter() );    break;
                case XLS_TOKEN( x ):    aItem.readIndex( rAttribs );                        break;
                default:    OSL_ENSURE( false, "PivotCacheRecordsFragment::onCreateContext - unexpected element" );
            }
            mrPivotCache.writeSourceDataCell( *this, mnColIdx, mnRowIdx, aItem );
            ++mnColIdx;
        }
        break;
    }
    return 0;
}

ContextHandlerRef PivotCacheRecordsFragment::onCreateRecordContext( sal_Int32 nRecId, SequenceInputStream& rStrm )
{
    switch( getCurrentElement() )
    {
        case XML_ROOT_CONTEXT:
            if( nRecId == BIFF12_ID_PCRECORDS ) return this;
        break;

        case BIFF12_ID_PCRECORDS:
            switch( nRecId )
            {
                case BIFF12_ID_PCRECORD:    importPCRecord( rStrm );                break;
                case BIFF12_ID_PCRECORDDT:  startCacheRecord();                     break;
                default:                    importPCRecordItem( nRecId, rStrm );    break;
            }
        break;
    }
    return 0;
}

const RecordInfo* PivotCacheRecordsFragment::getRecordInfos() const
{
    static const RecordInfo spRecInfos[] =
    {
        { BIFF12_ID_PCRECORDS,  BIFF12_ID_PCRECORDS + 1 },
        { -1,                   -1                      }
    };
    return spRecInfos;
}

// private --------------------------------------------------------------------

void PivotCacheRecordsFragment::startCacheRecord()
{
    mnColIdx = 0;
    ++mnRowIdx;
    mbInRecord = true;
}

void PivotCacheRecordsFragment::importPCRecord( SequenceInputStream& rStrm )
{
    startCacheRecord();
    mrPivotCache.importPCRecord( rStrm, *this, mnRowIdx );
    mbInRecord = false;
}

void PivotCacheRecordsFragment::importPCRecordItem( sal_Int32 nRecId, SequenceInputStream& rStrm )
{
    if( mbInRecord )
    {
        PivotCacheItem aItem;
        switch( nRecId )
        {
            case BIFF12_ID_PCITEM_MISSING:                              break;
            case BIFF12_ID_PCITEM_STRING:   aItem.readString( rStrm );  break;
            case BIFF12_ID_PCITEM_DOUBLE:   aItem.readDouble( rStrm );  break;
            case BIFF12_ID_PCITEM_DATE:     aItem.readDate( rStrm );    break;
            case BIFF12_ID_PCITEM_BOOL:     aItem.readBool( rStrm );    break;
            case BIFF12_ID_PCITEM_ERROR:    aItem.readError( rStrm );   break;
            case BIFF12_ID_PCITEM_INDEX:    aItem.readIndex( rStrm );   break;
            default:    OSL_ENSURE( false, "PivotCacheRecordsFragment::importPCRecordItem - unexpected record" );
        }
        mrPivotCache.writeSourceDataCell( *this, mnColIdx, mnRowIdx, aItem );
        ++mnColIdx;
    }
}

// ============================================================================
// ============================================================================

namespace {

bool lclSeekToPCDField( BiffInputStream& rStrm )
{
    sal_Int64 nRecHandle = rStrm.getRecHandle();
    while( rStrm.startNextRecord() )
        if( rStrm.getRecId() == BIFF_ID_PCDFIELD )
            return true;
    rStrm.startRecordByHandle( nRecHandle );
    return false;
}

} // namespace

// ----------------------------------------------------------------------------

BiffPivotCacheFragment::BiffPivotCacheFragment(
        const WorkbookHelper& rHelper, const OUString& rStrmName, PivotCache& rPivotCache ) :
    BiffWorkbookFragmentBase( rHelper, rStrmName, true ),
    mrPivotCache( rPivotCache )
{
}

bool BiffPivotCacheFragment::importFragment()
{
    BiffInputStream& rStrm = getInputStream();
    if( rStrm.startNextRecord() && (rStrm.getRecId() == BIFF_ID_PCDEFINITION) )
    {
        // read PCDEFINITION and optional PCDEFINITION2 records
        mrPivotCache.importPCDefinition( rStrm );

        // read cache fields as long as another PCDFIELD record can be found
        while( lclSeekToPCDField( rStrm ) )
            mrPivotCache.createCacheField( true ).importPCDField( rStrm );

        // finalize the cache (check source range etc.)
        mrPivotCache.finalizeImport();

        // load the cache records, if the cache is based on a deleted or an external worksheet
        if( mrPivotCache.isValidDataSource() && mrPivotCache.isBasedOnDummySheet() )
        {
            /*  Last call of lclSeekToPCDField() failed and kept stream position
                unchanged. Stream should point to source data table now. */
            sal_Int16 nSheet = mrPivotCache.getSourceRange().Sheet;
            WorksheetGlobalsRef xSheetGlob = WorksheetHelper::constructGlobals( *this, ISegmentProgressBarRef(), SHEETTYPE_WORKSHEET, nSheet );
            if( xSheetGlob.get() )
            {
                BiffPivotCacheRecordsContext aContext( *xSheetGlob, mrPivotCache );
                while( rStrm.startNextRecord() && (rStrm.getRecId() != BIFF_ID_EOF) )
                    aContext.importRecord( rStrm );
            }
        }
    }

    return rStrm.getRecId() == BIFF_ID_EOF;
}

// ============================================================================

BiffPivotCacheRecordsContext::BiffPivotCacheRecordsContext( const WorksheetHelper& rHelper, const PivotCache& rPivotCache ) :
    BiffWorksheetContextBase( rHelper ),
    mrPivotCache( rPivotCache ),
    mnColIdx( 0 ),
    mnRowIdx( 0 ),
    mbHasShared( false ),
    mbInRow( false )
{
    // prepare sheet: insert column header names into top row
    mrPivotCache.writeSourceHeaderCells( *this );

    // find all fields without shared items, remember column indexes in source data
    for( sal_Int32 nFieldIdx = 0, nFieldCount = mrPivotCache.getCacheFieldCount(), nCol = 0; nFieldIdx < nFieldCount; ++nFieldIdx )
    {
        const PivotCacheField* pCacheField = mrPivotCache.getCacheField( nFieldIdx );
        if( pCacheField && pCacheField->isDatabaseField() )
        {
            if( pCacheField->hasSharedItems() )
                mbHasShared = true;
            else
                maUnsharedCols.push_back( nCol );
            ++nCol;
        }
    }
}

void BiffPivotCacheRecordsContext::importRecord( BiffInputStream& rStrm )
{
    if( rStrm.getRecId() == BIFF_ID_PCITEM_INDEXLIST )
    {
        OSL_ENSURE( mbHasShared, "BiffPivotCacheRecordsContext::importRecord - unexpected PCITEM_INDEXLIST record" );
        // PCITEM_INDEXLIST record always in front of a new data row
        startNextRow();
        mrPivotCache.importPCItemIndexList( rStrm, *this, mnRowIdx );
        mbInRow = !maUnsharedCols.empty();  // mbInRow remains true, if unshared items are expected
        return;
    }

    PivotCacheItem aItem;
    switch( rStrm.getRecId() )
    {
        case BIFF_ID_PCITEM_MISSING:                                        break;
        case BIFF_ID_PCITEM_STRING:     aItem.readString( rStrm, *this );   break;
        case BIFF_ID_PCITEM_DOUBLE:     aItem.readDouble( rStrm );          break;
        case BIFF_ID_PCITEM_INTEGER:    aItem.readInteger( rStrm );         break;
        case BIFF_ID_PCITEM_DATE:       aItem.readDate( rStrm );            break;
        case BIFF_ID_PCITEM_BOOL:       aItem.readBool( rStrm );            break;
        case BIFF_ID_PCITEM_ERROR:      aItem.readError( rStrm );           break;
        default:                        return; // unknown record, ignore
    }

    // find next column index, might start new row if no fields with shared items exist
    if( mbInRow && (mnColIdx == maUnsharedCols.size()) )
    {
        OSL_ENSURE( !mbHasShared, "BiffPivotCacheRecordsContext::importRecord - PCITEM_INDEXLIST record missing" );
        mbInRow = mbHasShared;  // do not leave current row if PCITEM_INDEXLIST is expected
    }
    // start next row on first call, or on row wrap without shared items
    if( !mbInRow )
        startNextRow();

    // write the item data to the sheet cell
    OSL_ENSURE( mnColIdx < maUnsharedCols.size(), "BiffPivotCacheRecordsContext::importRecord - invalid column index" );
    if( mnColIdx < maUnsharedCols.size() )
        mrPivotCache.writeSourceDataCell( *this, maUnsharedCols[ mnColIdx ], mnRowIdx, aItem );
    ++mnColIdx;
}

void BiffPivotCacheRecordsContext::startNextRow()
{
    mnColIdx = 0;
    ++mnRowIdx;
    mbInRow = true;
}

// ============================================================================

} // namespace xls
} // namespace oox
