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

#include "xmloff/numehelp.hxx"

#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmluconv.hxx>
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmlexp.hxx>
#include <com/sun/star/uno/Reference.h>
#include <rtl/ustring.hxx>
#include <svl/zforlist.hxx>
#include <com/sun/star/util/NumberFormat.hpp>
#include <rtl/math.hxx>
#include <tools/debug.hxx>
#include <rtl/ustrbuf.hxx>

using namespace com::sun::star;
using namespace xmloff::token;

#define XML_TYPE "Type"
#define XML_CURRENCYSYMBOL "CurrencySymbol"
#define XML_CURRENCYABBREVIATION "CurrencyAbbreviation"
#define XML_STANDARDFORMAT "StandardFormat"

XMLNumberFormatAttributesExportHelper::XMLNumberFormatAttributesExportHelper(
			::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >& xTempNumberFormatsSupplier)
	: xNumberFormats(xTempNumberFormatsSupplier.is() ? xTempNumberFormatsSupplier->getNumberFormats() : ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormats > ()),
	pExport(NULL),
    sStandardFormat(RTL_CONSTASCII_USTRINGPARAM(XML_STANDARDFORMAT)),
    sType(RTL_CONSTASCII_USTRINGPARAM(XML_TYPE)),
    msCurrencySymbol(RTL_CONSTASCII_USTRINGPARAM(XML_CURRENCYSYMBOL)),
    msCurrencyAbbreviation(RTL_CONSTASCII_USTRINGPARAM(XML_CURRENCYABBREVIATION)),
	aNumberFormats()
{
}

XMLNumberFormatAttributesExportHelper::XMLNumberFormatAttributesExportHelper(
            ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >& xTempNumberFormatsSupplier,
            SvXMLExport& rTempExport )
:	xNumberFormats(xTempNumberFormatsSupplier.is() ? xTempNumberFormatsSupplier->getNumberFormats() : ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormats > ()),
	pExport(&rTempExport),
    sStandardFormat(RTL_CONSTASCII_USTRINGPARAM(XML_STANDARDFORMAT)),
    sType(RTL_CONSTASCII_USTRINGPARAM(XML_TYPE)),
    sAttrValueType(rTempExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_VALUE_TYPE))),
    sAttrValue(rTempExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_VALUE))),
	sAttrDateValue(rTempExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_DATE_VALUE))),
    sAttrTimeValue(rTempExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_TIME_VALUE))),
	sAttrBooleanValue(rTempExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_BOOLEAN_VALUE))),
    sAttrStringValue(rTempExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_STRING_VALUE))),
	sAttrCurrency(rTempExport.GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OFFICE, GetXMLToken(XML_CURRENCY))),
    msCurrencySymbol(RTL_CONSTASCII_USTRINGPARAM(XML_CURRENCYSYMBOL)),
    msCurrencyAbbreviation(RTL_CONSTASCII_USTRINGPARAM(XML_CURRENCYABBREVIATION)),
    aNumberFormats()
{
}

XMLNumberFormatAttributesExportHelper::~XMLNumberFormatAttributesExportHelper()
{
}

sal_Int16 XMLNumberFormatAttributesExportHelper::GetCellType(const sal_Int32 nNumberFormat, rtl::OUString& sCurrency, sal_Bool& bIsStandard)
{
	XMLNumberFormat aFormat(sEmpty, nNumberFormat, 0);
	XMLNumberFormatSet::iterator aItr(aNumberFormats.find(aFormat));
    XMLNumberFormatSet::iterator aEndItr(aNumberFormats.end());
	if (aItr != aEndItr)
	{
		bIsStandard = aItr->bIsStandard;
		sCurrency = aItr->sCurrency;
		return aItr->nType;
	}
	else
	{
		aFormat.nType = GetCellType(nNumberFormat, bIsStandard);
		aFormat.bIsStandard = bIsStandard;
        if ((aFormat.nType & ~util::NumberFormat::DEFINED) == util::NumberFormat::CURRENCY)
			if (GetCurrencySymbol(nNumberFormat, aFormat.sCurrency))
				sCurrency = aFormat.sCurrency;
		aNumberFormats.insert(aFormat);
		return aFormat.nType;
	}
}

