/**************************************************************
 *
 * 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 "tokenuno.hxx"

#include <com/sun/star/sheet/ComplexReference.hpp>
#include <com/sun/star/sheet/ExternalReference.hpp>
#include <com/sun/star/sheet/ReferenceFlags.hpp>
#include <com/sun/star/sheet/AddressConvention.hpp>
#include <com/sun/star/table/CellAddress.hpp>

#include <svl/itemprop.hxx>

#include "miscuno.hxx"
#include "convuno.hxx"
#include "unonames.hxx"
#include "unoguard.hxx"
#include "token.hxx"
#include "compiler.hxx"
#include "tokenarray.hxx"
#include "docsh.hxx"
#include "rangeseq.hxx"
#include "externalrefmgr.hxx"

using namespace ::formula;
using namespace ::com::sun::star;

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

const SfxItemPropertyMapEntry* lcl_GetFormulaParserMap()
{
    static SfxItemPropertyMapEntry aFormulaParserMap_Impl[] =
    {
        {MAP_CHAR_LEN(SC_UNO_COMPILEFAP),           0,  &getBooleanCppuType(),                   0, 0 },
        {MAP_CHAR_LEN(SC_UNO_COMPILEENGLISH),       0,  &getBooleanCppuType(),                   0, 0 },
        {MAP_CHAR_LEN(SC_UNO_IGNORELEADING),        0,  &getBooleanCppuType(),                   0, 0 },
        {MAP_CHAR_LEN(SC_UNO_FORMULACONVENTION),    0,  &getCppuType(&sheet::AddressConvention::UNSPECIFIED), 0, 0 },
        {MAP_CHAR_LEN(SC_UNO_OPCODEMAP),            0,  &getCppuType((uno::Sequence< sheet::FormulaOpCodeMapEntry >*)0), 0, 0 },
        {0,0,0,0,0,0}
    };
    return aFormulaParserMap_Impl;
}

SC_SIMPLE_SERVICE_INFO( ScFormulaParserObj, "ScFormulaParserObj", SC_SERVICENAME_FORMULAPARS )

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

ScFormulaParserObj::ScFormulaParserObj(ScDocShell* pDocSh) :
    mpDocShell( pDocSh ),
    mnConv( sheet::AddressConvention::UNSPECIFIED ),
    mbEnglish( false ),
    mbIgnoreSpaces( true ),
    mbCompileFAP( false )
{
    mpDocShell->GetDocument()->AddUnoObject(*this);
}

ScFormulaParserObj::~ScFormulaParserObj()
{
    if (mpDocShell)
        mpDocShell->GetDocument()->RemoveUnoObject(*this);
}

void ScFormulaParserObj::Notify( SfxBroadcaster&, const SfxHint& rHint )
{
    if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING )
        mpDocShell = NULL;
}

// XFormulaParser

void ScFormulaParserObj::SetCompilerFlags( ScCompiler& rCompiler ) const
{
    static const formula::FormulaGrammar::AddressConvention aConvMap[] = {
        formula::FormulaGrammar::CONV_OOO,        // <- AddressConvention::OOO
        formula::FormulaGrammar::CONV_XL_A1,      // <- AddressConvention::XL_A1
        formula::FormulaGrammar::CONV_XL_R1C1,    // <- AddressConvention::XL_R1C1
        formula::FormulaGrammar::CONV_XL_OOX,     // <- AddressConvention::XL_OOX
        formula::FormulaGrammar::CONV_LOTUS_A1    // <- AddressConvention::LOTUS_A1
    };
    static const sal_Int16 nConvMapCount = sizeof(aConvMap)/sizeof(aConvMap[0]);

    // If mxOpCodeMap is not empty it overrides mbEnglish, and vice versa. We
    // don't need to initialize things twice.
    if (mxOpCodeMap.get())
        rCompiler.SetFormulaLanguage( mxOpCodeMap );
    else
    {
        sal_Int32 nFormulaLanguage = mbEnglish ?
            sheet::FormulaLanguage::ENGLISH :
            sheet::FormulaLanguage::NATIVE;
        ScCompiler::OpCodeMapPtr xMap = rCompiler.GetOpCodeMap( nFormulaLanguage);
        rCompiler.SetFormulaLanguage( xMap);
    }

    formula::FormulaGrammar::AddressConvention eConv = formula::FormulaGrammar::CONV_UNSPECIFIED;
    if (mnConv >= 0 && mnConv < nConvMapCount)
        eConv = aConvMap[mnConv];

    rCompiler.SetRefConvention( eConv );

    rCompiler.SetCompileForFAP(mbCompileFAP);

    rCompiler.SetExternalLinks( maExternalLinks);
}

uno::Sequence<sheet::FormulaToken> SAL_CALL ScFormulaParserObj::parseFormula(
        const rtl::OUString& aFormula, const table::CellAddress& rReferencePos )
                                throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    uno::Sequence<sheet::FormulaToken> aRet;

    if (mpDocShell)
    {
        ScDocument* pDoc = mpDocShell->GetDocument();
        ScExternalRefManager::ApiGuard aExtRefGuard(pDoc);

        ScAddress aRefPos( ScAddress::UNINITIALIZED );
        ScUnoConversion::FillScAddress( aRefPos, rReferencePos );
        ScCompiler aCompiler( pDoc, aRefPos);
        aCompiler.SetGrammar(pDoc->GetGrammar());
        SetCompilerFlags( aCompiler );

        ScTokenArray* pCode = aCompiler.CompileString( aFormula );
        (void)ScTokenConversion::ConvertToTokenSequence( *pDoc, aRet, *pCode );
        delete pCode;
    }

    return aRet;
}

rtl::OUString SAL_CALL ScFormulaParserObj::printFormula(
        const uno::Sequence<sheet::FormulaToken>& aTokens, const table::CellAddress& rReferencePos )
                                throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    rtl::OUString aRet;

    if (mpDocShell)
    {
        ScDocument* pDoc = mpDocShell->GetDocument();
        ScTokenArray aCode;
        (void)ScTokenConversion::ConvertToTokenArray( *pDoc, aCode, aTokens );
        ScAddress aRefPos( ScAddress::UNINITIALIZED );
        ScUnoConversion::FillScAddress( aRefPos, rReferencePos );
        ScCompiler aCompiler( pDoc, aRefPos, aCode);
        aCompiler.SetGrammar(pDoc->GetGrammar());
        SetCompilerFlags( aCompiler );

        rtl::OUStringBuffer aBuffer;
        aCompiler.CreateStringFromTokenArray( aBuffer );
        aRet = aBuffer.makeStringAndClear();
    }

    return aRet;
}

// XPropertySet

uno::Reference<beans::XPropertySetInfo> SAL_CALL ScFormulaParserObj::getPropertySetInfo()
                                                        throw(uno::RuntimeException)
{
    ScUnoGuard aGuard;
    static uno::Reference< beans::XPropertySetInfo > aRef(new SfxItemPropertySetInfo( lcl_GetFormulaParserMap() ));
    return aRef;
}

void SAL_CALL ScFormulaParserObj::setPropertyValue(
                        const rtl::OUString& aPropertyName, const uno::Any& aValue )
                throw(beans::UnknownPropertyException, beans::PropertyVetoException,
                        lang::IllegalArgumentException, lang::WrappedTargetException,
                        uno::RuntimeException)
{
    ScUnoGuard aGuard;
    String aString(aPropertyName);
    if ( aString.EqualsAscii( SC_UNO_COMPILEFAP ) )
    {
        aValue >>= mbCompileFAP;
    }
    else if ( aString.EqualsAscii( SC_UNO_COMPILEENGLISH ) )
    {
        bool bOldEnglish = mbEnglish;
        if (aValue >>= mbEnglish)
        {
            // Need to recreate the symbol map to change English property
            // because the map is const. So for performance reasons set
            // CompileEnglish _before_ OpCodeMap!
            if (mxOpCodeMap.get() && mbEnglish != bOldEnglish)
            {
                ScDocument* pDoc = mpDocShell->GetDocument();
                ScCompiler aCompiler( pDoc, ScAddress());
                aCompiler.SetGrammar(pDoc->GetGrammar());
                mxOpCodeMap = aCompiler.CreateOpCodeMap( maOpCodeMapping, mbEnglish);
            }
        }
        else
            throw lang::IllegalArgumentException();
    }
    else if ( aString.EqualsAscii( SC_UNO_FORMULACONVENTION ) )
    {
        aValue >>= mnConv;
    }
    else if ( aString.EqualsAscii( SC_UNO_IGNORELEADING ) )
    {
        aValue >>= mbIgnoreSpaces;
    }
    else if ( aString.EqualsAscii( SC_UNO_OPCODEMAP ) )
    {
        if (aValue >>= maOpCodeMapping)
        {
            ScDocument* pDoc = mpDocShell->GetDocument();
            ScCompiler aCompiler( pDoc, ScAddress());
            aCompiler.SetGrammar(pDoc->GetGrammar());
            mxOpCodeMap = aCompiler.CreateOpCodeMap( maOpCodeMapping, mbEnglish);
        }
        else
            throw lang::IllegalArgumentException();
    }
    else if ( aString.EqualsAscii( SC_UNO_EXTERNALLINKS ) )
    {
        if (!(aValue >>= maExternalLinks))
            throw lang::IllegalArgumentException();
    }
    else
        throw beans::UnknownPropertyException();
}

uno::Any SAL_CALL ScFormulaParserObj::getPropertyValue( const rtl::OUString& aPropertyName )
                throw(beans::UnknownPropertyException, lang::WrappedTargetException,
                        uno::RuntimeException)
{
    ScUnoGuard aGuard;
    uno::Any aRet;
    String aString(aPropertyName);
    if ( aString.EqualsAscii( SC_UNO_COMPILEFAP ) )
    {
        aRet <<= mbCompileFAP;
    }
    else if ( aString.EqualsAscii( SC_UNO_COMPILEENGLISH ) )
    {
        aRet <<= mbEnglish;
    }
    else if ( aString.EqualsAscii( SC_UNO_FORMULACONVENTION ) )
    {
        aRet <<= mnConv;
    }
    else if ( aString.EqualsAscii( SC_UNO_IGNORELEADING ) )
    {
        aRet <<= mbIgnoreSpaces;
    }
    else if ( aString.EqualsAscii( SC_UNO_OPCODEMAP ) )
    {
        aRet <<= maOpCodeMapping;
    }
    else if ( aString.EqualsAscii( SC_UNO_EXTERNALLINKS ) )
    {
        aRet <<= maExternalLinks;
    }
    else
        throw beans::UnknownPropertyException();
    return aRet;
}

SC_IMPL_DUMMY_PROPERTY_LISTENER( ScFormulaParserObj )

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

void lcl_ExternalRefToApi( sheet::SingleReference& rAPI, const ScSingleRefData& rRef )
{
    rAPI.Column         = rRef.nCol;
    rAPI.Row            = rRef.nRow;
    rAPI.Sheet          = 0;
    rAPI.RelativeColumn = rRef.nRelCol;
    rAPI.RelativeRow    = rRef.nRelRow;
    rAPI.RelativeSheet  = 0;

    sal_Int32 nFlags = 0;
    if ( rRef.IsColRel() )     nFlags |= sheet::ReferenceFlags::COLUMN_RELATIVE;
    if ( rRef.IsRowRel() )     nFlags |= sheet::ReferenceFlags::ROW_RELATIVE;
    if ( rRef.IsColDeleted() ) nFlags |= sheet::ReferenceFlags::COLUMN_DELETED;
    if ( rRef.IsRowDeleted() ) nFlags |= sheet::ReferenceFlags::ROW_DELETED;
    if ( rRef.IsFlag3D() )     nFlags |= sheet::ReferenceFlags::SHEET_3D;
    if ( rRef.IsRelName() )    nFlags |= sheet::ReferenceFlags::RELATIVE_NAME;
    rAPI.Flags = nFlags;
}

void lcl_SingleRefToApi( sheet::SingleReference& rAPI, const ScSingleRefData& rRef )
{
    rAPI.Column         = rRef.nCol;
    rAPI.Row            = rRef.nRow;
    rAPI.Sheet          = rRef.nTab;
    rAPI.RelativeColumn = rRef.nRelCol;
    rAPI.RelativeRow    = rRef.nRelRow;
    rAPI.RelativeSheet  = rRef.nRelTab;

    sal_Int32 nFlags = 0;
    if ( rRef.IsColRel() )     nFlags |= sheet::ReferenceFlags::COLUMN_RELATIVE;
    if ( rRef.IsRowRel() )     nFlags |= sheet::ReferenceFlags::ROW_RELATIVE;
    if ( rRef.IsTabRel() )     nFlags |= sheet::ReferenceFlags::SHEET_RELATIVE;
    if ( rRef.IsColDeleted() ) nFlags |= sheet::ReferenceFlags::COLUMN_DELETED;
    if ( rRef.IsRowDeleted() ) nFlags |= sheet::ReferenceFlags::ROW_DELETED;
    if ( rRef.IsTabDeleted() ) nFlags |= sheet::ReferenceFlags::SHEET_DELETED;
    if ( rRef.IsFlag3D() )     nFlags |= sheet::ReferenceFlags::SHEET_3D;
    if ( rRef.IsRelName() )    nFlags |= sheet::ReferenceFlags::RELATIVE_NAME;
    rAPI.Flags = nFlags;
}

// static
bool ScTokenConversion::ConvertToTokenArray( ScDocument& rDoc,
        ScTokenArray& rTokenArray, const uno::Sequence<sheet::FormulaToken>& rSequence )
{
    return !rTokenArray.Fill(rSequence,rDoc.GetExternalRefManager());
}

// static
bool ScTokenConversion::ConvertToTokenSequence( ScDocument& rDoc,
        uno::Sequence<sheet::FormulaToken>& rSequence, const ScTokenArray& rTokenArray )
{
    bool bError = false;

    sal_Int32 nLen = static_cast<sal_Int32>(rTokenArray.GetLen());
    formula::FormulaToken** pTokens = rTokenArray.GetArray();
    if ( pTokens )
    {
        rSequence.realloc(nLen);
        for (sal_Int32 nPos=0; nPos<nLen; nPos++)
        {
            const formula::FormulaToken& rToken = *pTokens[nPos];
            sheet::FormulaToken& rAPI = rSequence[nPos];

            OpCode eOpCode = rToken.GetOpCode();
            // eOpCode may be changed in the following switch/case
            switch ( rToken.GetType() )
            {
                case svByte:
                    // Only the count of spaces is stored as "long". Parameter count is ignored.
                    if ( eOpCode == ocSpaces )
                        rAPI.Data <<= (sal_Int32) rToken.GetByte();
                    else
                        rAPI.Data.clear();      // no data
                    break;
                case formula::svDouble:
                    rAPI.Data <<= rToken.GetDouble();
                    break;
                case formula::svString:
                    rAPI.Data <<= rtl::OUString( rToken.GetString() );
                    break;
                case svExternal:
                    // Function name is stored as string.
                    // Byte (parameter count) is ignored.
                    rAPI.Data <<= rtl::OUString( rToken.GetExternal() );
                    break;
                case svSingleRef:
                    {
                        sheet::SingleReference aSingleRef;
                        lcl_SingleRefToApi( aSingleRef, static_cast<const ScToken&>(rToken).GetSingleRef() );
                        rAPI.Data <<= aSingleRef;
                    }
                    break;
                case formula::svDoubleRef:
                    {
                        sheet::ComplexReference aCompRef;
                        lcl_SingleRefToApi( aCompRef.Reference1, static_cast<const ScToken&>(rToken).GetSingleRef() );
                        lcl_SingleRefToApi( aCompRef.Reference2, static_cast<const ScToken&>(rToken).GetSingleRef2() );
                        rAPI.Data <<= aCompRef;
                    }
                    break;
                case svIndex:
                    rAPI.Data <<= static_cast<sal_Int32>( rToken.GetIndex() );
                    break;
                case svMatrix:
                    if (!ScRangeToSequence::FillMixedArray( rAPI.Data, static_cast<const ScToken&>(rToken).GetMatrix(), true))
                        rAPI.Data.clear();
                    break;
                case svExternalSingleRef:
                    {
                        sheet::SingleReference aSingleRef;
                        lcl_ExternalRefToApi( aSingleRef, static_cast<const ScToken&>(rToken).GetSingleRef() );
                        size_t nCacheId;
                        rDoc.GetExternalRefManager()->getCacheTable( rToken.GetIndex(), rToken.GetString(), false, &nCacheId );
                        aSingleRef.Sheet = static_cast< sal_Int32 >( nCacheId );
                        sheet::ExternalReference aExtRef;
                        aExtRef.Index = rToken.GetIndex();
                        aExtRef.Reference <<= aSingleRef;
                        rAPI.Data <<= aExtRef;
                        eOpCode = ocPush;
                    }
                    break;
                case svExternalDoubleRef:
                    {
                        sheet::ComplexReference aComplRef;
                        lcl_ExternalRefToApi( aComplRef.Reference1, static_cast<const ScToken&>(rToken).GetSingleRef() );
                        lcl_ExternalRefToApi( aComplRef.Reference2, static_cast<const ScToken&>(rToken).GetSingleRef2() );
                        size_t nCacheId;
                        rDoc.GetExternalRefManager()->getCacheTable( rToken.GetIndex(), rToken.GetString(), false, &nCacheId );
                        aComplRef.Reference1.Sheet = static_cast< sal_Int32 >( nCacheId );
                        // NOTE: This assumes that cached sheets are in consecutive order!
                        aComplRef.Reference2.Sheet = aComplRef.Reference1.Sheet + (static_cast<const ScToken&>(rToken).GetSingleRef2().nTab - static_cast<const ScToken&>(rToken).GetSingleRef().nTab);
                        sheet::ExternalReference aExtRef;
                        aExtRef.Index = rToken.GetIndex();
                        aExtRef.Reference <<= aComplRef;
                        rAPI.Data <<= aExtRef;
                        eOpCode = ocPush;
                    }
                    break;
                case svExternalName:
                    {
                        sheet::ExternalReference aExtRef;
                        aExtRef.Index = rToken.GetIndex();
                        aExtRef.Reference <<= ::rtl::OUString( rToken.GetString() );
                        rAPI.Data <<= aExtRef;
                        eOpCode = ocPush;
                    }
                    break;
                default:
                    DBG_ERROR1( "ScTokenConversion::ConvertToTokenSequence: unhandled token type SvStackVar %d", rToken.GetType());
                case svSep:     // occurs with ocSep, ocOpen, ocClose, ocArray*
                case svJump:    // occurs with ocIf, ocChose
                case svMissing: // occurs with ocMissing
                    rAPI.Data.clear();      // no data
            }
            rAPI.OpCode = static_cast<sal_Int32>(eOpCode);      //! assuming equal values for the moment
        }
    }
    else
        rSequence.realloc(0);

    return !bError;
}

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

ScFormulaOpCodeMapperObj::ScFormulaOpCodeMapperObj(::std::auto_ptr<formula::FormulaCompiler> _pCompiler)
: formula::FormulaOpCodeMapperObj(_pCompiler)
{
}

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