/**************************************************************
 * 
 * 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 "vbaformatcondition.hxx"
#include "vbaformatconditions.hxx"
#include <ooo/vba/excel/XlFormatConditionType.hpp>

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

ScVbaFormatConditions* 
lcl_getScVbaFormatConditionsPtr( const uno::Reference< excel::XFormatConditions >& xFormatConditions ) throw ( script::BasicErrorException )
{
	ScVbaFormatConditions* pFormatConditions = static_cast< ScVbaFormatConditions* >( xFormatConditions.get() );
	if ( !pFormatConditions )
		DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
	return pFormatConditions;
}
ScVbaFormatCondition::ScVbaFormatCondition(  const uno::Reference< XHelperInterface >& xParent, const uno::Reference< uno::XComponentContext > & xContext, const uno::Reference< sheet::XSheetConditionalEntry >& _xSheetConditionalEntry, const uno::Reference< excel::XStyle >& _xStyle, const uno::Reference< excel::XFormatConditions >& _xFormatConditions, const uno::Reference< css::beans::XPropertySet >& _xPropertySet ) throw ( css::uno::RuntimeException ) : ScVbaFormatCondition_BASE( xParent, xContext, uno::Reference< sheet::XSheetCondition >( _xSheetConditionalEntry, css::uno::UNO_QUERY_THROW ) ), moFormatConditions( _xFormatConditions ), mxStyle( _xStyle ), mxParentRangePropertySet( _xPropertySet )
{
        mxSheetConditionalEntries = lcl_getScVbaFormatConditionsPtr( moFormatConditions )->getSheetConditionalEntries();

        mxSheetConditionalEntry = _xSheetConditionalEntry;
        msStyleName = mxStyle->getName();
}


void SAL_CALL 
ScVbaFormatCondition::Delete(  ) throw (script::BasicErrorException, uno::RuntimeException)
{
	ScVbaFormatConditions* pFormatConditions = lcl_getScVbaFormatConditionsPtr( moFormatConditions );
	pFormatConditions->removeFormatCondition(msStyleName, sal_True);
        notifyRange();
}

void SAL_CALL 
ScVbaFormatCondition::Modify( ::sal_Int32 _nType, const uno::Any& _aOperator, const uno::Any& _aFormula1, const uno::Any& _aFormula2 ) throw (script::BasicErrorException, uno::RuntimeException)
{
	try
	{
		ScVbaFormatConditions* pFormatConditions = lcl_getScVbaFormatConditionsPtr( moFormatConditions );
		pFormatConditions->removeFormatCondition(msStyleName, sal_False);
		pFormatConditions->Add(_nType, _aOperator, _aFormula1, _aFormula2, mxStyle);
	}
	catch (uno::Exception& )
	{
		DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
	}
}

uno::Reference< excel::XInterior > SAL_CALL 
ScVbaFormatCondition::Interior(  ) throw (script::BasicErrorException, uno::RuntimeException)
{
	return mxStyle->Interior();
}

uno::Reference< excel::XFont > SAL_CALL 
ScVbaFormatCondition::Font(  ) throw (script::BasicErrorException, uno::RuntimeException)
{
	return mxStyle->Font();
}
uno::Any SAL_CALL 
ScVbaFormatCondition::Borders( const uno::Any& Index ) throw (script::BasicErrorException, uno::RuntimeException)
{ return mxStyle->Borders( Index );
}

sheet::ConditionOperator
ScVbaFormatCondition::retrieveAPIType(sal_Int32 _nVBAType, const uno::Reference< sheet::XSheetCondition >& _xSheetCondition ) throw ( script::BasicErrorException )
{
	sheet::ConditionOperator aAPIType = sheet::ConditionOperator_NONE;
	switch (_nVBAType)
	{
		case excel::XlFormatConditionType::xlExpression:
			aAPIType = sheet::ConditionOperator_FORMULA;
			break;
		case excel::XlFormatConditionType::xlCellValue:
			if ( _xSheetCondition.is() && (_xSheetCondition->getOperator() == sheet::ConditionOperator_FORMULA ) )
				aAPIType = sheet::ConditionOperator_NONE;
			break;
		default:
			DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
	}        
	return aAPIType;
}

void 
ScVbaFormatCondition::setFormula1( const uno::Any& _aFormula1) throw ( script::BasicErrorException )
{
	// getA1Formula *SHOULD* detect whether the formula is r1c1 or A1 syntax
	// and if R1C1 convert to A1
	ScVbaFormatCondition_BASE::setFormula1( uno::makeAny( lcl_getScVbaFormatConditionsPtr( moFormatConditions )->getA1Formula(_aFormula1) ) );
}

void
ScVbaFormatCondition::setFormula2( const uno::Any& _aFormula2) throw ( script::BasicErrorException )
{
	ScVbaFormatCondition_BASE::setFormula1( uno::makeAny( lcl_getScVbaFormatConditionsPtr( moFormatConditions )->getA1Formula(_aFormula2)) );
}

::sal_Int32 SAL_CALL 
ScVbaFormatCondition::Type(  ) throw ( script::BasicErrorException, uno::RuntimeException )
{
	sal_Int32 nReturnType = 0;
	if ( mxSheetCondition->getOperator() == sheet::ConditionOperator_FORMULA)
		nReturnType = excel::XlFormatConditionType::xlExpression;
	else
		nReturnType = excel::XlFormatConditionType::xlCellValue;
	return nReturnType;
}


::sal_Int32 
ScVbaFormatCondition::Operator( sal_Bool bVal ) throw (script::BasicErrorException )
{
	return ScVbaFormatCondition_BASE::Operator( bVal );
}
::sal_Int32 SAL_CALL 
ScVbaFormatCondition::Operator(  ) throw (script::BasicErrorException, uno::RuntimeException)
{
	return ScVbaFormatCondition_BASE::Operator( sal_True );
}

void 
ScVbaFormatCondition::notifyRange() throw ( script::BasicErrorException )
{
	try
	{
		mxParentRangePropertySet->setPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("ConditionalFormat") ), uno::makeAny( mxSheetConditionalEntries) );
    }
	catch (uno::Exception& )
	{
        DebugHelper::exception(SbERR_METHOD_FAILED, rtl::OUString() );
    }
}

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

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