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



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

#include "dpdimsave.hxx"
#include "dpgroup.hxx"
#include "dpobject.hxx"
#include "document.hxx"

#include <com/sun/star/sheet/DataPilotFieldGroupBy.hpp>

#include <svl/zforlist.hxx>
#include <tools/debug.hxx>
#include <rtl/math.hxx>
#include <algorithm>

#include "global.hxx"
#include "scresid.hxx"
#include "globstr.hrc"

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

ScDPSaveGroupItem::ScDPSaveGroupItem( const String& rName ) :
    aGroupName( rName )
{
}

ScDPSaveGroupItem::~ScDPSaveGroupItem()
{
}

void ScDPSaveGroupItem::AddElement( const String& rName )
{
    aElements.push_back( rName );
}

void ScDPSaveGroupItem::AddElementsFromGroup( const ScDPSaveGroupItem& rGroup )
{
    // add all elements of the other group (used for nested grouping)

    for ( std::vector<String>::const_iterator aIter(rGroup.aElements.begin());
                                aIter != rGroup.aElements.end(); aIter++ )
        aElements.push_back( *aIter );
}

bool ScDPSaveGroupItem::RemoveElement( const String& rName )
{
    for ( std::vector<String>::iterator aIter(aElements.begin()); aIter != aElements.end(); aIter++ )
        if ( *aIter == rName )          //! ignore case
        {
            aElements.erase( aIter );   // found -> remove
            return true;                // don't have to look further
        }

    return false;   // not found
}

bool ScDPSaveGroupItem::IsEmpty() const
{
    return aElements.empty();
}

size_t ScDPSaveGroupItem::GetElementCount() const
{
    return aElements.size();
}

const String* ScDPSaveGroupItem::GetElementByIndex( size_t nIndex ) const
{
    return (nIndex < aElements.size()) ? &aElements[ nIndex ] : 0;
}

void ScDPSaveGroupItem::Rename( const String& rNewName )
{
    aGroupName = rNewName;
}

void ScDPSaveGroupItem::RemoveElementsFromGroups( ScDPSaveGroupDimension& rDimension ) const
{
    // remove this group's elements from their groups in rDimension
    // (rDimension must be a different dimension from the one which contains this)

    for ( std::vector<String>::const_iterator aIter(aElements.begin()); aIter != aElements.end(); aIter++ )
        rDimension.RemoveFromGroups( *aIter );
}

void ScDPSaveGroupItem::AddToData( ScDPGroupDimension& rDataDim, SvNumberFormatter* pFormatter ) const
{
    ScDPGroupItem aGroup( aGroupName );
    ScDPItemData aData;

    for ( std::vector<String>::const_iterator aIter(aElements.begin()); aIter != aElements.end(); aIter++ )
    {
        sal_uInt32 nFormat = 0;      //! ...
        double fValue;
        if ( pFormatter->IsNumberFormat( *aIter, nFormat, fValue ) )
            aData = ScDPItemData( *aIter, fValue, sal_True );
        else
            aData.SetString( *aIter );

        aGroup.AddElement( aData );
        //! for numeric data, look at source members?
    }

    rDataDim.AddItem( aGroup );
}

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

ScDPSaveGroupDimension::ScDPSaveGroupDimension( const String& rSource, const String& rName ) :
    aSourceDim( rSource ),
    aGroupDimName( rName ),
    nDatePart( 0 )
{
}

ScDPSaveGroupDimension::ScDPSaveGroupDimension( const String& rSource, const String& rName, const ScDPNumGroupInfo& rDateInfo, sal_Int32 nPart ) :
    aSourceDim( rSource ),
    aGroupDimName( rName ),
    aDateInfo( rDateInfo ),
    nDatePart( nPart )
{
}

ScDPSaveGroupDimension::~ScDPSaveGroupDimension()
{
}

void ScDPSaveGroupDimension::SetDateInfo( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart )
{
    aDateInfo = rInfo;
    nDatePart = nPart;
}

void ScDPSaveGroupDimension::AddGroupItem( const ScDPSaveGroupItem& rItem )
{
    aGroups.push_back( rItem );
}

