/**************************************************************
 * 
 * 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;
}
