/**************************************************************
 *
 * 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 "XMLSectionSourceDDEImportContext.hxx"
#include "XMLSectionImportContext.hxx"
#include <com/sun/star/text/SectionFileLink.hpp>
#include <xmloff/xmlictxt.hxx>
#include <xmloff/xmlimp.hxx>
#include <xmloff/txtimp.hxx>
#include <xmloff/nmspmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmluconv.hxx>
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XMultiPropertySet.hpp>
#include <tools/debug.hxx>

using ::rtl::OUString;
using ::com::sun::star::beans::XPropertySet;
using ::com::sun::star::beans::XMultiPropertySet;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::xml::sax::XAttributeList;

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

const sal_Char sAPI_DDECommandFile[] = "DDECommandFile";
const sal_Char sAPI_DDECommandType[] = "DDECommandType";
const sal_Char sAPI_DDECommandElement[] = "DDECommandElement";
const sal_Char sAPI_IsAutomaticUpdate[] = "IsAutomaticUpdate";


TYPEINIT1(XMLSectionSourceDDEImportContext, SvXMLImportContext);

XMLSectionSourceDDEImportContext::XMLSectionSourceDDEImportContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	Reference<XPropertySet> & rSectPropSet) :
		SvXMLImportContext(rImport, nPrfx, rLocalName),
		rSectionPropertySet(rSectPropSet),
		sDdeCommandFile(RTL_CONSTASCII_USTRINGPARAM(sAPI_DDECommandFile)),
		sDdeCommandType(RTL_CONSTASCII_USTRINGPARAM(sAPI_DDECommandType)),
	   sDdeCommandElement(RTL_CONSTASCII_USTRINGPARAM(sAPI_DDECommandElement)),
		sIsAutomaticUpdate(RTL_CONSTASCII_USTRINGPARAM(sAPI_IsAutomaticUpdate))
{
}

XMLSectionSourceDDEImportContext::~XMLSectionSourceDDEImportContext()
{
}

enum XMLSectionSourceDDEToken
{
	XML_TOK_SECTION_DDE_APPLICATION,
	XML_TOK_SECTION_DDE_TOPIC,
	XML_TOK_SECTION_DDE_ITEM,
	XML_TOK_SECTION_IS_AUTOMATIC_UPDATE
};

static __FAR_DATA SvXMLTokenMapEntry aSectionSourceDDETokenMap[] =
{
	{ XML_NAMESPACE_OFFICE, XML_DDE_APPLICATION,
		  XML_TOK_SECTION_DDE_APPLICATION },
	{ XML_NAMESPACE_OFFICE, XML_DDE_TOPIC, XML_TOK_SECTION_DDE_TOPIC },
	{ XML_NAMESPACE_OFFICE, XML_DDE_ITEM, XML_TOK_SECTION_DDE_ITEM },
	{ XML_NAMESPACE_OFFICE, XML_AUTOMATIC_UPDATE,
		  XML_TOK_SECTION_IS_AUTOMATIC_UPDATE },
	XML_TOKEN_MAP_END
};


void XMLSectionSourceDDEImportContext::StartElement(
	const Reference<XAttributeList> & xAttrList)
{
	SvXMLTokenMap aTokenMap(aSectionSourceDDETokenMap);
	OUString sApplication;
	OUString sTopic;
	OUString sItem;
	sal_Bool bAutomaticUpdate = sal_False;

	sal_Int16 nLength = xAttrList->getLength();
	for(sal_Int16 nAttr = 0; nAttr < nLength; nAttr++)
	{
		OUString sLocalName;
		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().
			GetKeyByAttrName( xAttrList->getNameByIndex(nAttr),
							  &sLocalName );

		switch (aTokenMap.Get(nPrefix, sLocalName))
		{
			case XML_TOK_SECTION_DDE_APPLICATION:
				sApplication = xAttrList->getValueByIndex(nAttr);
				break;
			case XML_TOK_SECTION_DDE_TOPIC:
				sTopic = xAttrList->getValueByIndex(nAttr);
				break;
			case XML_TOK_SECTION_DDE_ITEM:
				sItem = xAttrList->getValueByIndex(nAttr);
				break;
			case XML_TOK_SECTION_IS_AUTOMATIC_UPDATE:
			{
				sal_Bool bTmp;
				if (SvXMLUnitConverter::convertBool(
					bTmp, xAttrList->getValueByIndex(nAttr)))
				{
					bAutomaticUpdate = bTmp;
				}
				break;
			}
			default:
				; // ignore
				break;
		}
	}

	// DDE not supported on all platforms; query property first
	if (rSectionPropertySet->getPropertySetInfo()->
		hasPropertyByName(sDdeCommandFile))
	{
		// use multi property set to force single update of connection #83654#
		Sequence<OUString> aNames(4);
		Sequence<Any> aValues(4);

		aValues[0] <<= sApplication;
		aNames[0] = sDdeCommandFile;

		aValues[1] <<= sTopic;
		aNames[1] = sDdeCommandType;

		aValues[2] <<= sItem;
		aNames[2] = sDdeCommandElement;

		aValues[3].setValue(&bAutomaticUpdate, ::getBooleanCppuType());
		aNames[3] = sIsAutomaticUpdate;

		Reference<XMultiPropertySet> rMultiPropSet(rSectionPropertySet,
												   UNO_QUERY);
		DBG_ASSERT(rMultiPropSet.is(), "we'd really like a XMultiPropertySet");
		if (rMultiPropSet.is())
			rMultiPropSet->setPropertyValues(aNames, aValues);
		// else: ignore
	}
}

void XMLSectionSourceDDEImportContext::EndElement()
{
	// nothing to be done!
}

SvXMLImportContext* XMLSectionSourceDDEImportContext::CreateChildContext(
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	const Reference<XAttributeList> & )
{
	// ignore -> default context
	return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
}