String ScDPSaveGroupDimension::CreateGroupName( const String& rPrefix )
{
    // create a name for a new group, using "Group1", "Group2" etc. (translated prefix in rPrefix)

    //! look in all dimensions, to avoid clashes with automatic groups (=name of base element)?
    //! (only dimensions for the same base)

    sal_Int32 nAdd = 1;                                 // first try is "Group1"
    const sal_Int32 nMaxAdd = nAdd + aGroups.size();    // limit the loop
    while ( nAdd <= nMaxAdd )
    {
        String aGroupName( rPrefix );
        aGroupName.Append( String::CreateFromInt32( nAdd ) );
        bool bExists = false;

        // look for existing groups
        for ( ScDPSaveGroupItemVec::const_iterator aIter(aGroups.begin());
                                    aIter != aGroups.end() && !bExists; aIter++ )
            if ( aIter->GetGroupName() == aGroupName )         //! ignore case
                bExists = true;

        if ( !bExists )
            return aGroupName;          // found a new name

        ++nAdd;                         // continue with higher number
    }

    DBG_ERROR("CreateGroupName: no valid name found");
    return EMPTY_STRING;
}

const ScDPSaveGroupItem* ScDPSaveGroupDimension::GetNamedGroup( const String& rGroupName ) const
{
    return const_cast< ScDPSaveGroupDimension* >( this )->GetNamedGroupAcc( rGroupName );
}