void XMLNumberFormatAttributesExportHelper::WriteAttributes(SvXMLExport& rXMLExport,
								const sal_Int16 nTypeKey,
								const double& rValue,
								const rtl::OUString& rCurrency,
								sal_Bool bExportValue)
{
	sal_Bool bWasSetTypeAttribute = sal_False;
	switch(nTypeKey & ~util::NumberFormat::DEFINED)
	{
	case 0:
	case util::NumberFormat::NUMBER:
	case util::NumberFormat::SCIENTIFIC:
	case util::NumberFormat::FRACTION:
		{
			if (!bWasSetTypeAttribute)
			{
				rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
				bWasSetTypeAttribute = sal_True;
			}
		}		// No Break
	case util::NumberFormat::PERCENT:
		{
			if (!bWasSetTypeAttribute)
			{
				rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_PERCENTAGE);
				bWasSetTypeAttribute = sal_True;
			}
		}		// No Break
	case util::NumberFormat::CURRENCY:
		{
			if (!bWasSetTypeAttribute)
			{
				rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_CURRENCY);
				if (rCurrency.getLength() > 0)
					rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_CURRENCY, rCurrency);
				bWasSetTypeAttribute = sal_True;
			}

			if (bExportValue)
			{
                rtl::OUString sValue( ::rtl::math::doubleToUString( rValue,
                            rtl_math_StringFormat_Automatic,
                            rtl_math_DecimalPlaces_Max, '.', sal_True));
				rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, sValue);
			}
		}
		break;
	case util::NumberFormat::DATE:
	case util::NumberFormat::DATETIME:
		{
			if (!bWasSetTypeAttribute)
			{
				rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_DATE);
				bWasSetTypeAttribute = sal_True;
			}
			if (bExportValue)
			{
                if ( rXMLExport.SetNullDateOnUnitConverter() )
				{
					rtl::OUStringBuffer sBuffer;
					rXMLExport.GetMM100UnitConverter().convertDateTime(sBuffer, rValue);
					rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_DATE_VALUE, sBuffer.makeStringAndClear());
				}
			}
		}
		break;
	case util::NumberFormat::TIME:
		{
			if (!bWasSetTypeAttribute)
			{
				rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_TIME);
				bWasSetTypeAttribute = sal_True;
			}
			if (bExportValue)
			{
				rtl::OUStringBuffer sBuffer;
				rXMLExport.GetMM100UnitConverter().convertTime(sBuffer, rValue);
				rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_TIME_VALUE, sBuffer.makeStringAndClear());
			}
		}
		break;
	case util::NumberFormat::LOGICAL:
		{
			if (!bWasSetTypeAttribute)
			{
				rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_BOOLEAN);
				bWasSetTypeAttribute = sal_True;
			}
			if (bExportValue)
			{
				double fTempValue = rValue;
				if (::rtl::math::approxEqual( fTempValue, 1.0 ))
				{
					rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE, XML_TRUE);
				}
				else
				{
					if (::rtl::math::approxEqual( rValue, 0.0 ))
					{
						rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE, XML_FALSE);
					}
					else
					{
                        rtl::OUString sValue( ::rtl::math::doubleToUString(
                                    fTempValue,
                                    rtl_math_StringFormat_Automatic,
                                    rtl_math_DecimalPlaces_Max, '.',
                                    sal_True));
						rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_BOOLEAN_VALUE, sValue);
					}
				}
			}
		}
		break;
	case util::NumberFormat::TEXT:
		{
			if (!bWasSetTypeAttribute)
			{
				rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_FLOAT);
				bWasSetTypeAttribute = sal_True;
				if (bExportValue)
				{
                    rtl::OUString sValue( ::rtl::math::doubleToUString( rValue,
                                rtl_math_StringFormat_Automatic,
                                rtl_math_DecimalPlaces_Max, '.', sal_True));
					rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE, sValue);
				}
			}
		}
		break;
	}
}

