/**************************************************************
 *
 * 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 <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/table/XCell.hpp>
#include <com/sun/star/table/XColumnRowRange.hpp>
#include <com/sun/star/beans/XIntrospection.hpp>
#include <com/sun/star/beans/XIntrospectionAccess.hpp>
#include <com/sun/star/sheet/XFunctionAccess.hpp>
#include <com/sun/star/sheet/XCellRangesQuery.hpp>
#include <com/sun/star/sheet/XCellRangeAddressable.hpp>
#include <com/sun/star/sheet/CellFlags.hpp>
#include <com/sun/star/reflection/XIdlMethod.hpp>
#include <com/sun/star/beans/MethodConcept.hpp>
#include <comphelper/processfactory.hxx>
#include <cppuhelper/queryinterface.hxx>
#include <comphelper/anytostring.hxx>

#include "vbawsfunction.hxx"
#include "compiler.hxx"

using namespace com::sun::star;
using namespace ooo::vba;

namespace {

void lclConvertDoubleToBoolean( uno::Any& rAny )
{
    if( rAny.has< double >() )
    {
        double fValue = rAny.get< double >();
        if( fValue == 0.0 )
            rAny <<= false;
        else if( fValue == 1.0 )
            rAny <<= true;
        // do nothing for other values or types
    }
}

} // namespace

ScVbaWSFunction::ScVbaWSFunction( const uno::Reference< XHelperInterface >& xParent, const css::uno::Reference< css::uno::XComponentContext >& xContext ) :
    ScVbaWSFunction_BASE( xParent, xContext )
{
}

uno::Reference< beans::XIntrospectionAccess >
ScVbaWSFunction::getIntrospection(void)  throw(uno::RuntimeException)
{
	return uno::Reference<beans::XIntrospectionAccess>();
}

uno::Any SAL_CALL
ScVbaWSFunction::invoke(const rtl::OUString& FunctionName, const uno::Sequence< uno::Any >& Params, uno::Sequence< sal_Int16 >& /*OutParamIndex*/, uno::Sequence< uno::Any >& /*OutParam*/) throw(lang::IllegalArgumentException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException)
{
    // create copy of parameters, replace Excel range objects with UNO range objects
    uno::Sequence< uno::Any > aParamTemp( Params );
    if( aParamTemp.hasElements() )
    {
        uno::Any* pArray = aParamTemp.getArray();
        uno::Any* pArrayEnd = pArray + aParamTemp.getLength();
        for( ; pArray < pArrayEnd; ++pArray )
        {
            uno::Reference< excel::XRange > myRange( *pArray, uno::UNO_QUERY );
            if( myRange.is() )
                *pArray = myRange->getCellRange();
            OSL_TRACE("Param[%d] is %s", (int)(pArray - aParamTemp.getConstArray()), rtl::OUStringToOString( comphelper::anyToString( *pArray ), RTL_TEXTENCODING_UTF8 ).getStr() );
        }
    }

    uno::Any aRet;
    bool bAsArray = true;

    // special handing for some functions that don't work correctly in FunctionAccess
	ScCompiler aCompiler( 0, ScAddress() );
	OpCode eOpCode = aCompiler.GetEnglishOpCode( FunctionName.toAsciiUpperCase() );
	switch( eOpCode )
	{
        // ISLOGICAL does not work in array formula mode
        case ocIsLogical:
        {
            if( aParamTemp.getLength() != 1 )
                throw lang::IllegalArgumentException();
            const uno::Any& rParam = aParamTemp[ 0 ];
            if( rParam.has< bool >() )
            {
                aRet <<= true;
            }
            else if( rParam.has< uno::Reference< table::XCellRange > >() ) try
            {
                uno::Reference< sheet::XCellRangeAddressable > xRangeAddr( rParam, uno::UNO_QUERY_THROW );
                table::CellRangeAddress aRangeAddr = xRangeAddr->getRangeAddress();
                bAsArray = (aRangeAddr.StartColumn != aRangeAddr.EndColumn) || (aRangeAddr.StartRow != aRangeAddr.EndRow);
            }
            catch( uno::Exception& )
            {
            }
        }
        break;
        default:;
    }

    if( !aRet.hasValue() )
    {
    	uno::Reference< lang::XMultiComponentFactory > xSMgr( mxContext->getServiceManager(), uno::UNO_QUERY_THROW );
    	uno::Reference< sheet::XFunctionAccess > xFunctionAccess( xSMgr->createInstanceWithContext(
            ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.sheet.FunctionAccess" ) ), mxContext ),
            uno::UNO_QUERY_THROW );
    	uno::Reference< beans::XPropertySet > xPropSet( xFunctionAccess, uno::UNO_QUERY_THROW );
    	xPropSet->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "IsArrayFunction" ) ), uno::Any( bAsArray ) );
        aRet = xFunctionAccess->callFunction( FunctionName, aParamTemp );
    }

    /*  Convert return value from double to to Boolean for some functions that
        return Booleans. */
    typedef uno::Sequence< uno::Sequence< uno::Any > > AnySeqSeq;
    if( (eOpCode == ocIsEmpty) || (eOpCode == ocIsString) || (eOpCode == ocIsNonString) || (eOpCode == ocIsLogical) ||
        (eOpCode == ocIsRef) || (eOpCode == ocIsValue) || (eOpCode == ocIsFormula) || (eOpCode == ocIsNA) ||
        (eOpCode == ocIsErr) || (eOpCode == ocIsError) || (eOpCode == ocIsEven) || (eOpCode == ocIsOdd) ||
        (eOpCode == ocAnd) || (eOpCode == ocOr) || (eOpCode == ocNot) || (eOpCode == ocTrue) || (eOpCode == ocFalse) )
    {
        if( aRet.has< AnySeqSeq >() )
        {
            AnySeqSeq aAnySeqSeq = aRet.get< AnySeqSeq >();
            for( sal_Int32 nRow = 0; nRow < aAnySeqSeq.getLength(); ++nRow )
                for( sal_Int32 nCol = 0; nCol < aAnySeqSeq[ nRow ].getLength(); ++nCol )
                    lclConvertDoubleToBoolean( aAnySeqSeq[ nRow ][ nCol ] );
            aRet <<= aAnySeqSeq;
        }
        else
        {
            lclConvertDoubleToBoolean( aRet );
        }
    }

    /*  Hack/workaround (?): shorten single-row matrix to simple array, shorten
        1x1 matrix to single value. */
    if( aRet.has< AnySeqSeq >() )
    {
        AnySeqSeq aAnySeqSeq = aRet.get< AnySeqSeq >();
        if( aAnySeqSeq.getLength() == 1 )
        {
            if( aAnySeqSeq[ 0 ].getLength() == 1 )
                aRet = aAnySeqSeq[ 0 ][ 0 ];
            else
                aRet <<= aAnySeqSeq[ 0 ];
        }
    }