ScDPSaveGroupItem* ScDPSaveGroupDimension::GetNamedGroupAcc( const String& rGroupName )
{
    for ( ScDPSaveGroupItemVec::iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
        if ( aIter->GetGroupName() == rGroupName )         //! ignore case
            return &*aIter;

    return NULL;        // none found
}

long ScDPSaveGroupDimension::GetGroupCount() const
{
    return aGroups.size();
}

const ScDPSaveGroupItem* ScDPSaveGroupDimension::GetGroupByIndex( long nIndex ) const
{
    return const_cast< ScDPSaveGroupDimension* >( this )->GetGroupAccByIndex( nIndex );
}

ScDPSaveGroupItem* ScDPSaveGroupDimension::GetGroupAccByIndex( long nIndex )
{
    return &aGroups[nIndex];
}

void ScDPSaveGroupDimension::RemoveFromGroups( const String& rItemName )
{
    //  if the item is in any group, remove it from the group,
    //  also remove the group if it is empty afterwards

    for ( ScDPSaveGroupItemVec::iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
        if ( aIter->RemoveElement( rItemName ) )
        {
            if ( aIter->IsEmpty() )         // removed last item from the group?
                aGroups.erase( aIter );     // then remove the group

            return;     // don't have to look further
        }
}

void ScDPSaveGroupDimension::RemoveGroup( const String& rGroupName )
{
    for ( ScDPSaveGroupItemVec::iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
        if ( aIter->GetGroupName() == rGroupName )          //! ignore case
        {
            aGroups.erase( aIter );
            return;                     // don't have to look further
        }
}

bool ScDPSaveGroupDimension::IsEmpty() const
{
    return aGroups.empty();
}

bool ScDPSaveGroupDimension::HasOnlyHidden( const ScStrCollection& rVisible )
{
    // check if there are only groups that don't appear in the list of visible names

    bool bAllHidden = true;
    for ( ScDPSaveGroupItemVec::const_iterator aIter(aGroups.begin()); aIter != aGroups.end() && bAllHidden; aIter++ )
    {
        StrData aSearch( aIter->GetGroupName() );
        sal_uInt16 nCollIndex;
        if ( rVisible.Search( &aSearch, nCollIndex ) )
            bAllHidden = false;                             // found one that is visible
    }
    return bAllHidden;
}

void ScDPSaveGroupDimension::Rename( const String& rNewName )
{
    aGroupDimName = rNewName;
}

void ScDPSaveGroupDimension::AddToData( ScDPGroupTableData& rData ) const
{
    long nSourceIndex = rData.GetDimensionIndex( aSourceDim );
    if ( nSourceIndex >= 0 )
    {
        ScDPGroupDimension aDim( nSourceIndex, aGroupDimName );
        if ( nDatePart )
        {
            // date grouping

            aDim.MakeDateHelper( aDateInfo, nDatePart );
        }
        else
        {
            // normal (manual) grouping

            SvNumberFormatter* pFormatter = rData.GetDocument()->GetFormatTable();

            for ( ScDPSaveGroupItemVec::const_iterator aIter(aGroups.begin()); aIter != aGroups.end(); aIter++ )
                aIter->AddToData( aDim, pFormatter );
        }

        rData.AddGroupDimension( aDim );
    }
}

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

ScDPSaveNumGroupDimension::ScDPSaveNumGroupDimension( const String& rName, const ScDPNumGroupInfo& rInfo ) :
    aDimensionName( rName ),
    aGroupInfo( rInfo ),
    nDatePart( 0 )
{
}

ScDPSaveNumGroupDimension::ScDPSaveNumGroupDimension( const String& rName, const ScDPNumGroupInfo& rDateInfo, sal_Int32 nPart ) :
    aDimensionName( rName ),
    aDateInfo( rDateInfo ),
    nDatePart( nPart )
{
}

ScDPSaveNumGroupDimension::~ScDPSaveNumGroupDimension()
{
}

void ScDPSaveNumGroupDimension::AddToData( ScDPGroupTableData& rData ) const
{
    long nSource = rData.GetDimensionIndex( aDimensionName );
    if ( nSource >= 0 )
    {
        ScDPNumGroupDimension aDim( aGroupInfo );           // aGroupInfo: value grouping
        if ( nDatePart )
            aDim.MakeDateHelper( aDateInfo, nDatePart );    // date grouping

        rData.SetNumGroupDimension( nSource, aDim );
    }
}

void ScDPSaveNumGroupDimension::SetGroupInfo( const ScDPNumGroupInfo& rNew )
{
    aGroupInfo = rNew;
}

void ScDPSaveNumGroupDimension::SetDateInfo( const ScDPNumGroupInfo& rInfo, sal_Int32 nPart )
{
    aDateInfo = rInfo;
    nDatePart = nPart;
}

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

namespace {

struct ScDPSaveGroupDimNameFunc
{
    String              maDimName;
    inline explicit     ScDPSaveGroupDimNameFunc( const String& rDimName ) : maDimName( rDimName ) {}
    inline bool         operator()( const ScDPSaveGroupDimension& rGroupDim ) const { return rGroupDim.GetGroupDimName() == maDimName; }
};

struct ScDPSaveGroupSourceNameFunc
{
    String              maSrcDimName;
    inline explicit     ScDPSaveGroupSourceNameFunc( const String& rSrcDimName ) : maSrcDimName( rSrcDimName ) {}
    inline bool         operator()( const ScDPSaveGroupDimension& rGroupDim ) const { return rGroupDim.GetSourceDimName() == maSrcDimName; }
};

} // namespace

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

ScDPDimensionSaveData::ScDPDimensionSaveData()
{
}

ScDPDimensionSaveData::~ScDPDimensionSaveData()
{
}

bool ScDPDimensionSaveData::operator==( const ScDPDimensionSaveData& ) const
{
    return false;
}

void ScDPDimensionSaveData::AddGroupDimension( const ScDPSaveGroupDimension& rGroupDim )
{
    DBG_ASSERT( ::std::find_if( maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDim.GetGroupDimName() ) ) == maGroupDims.end(),
        "ScDPDimensionSaveData::AddGroupDimension - group dimension exists already" );
    // ReplaceGroupDimension() adds new or replaces existing
    ReplaceGroupDimension( rGroupDim );
}

void ScDPDimensionSaveData::ReplaceGroupDimension( const ScDPSaveGroupDimension& rGroupDim )
{
    ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
        maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDim.GetGroupDimName() ) );
    if( aIt == maGroupDims.end() )
        maGroupDims.push_back( rGroupDim );
    else
        *aIt = rGroupDim;
}

void ScDPDimensionSaveData::RemoveGroupDimension( const String& rGroupDimName )
{
    ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
        maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDimName ) );
    if( aIt != maGroupDims.end() )
        maGroupDims.erase( aIt );
}

void ScDPDimensionSaveData::AddNumGroupDimension( const ScDPSaveNumGroupDimension& rGroupDim )
{
    DBG_ASSERT( maNumGroupDims.count( rGroupDim.GetDimensionName() ) == 0,
        "ScDPDimensionSaveData::AddNumGroupDimension - numeric group dimension exists already" );
    // ReplaceNumGroupDimension() adds new or replaces existing
    ReplaceNumGroupDimension( rGroupDim );
}

void ScDPDimensionSaveData::ReplaceNumGroupDimension( const ScDPSaveNumGroupDimension& rGroupDim )
{
    ScDPSaveNumGroupDimMap::iterator aIt = maNumGroupDims.find( rGroupDim.GetDimensionName() );
    if( aIt == maNumGroupDims.end() )
        maNumGroupDims.insert( ScDPSaveNumGroupDimMap::value_type( rGroupDim.GetDimensionName(), rGroupDim ) );
    else
        aIt->second = rGroupDim;
}