sal_Bool XMLNumberFormatAttributesExportHelper::GetCurrencySymbol(const sal_Int32 nNumberFormat, rtl::OUString& sCurrencySymbol,
	uno::Reference <util::XNumberFormatsSupplier>& xNumberFormatsSupplier)
{
	if (xNumberFormatsSupplier.is())
	{
		uno::Reference <util::XNumberFormats> xNumberFormats(xNumberFormatsSupplier->getNumberFormats());
		if (xNumberFormats.is())
		{
			try
			{
				uno::Reference <beans::XPropertySet> xNumberPropertySet(xNumberFormats->getByKey(nNumberFormat));
				if ( xNumberPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_CURRENCYSYMBOL))) >>= sCurrencySymbol)
				{
					rtl::OUString sCurrencyAbbreviation;
					if ( xNumberPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_CURRENCYABBREVIATION))) >>= sCurrencyAbbreviation)
					{
						if ( sCurrencyAbbreviation.getLength() != 0 )
							sCurrencySymbol = sCurrencyAbbreviation;
						else
						{
							if ( sCurrencySymbol.getLength() == 1 && sCurrencySymbol.toChar() == NfCurrencyEntry::GetEuroSymbol() )
								sCurrencySymbol = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EUR"));
						}
					}
					return sal_True;
				}
			}
			catch ( uno::Exception& )
			{
				DBG_ERROR("Numberformat not found");
			}
		}
	}
	return sal_False;
}


sal_Int16 XMLNumberFormatAttributesExportHelper::GetCellType(const sal_Int32 nNumberFormat, sal_Bool& bIsStandard,
	uno::Reference <util::XNumberFormatsSupplier>& xNumberFormatsSupplier)
{
	if (xNumberFormatsSupplier.is())
	{
		uno::Reference <util::XNumberFormats> xNumberFormats(xNumberFormatsSupplier->getNumberFormats());
		if (xNumberFormats.is())
		{
			try
			{
				uno::Reference <beans::XPropertySet> xNumberPropertySet(xNumberFormats->getByKey(nNumberFormat));
				xNumberPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_STANDARDFORMAT))) >>= bIsStandard;
				sal_Int16 nNumberType = sal_Int16();
				if ( xNumberPropertySet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(XML_TYPE))) >>= nNumberType )
				{
					return nNumberType;
				}
			}
			catch ( uno::Exception& )
			{
				DBG_ERROR("Numberformat not found");
			}
		}
	}
	return 0;
}

void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(SvXMLExport& rXMLExport,
	const sal_Int32 nNumberFormat, const double& rValue, sal_Bool bExportValue)
{
	sal_Bool bIsStandard;
	sal_Int16 nTypeKey = GetCellType(nNumberFormat, bIsStandard, rXMLExport.GetNumberFormatsSupplier());
	rtl::OUString sCurrency;
    if ((nTypeKey & ~util::NumberFormat::DEFINED) == util::NumberFormat::CURRENCY)
		GetCurrencySymbol(nNumberFormat, sCurrency, rXMLExport.GetNumberFormatsSupplier());
	WriteAttributes(rXMLExport, nTypeKey, rValue, sCurrency, bExportValue);
}

void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(SvXMLExport& rXMLExport,
	const rtl::OUString& rValue, const rtl::OUString& rCharacters,
	sal_Bool bExportValue, sal_Bool bExportTypeAttribute)
{
	if (bExportTypeAttribute)
		rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_VALUE_TYPE, XML_STRING);
	if (bExportValue && rValue.getLength() && (rValue != rCharacters))
		rXMLExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_STRING_VALUE, rValue);
}