#if 0
	// MATCH function should alwayse return a double value, but currently if the first argument is XCellRange, MATCH function returns an array instead of a double value. Don't know why?
	// To fix this issue in safe, current solution is to convert this array to a double value just for MATCH function.
	String aUpper( FunctionName );
	ScCompiler aCompiler( NULL, ScAddress() );
	OpCode eOp = aCompiler.GetEnglishOpCode( aUpper.ToUpperAscii() );
	if( eOp == ocMatch )
	{
		double fVal = 0.0;
		if( aRet >>= fVal )
			return aRet;
		uno::Sequence< uno::Sequence< uno::Any > > aSequence;
		if( !( ( aRet >>= aSequence ) && ( aSequence.getLength() > 0 ) &&
			( aSequence[0].getLength() > 0 ) && ( aSequence[0][0] >>= fVal ) ) )
				throw uno::RuntimeException();
		aRet <<= fVal;
	}
#endif

	return aRet;
}

void SAL_CALL
ScVbaWSFunction::setValue(const rtl::OUString& /*PropertyName*/, const uno::Any& /*Value*/) throw(beans::UnknownPropertyException, script::CannotConvertException, reflection::InvocationTargetException, uno::RuntimeException)
{
	throw beans::UnknownPropertyException();
}

uno::Any SAL_CALL
ScVbaWSFunction::getValue(const rtl::OUString& /*PropertyName*/) throw(beans::UnknownPropertyException, uno::RuntimeException)
{
	throw beans::UnknownPropertyException();
}

sal_Bool SAL_CALL
ScVbaWSFunction::hasMethod(const rtl::OUString& Name)  throw(uno::RuntimeException)
{
	sal_Bool bIsFound = sal_False;
	try
	{
	// the function name contained in the com.sun.star.sheet.FunctionDescription service is alwayse localized.
		// but the function name used in WorksheetFunction is a programmatic name (seems English).
		// So m_xNameAccess->hasByName( Name ) may fail to find name when a function name has a localized name.
		ScCompiler aCompiler( NULL, ScAddress() );
		if( aCompiler.IsEnglishSymbol( Name ) )
			bIsFound = sal_True;
	}
	catch( uno::Exception& /*e*/ )
	{
		// failed to find name
	}
	return bIsFound;
}

sal_Bool SAL_CALL
ScVbaWSFunction::hasProperty(const rtl::OUString& /*Name*/)  throw(uno::RuntimeException)
{
	 return sal_False;
}

::rtl::OUString SAL_CALL
ScVbaWSFunction::getExactName( const ::rtl::OUString& aApproximateName ) throw (css::uno::RuntimeException)
{
	rtl::OUString sName = aApproximateName.toAsciiUpperCase();
	if ( !hasMethod( sName ) )
		return rtl::OUString();
	return sName;
}

rtl::OUString&
ScVbaWSFunction::getServiceImplName()
{
	static rtl::OUString sImplName( RTL_CONSTASCII_USTRINGPARAM("ScVbaWSFunction") );
	return sImplName;
}

uno::Sequence< rtl::OUString >
ScVbaWSFunction::getServiceNames()
{
	static uno::Sequence< rtl::OUString > aServiceNames;
	if ( aServiceNames.getLength() == 0 )
	{
		aServiceNames.realloc( 1 );
		aServiceNames[ 0 ] = rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ooo.vba.excel.WorksheetFunction" ) );
	}
	return aServiceNames;
}