void ScDPDimensionSaveData::RemoveNumGroupDimension( const String& rGroupDimName )
{
    maNumGroupDims.erase( rGroupDimName );
}

void ScDPDimensionSaveData::WriteToData( ScDPGroupTableData& rData ) const
{
    //  rData is assumed to be empty
    //  AddToData also handles date grouping

    for( ScDPSaveGroupDimVec::const_iterator aIt = maGroupDims.begin(), aEnd = maGroupDims.end(); aIt != aEnd; ++aIt )
        aIt->AddToData( rData );

    for( ScDPSaveNumGroupDimMap::const_iterator aIt = maNumGroupDims.begin(), aEnd = maNumGroupDims.end(); aIt != aEnd; ++aIt )
        aIt->second.AddToData( rData );
}

const ScDPSaveGroupDimension* ScDPDimensionSaveData::GetGroupDimForBase( const String& rBaseDimName ) const
{
    return const_cast< ScDPDimensionSaveData* >( this )->GetGroupDimAccForBase( rBaseDimName );
}

const ScDPSaveGroupDimension* ScDPDimensionSaveData::GetNamedGroupDim( const String& rGroupDimName ) const
{
    return const_cast< ScDPDimensionSaveData* >( this )->GetNamedGroupDimAcc( rGroupDimName );
}

const ScDPSaveGroupDimension* ScDPDimensionSaveData::GetFirstNamedGroupDim( const String& rBaseDimName ) const
{
    return const_cast< ScDPDimensionSaveData* >( this )->GetFirstNamedGroupDimAcc( rBaseDimName );
}

const ScDPSaveGroupDimension* ScDPDimensionSaveData::GetNextNamedGroupDim( const String& rGroupDimName ) const
{
    return const_cast< ScDPDimensionSaveData* >( this )->GetNextNamedGroupDimAcc( rGroupDimName );
}

const ScDPSaveNumGroupDimension* ScDPDimensionSaveData::GetNumGroupDim( const String& rGroupDimName ) const
{
    return const_cast< ScDPDimensionSaveData* >( this )->GetNumGroupDimAcc( rGroupDimName );
}

ScDPSaveGroupDimension* ScDPDimensionSaveData::GetGroupDimAccForBase( const String& rBaseDimName )
{
    ScDPSaveGroupDimension* pGroupDim = GetFirstNamedGroupDimAcc( rBaseDimName );
    return pGroupDim ? pGroupDim : GetNextNamedGroupDimAcc( rBaseDimName );
}

ScDPSaveGroupDimension* ScDPDimensionSaveData::GetNamedGroupDimAcc( const String& rGroupDimName )
{
    ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
        maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDimName ) );
    return (aIt == maGroupDims.end()) ? 0 : &*aIt;
}

ScDPSaveGroupDimension* ScDPDimensionSaveData::GetFirstNamedGroupDimAcc( const String& rBaseDimName )
{
    ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
        maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupSourceNameFunc( rBaseDimName ) );
    return (aIt == maGroupDims.end()) ? 0 : &*aIt;
}

ScDPSaveGroupDimension* ScDPDimensionSaveData::GetNextNamedGroupDimAcc( const String& rGroupDimName )
{
    // find the group dimension with the passed name
    ScDPSaveGroupDimVec::iterator aIt = ::std::find_if(
        maGroupDims.begin(), maGroupDims.end(), ScDPSaveGroupDimNameFunc( rGroupDimName ) );
    // find next group dimension based on the same source dimension name
    if( aIt != maGroupDims.end() )
        aIt = ::std::find_if( aIt + 1, maGroupDims.end(), ScDPSaveGroupSourceNameFunc( aIt->GetSourceDimName() ) );
    return (aIt == maGroupDims.end()) ? 0 : &*aIt;
}

ScDPSaveNumGroupDimension* ScDPDimensionSaveData::GetNumGroupDimAcc( const String& rGroupDimName )
{
    ScDPSaveNumGroupDimMap::iterator aIt = maNumGroupDims.find( rGroupDimName );
    return (aIt == maNumGroupDims.end()) ? 0 : &aIt->second;
}