sal_Bool XMLNumberFormatAttributesExportHelper::GetCurrencySymbol(const sal_Int32 nNumberFormat, rtl::OUString& rCurrencySymbol)
{
    if (!xNumberFormats.is() && pExport && pExport->GetNumberFormatsSupplier().is())
		xNumberFormats.set(pExport->GetNumberFormatsSupplier()->getNumberFormats());

    if (xNumberFormats.is())
	{
		try
		{
			uno::Reference <beans::XPropertySet> xNumberPropertySet(xNumberFormats->getByKey(nNumberFormat));
			if ( xNumberPropertySet->getPropertyValue(msCurrencySymbol) >>= rCurrencySymbol)
			{
				rtl::OUString sCurrencyAbbreviation;
				if ( xNumberPropertySet->getPropertyValue(msCurrencyAbbreviation) >>= sCurrencyAbbreviation)
				{
					if ( sCurrencyAbbreviation.getLength() != 0 )
						rCurrencySymbol = sCurrencyAbbreviation;
					else
					{
						if ( rCurrencySymbol.getLength() == 1 && rCurrencySymbol.toChar() == NfCurrencyEntry::GetEuroSymbol() )
							rCurrencySymbol = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("EUR"));
					}
				}
				return sal_True;
			}
		}
		catch ( uno::Exception& )
		{
			DBG_ERROR("Numberformat not found");
		}
	}
	return sal_False;
}

sal_Int16 XMLNumberFormatAttributesExportHelper::GetCellType(const sal_Int32 nNumberFormat, sal_Bool& bIsStandard)
{
    if (!xNumberFormats.is() && pExport && pExport->GetNumberFormatsSupplier().is())
		xNumberFormats.set(pExport->GetNumberFormatsSupplier()->getNumberFormats());

    if (xNumberFormats.is())
	{
		try
		{
			uno::Reference <beans::XPropertySet> xNumberPropertySet(xNumberFormats->getByKey(nNumberFormat));
            if (xNumberPropertySet.is())
            {
			    xNumberPropertySet->getPropertyValue(sStandardFormat) >>= bIsStandard;
			    sal_Int16 nNumberType = sal_Int16();
			    if ( xNumberPropertySet->getPropertyValue(sType) >>= nNumberType )
			    {
				    return nNumberType;
			    }
            }
		}
		catch ( uno::Exception& )
		{
			DBG_ERROR("Numberformat not found");
		}
	}
	return 0;
}