bool ScDPDimensionSaveData::HasGroupDimensions() const
{
    return !maGroupDims.empty() || !maNumGroupDims.empty();
}

sal_Int32 ScDPDimensionSaveData::CollectDateParts( const String& rBaseDimName ) const
{
    sal_Int32 nParts = 0;
    // start with part of numeric group
    if( const ScDPSaveNumGroupDimension* pNumDim = GetNumGroupDim( rBaseDimName ) )
        nParts |= pNumDim->GetDatePart();
    // collect parts from all matching group dimensions
    for( const ScDPSaveGroupDimension* pGroupDim = GetFirstNamedGroupDim( rBaseDimName ); pGroupDim; pGroupDim = GetNextNamedGroupDim( pGroupDim->GetGroupDimName() ) )
        nParts |= pGroupDim->GetDatePart();

    return nParts;
}

String ScDPDimensionSaveData::CreateGroupDimName( const String& rSourceName,
                                        const ScDPObject& rObject, bool bAllowSource,
                                        const std::vector<String>* pDeletedNames )
{
    // create a name for the new dimension by appending a number to the original
    // dimension's name

    bool bUseSource = bAllowSource;     // if set, try the unchanged original name first

    sal_Int32 nAdd = 2;                 // first try is "Name2"
    const sal_Int32 nMaxAdd = 1000;     // limit the loop
    while ( nAdd <= nMaxAdd )
    {
        String aDimName( rSourceName );
        if ( !bUseSource )
            aDimName.Append( String::CreateFromInt32( nAdd ) );
        bool bExists = false;

        // look for existing group dimensions
        for( ScDPSaveGroupDimVec::const_iterator aIt = maGroupDims.begin(), aEnd = maGroupDims.end(); (aIt != aEnd) && !bExists; ++aIt )
            if( aIt->GetGroupDimName() == aDimName )         //! ignore case
                bExists = true;

        // look for base dimensions that happen to have that name
        if ( !bExists && rObject.IsDimNameInUse( aDimName ) )
        {
            if ( pDeletedNames &&
                 std::find( pDeletedNames->begin(), pDeletedNames->end(), aDimName ) != pDeletedNames->end() )
            {
                // allow the name anyway if the name is in pDeletedNames
            }
            else
                bExists = true;
        }

        if ( !bExists )
            return aDimName;            // found a new name

        if ( bUseSource )
            bUseSource = false;
        else
            ++nAdd;                     // continue with higher number
    }
    DBG_ERROR("CreateGroupDimName: no valid name found");
    return EMPTY_STRING;
}

namespace {

static const sal_uInt16 nDatePartIds[] =
{
    STR_DPFIELD_GROUP_BY_SECONDS,
    STR_DPFIELD_GROUP_BY_MINUTES,
    STR_DPFIELD_GROUP_BY_HOURS,
    STR_DPFIELD_GROUP_BY_DAYS,
    STR_DPFIELD_GROUP_BY_MONTHS,
    STR_DPFIELD_GROUP_BY_QUARTERS,
    STR_DPFIELD_GROUP_BY_YEARS
};

}
String ScDPDimensionSaveData::CreateDateGroupDimName( sal_Int32 nDatePart, const ScDPObject& rObject, bool bAllowSource, const ::std::vector< String >* pDeletedNames )
{
    using namespace ::com::sun::star::sheet::DataPilotFieldGroupBy;
    String aPartName;
    switch( nDatePart )
    {
        case SECONDS:  aPartName = ScGlobal::GetRscString( nDatePartIds[0] ); break;
        case MINUTES:  aPartName = ScGlobal::GetRscString( nDatePartIds[1] ); break;
        case HOURS:    aPartName = ScGlobal::GetRscString( nDatePartIds[2] ); break;
        case DAYS:     aPartName = ScGlobal::GetRscString( nDatePartIds[3] ); break;
        case MONTHS:   aPartName = ScGlobal::GetRscString( nDatePartIds[4] ); break;
        case QUARTERS: aPartName = ScGlobal::GetRscString( nDatePartIds[5] ); break;
        case YEARS:    aPartName = ScGlobal::GetRscString( nDatePartIds[6] ); break;
    }
    DBG_ASSERT( aPartName.Len() > 0, "ScDPDimensionSaveData::CreateDateGroupDimName - invalid date part" );
    return CreateGroupDimName( aPartName, rObject, bAllowSource, pDeletedNames );
}

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