void XMLNumberFormatAttributesExportHelper::WriteAttributes(
								const sal_Int16 nTypeKey,
								const double& rValue,
								const rtl::OUString& rCurrency,
								sal_Bool bExportValue)
{
    if (!pExport)
        return;

	sal_Bool bWasSetTypeAttribute = sal_False;
	switch(nTypeKey & ~util::NumberFormat::DEFINED)
	{
	case 0:
	case util::NumberFormat::NUMBER:
	case util::NumberFormat::SCIENTIFIC:
	case util::NumberFormat::FRACTION:
		{
			if (!bWasSetTypeAttribute)
			{
				pExport->AddAttribute(sAttrValueType, XML_FLOAT);
				bWasSetTypeAttribute = sal_True;
			}
		}		// No Break
	case util::NumberFormat::PERCENT:
		{
			if (!bWasSetTypeAttribute)
			{
				pExport->AddAttribute(sAttrValueType, XML_PERCENTAGE);
				bWasSetTypeAttribute = sal_True;
			}
		}		// No Break
	case util::NumberFormat::CURRENCY:
		{
			if (!bWasSetTypeAttribute)
			{
				pExport->AddAttribute(sAttrValueType, XML_CURRENCY);
				if (rCurrency.getLength() > 0)
					pExport->AddAttribute(sAttrCurrency, rCurrency);
				bWasSetTypeAttribute = sal_True;
			}

			if (bExportValue)
			{
                rtl::OUString sValue( ::rtl::math::doubleToUString( rValue,
                            rtl_math_StringFormat_Automatic,
                            rtl_math_DecimalPlaces_Max, '.', sal_True));
				pExport->AddAttribute(sAttrValue, sValue);
			}
		}
		break;
	case util::NumberFormat::DATE:
	case util::NumberFormat::DATETIME:
		{
			if (!bWasSetTypeAttribute)
			{
				pExport->AddAttribute(sAttrValueType, XML_DATE);
				bWasSetTypeAttribute = sal_True;
			}
			if (bExportValue)
			{
                if ( pExport->SetNullDateOnUnitConverter() )
				{
					rtl::OUStringBuffer sBuffer;
					pExport->GetMM100UnitConverter().convertDateTime(sBuffer, rValue);
					pExport->AddAttribute(sAttrDateValue, sBuffer.makeStringAndClear());
				}
			}
		}
		break;
	case util::NumberFormat::TIME:
		{
			if (!bWasSetTypeAttribute)
			{
				pExport->AddAttribute(sAttrValueType, XML_TIME);
				bWasSetTypeAttribute = sal_True;
			}
			if (bExportValue)
			{
				rtl::OUStringBuffer sBuffer;
				pExport->GetMM100UnitConverter().convertTime(sBuffer, rValue);
				pExport->AddAttribute(sAttrTimeValue, sBuffer.makeStringAndClear());
			}
		}
		break;
	case util::NumberFormat::LOGICAL:
		{
			if (!bWasSetTypeAttribute)
			{
				pExport->AddAttribute(sAttrValueType, XML_BOOLEAN);
				bWasSetTypeAttribute = sal_True;
			}
			if (bExportValue)
			{
				double fTempValue = rValue;
				if (::rtl::math::approxEqual( fTempValue, 1.0 ))
				{
					pExport->AddAttribute(sAttrBooleanValue, XML_TRUE);
				}
				else
				{
					if (::rtl::math::approxEqual( rValue, 0.0 ))
					{
						pExport->AddAttribute(sAttrBooleanValue, XML_FALSE);
					}
					else
					{
                        rtl::OUString sValue( ::rtl::math::doubleToUString(
                                    fTempValue,
                                    rtl_math_StringFormat_Automatic,
                                    rtl_math_DecimalPlaces_Max, '.',
                                    sal_True));
						pExport->AddAttribute(sAttrBooleanValue, sValue);
					}
				}
			}
		}
		break;
	case util::NumberFormat::TEXT:
		{
			if (!bWasSetTypeAttribute)
			{
				pExport->AddAttribute(sAttrValueType, XML_FLOAT);
				bWasSetTypeAttribute = sal_True;
				if (bExportValue)
				{
                    rtl::OUString sValue( ::rtl::math::doubleToUString( rValue,
                                rtl_math_StringFormat_Automatic,
                                rtl_math_DecimalPlaces_Max, '.', sal_True));
					pExport->AddAttribute(sAttrValue, sValue);
				}
			}
		}
		break;
	}
}

void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(
	const sal_Int32 nNumberFormat, const double& rValue, sal_Bool bExportValue)
{
	if (pExport)
	{
		sal_Bool bIsStandard;
		rtl::OUString sCurrency;
		sal_Int16 nTypeKey = GetCellType(nNumberFormat, sCurrency, bIsStandard);
	    WriteAttributes(nTypeKey, rValue, sCurrency, bExportValue);
	}
	else {
		DBG_ERROR("no SvXMLExport given");
    }
}

void XMLNumberFormatAttributesExportHelper::SetNumberFormatAttributes(
	const rtl::OUString& rValue, const rtl::OUString& rCharacters,
	sal_Bool bExportValue, sal_Bool bExportTypeAttribute)
{
    if (pExport)
    {
	    if (bExportTypeAttribute)
		    pExport->AddAttribute(sAttrValueType, XML_STRING);
	    if (bExportValue && rValue.getLength() && (rValue != rCharacters))
		    pExport->AddAttribute(sAttrStringValue, rValue);
    }
	else {
		DBG_ERROR("no SvXMLExport given");
    }
}
