/**************************************************************
 * 
 * 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 "XMLImageMapContext.hxx"
#include <rtl/ustrbuf.hxx>
#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XPropertySetInfo.hpp>
#include <com/sun/star/xml/sax/XAttributeList.hpp>
#include <com/sun/star/container/XIndexContainer.hpp>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/drawing/PointSequenceSequence.hpp>
#include <com/sun/star/document/XEventsSupplier.hpp>
#include <com/sun/star/awt/Rectangle.hpp>
#include <xmloff/xmltoken.hxx>
#include <xmloff/xmlimp.hxx>
#include <xmloff/xmltkmap.hxx>
#include "xmloff/xmlnmspe.hxx"
#include <xmloff/nmspmap.hxx>
#include <xmloff/xmluconv.hxx>
#include "xexptran.hxx"
#include "xmloff/xmlerror.hxx"
#include <xmloff/XMLEventsImportContext.hxx>
#include "XMLStringBufferImportContext.hxx"
#include <tools/debug.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>

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

using ::rtl::OUString;
using ::rtl::OUStringBuffer;
using ::com::sun::star::beans::XPropertySet;
using ::com::sun::star::beans::XPropertySetInfo;
using ::com::sun::star::container::XIndexContainer;
using ::com::sun::star::lang::XMultiServiceFactory;
using ::com::sun::star::uno::Reference;
using ::com::sun::star::uno::UNO_QUERY;
using ::com::sun::star::xml::sax::XAttributeList;
using ::com::sun::star::uno::XInterface;
using ::com::sun::star::uno::Any;
using ::com::sun::star::drawing::PointSequenceSequence;
using ::com::sun::star::document::XEventsSupplier;


enum XMLImageMapToken 
{
	XML_TOK_IMAP_URL,
	XML_TOK_IMAP_X,
	XML_TOK_IMAP_Y,
	XML_TOK_IMAP_CENTER_X,
	XML_TOK_IMAP_CENTER_Y,
	XML_TOK_IMAP_WIDTH,
	XML_TOK_IMAP_HEIGTH,
	XML_TOK_IMAP_POINTS,
	XML_TOK_IMAP_VIEWBOX,
	XML_TOK_IMAP_NOHREF,
	XML_TOK_IMAP_NAME,
	XML_TOK_IMAP_RADIUS,
	XML_TOK_IMAP_TARGET
};

static __FAR_DATA SvXMLTokenMapEntry aImageMapObjectTokenMap[] =
{
	{ XML_NAMESPACE_XLINK,	XML_HREF,			XML_TOK_IMAP_URL 			},
	{ XML_NAMESPACE_OFFICE,	XML_NAME,			XML_TOK_IMAP_NAME			},
	{ XML_NAMESPACE_DRAW,	XML_NOHREF, 		XML_TOK_IMAP_NOHREF			},
	{ XML_NAMESPACE_SVG,	XML_X,				XML_TOK_IMAP_X				},
	{ XML_NAMESPACE_SVG,	XML_Y,				XML_TOK_IMAP_Y				},
	{ XML_NAMESPACE_SVG,	XML_CX,			    XML_TOK_IMAP_CENTER_X		},
	{ XML_NAMESPACE_SVG,	XML_CY,			    XML_TOK_IMAP_CENTER_Y		},
	{ XML_NAMESPACE_SVG,	XML_WIDTH,			XML_TOK_IMAP_WIDTH			},
	{ XML_NAMESPACE_SVG,	XML_HEIGHT,		    XML_TOK_IMAP_HEIGTH			},
	{ XML_NAMESPACE_SVG,	XML_R,				XML_TOK_IMAP_RADIUS			},
	{ XML_NAMESPACE_SVG,	XML_VIEWBOX,		XML_TOK_IMAP_VIEWBOX		},
	{ XML_NAMESPACE_DRAW,	XML_POINTS,		    XML_TOK_IMAP_POINTS			},
	{ XML_NAMESPACE_OFFICE, XML_TARGET_FRAME_NAME, XML_TOK_IMAP_TARGET		},
	XML_TOKEN_MAP_END
};



class XMLImageMapObjectContext : public SvXMLImportContext
{

protected:

	const ::rtl::OUString sBoundary;
	const ::rtl::OUString sCenter;
	const ::rtl::OUString sTitle;
	const ::rtl::OUString sDescription;
	const ::rtl::OUString sImageMap;
	const ::rtl::OUString sIsActive;
	const ::rtl::OUString sName;
	const ::rtl::OUString sPolygon;
	const ::rtl::OUString sRadius;
	const ::rtl::OUString sTarget;
	const ::rtl::OUString sURL;

	::rtl::OUString sServiceName;

	Reference<XIndexContainer> xImageMap;	/// the image map
	Reference<XPropertySet> xMapEntry;		/// one map-entry (one area)

	::rtl::OUString sUrl;
	::rtl::OUString sTargt;
	::rtl::OUStringBuffer sDescriptionBuffer;
	::rtl::OUStringBuffer sTitleBuffer;
	::rtl::OUString sNam;
	sal_Bool bIsActive;

	sal_Bool bValid;

public:
	TYPEINFO();

	XMLImageMapObjectContext(
		SvXMLImport& rImport,
		sal_uInt16 nPrefix,
		const ::rtl::OUString& rLocalName,
		::com::sun::star::uno::Reference<
			::com::sun::star::container::XIndexContainer> xMap,
		const sal_Char* pServiceName);

	void StartElement( 
		const ::com::sun::star::uno::Reference<
		::com::sun::star::xml::sax::XAttributeList >& xAttrList );

	void EndElement();

	SvXMLImportContext *CreateChildContext( 
		sal_uInt16 nPrefix,
		const ::rtl::OUString& rLocalName,
		const ::com::sun::star::uno::Reference<
			::com::sun::star::xml::sax::XAttributeList> & xAttrList );

protected:
	
	virtual void ProcessAttribute(
		enum XMLImageMapToken eToken,
		const ::rtl::OUString& rValue);

	virtual void Prepare(
		::com::sun::star::uno::Reference<
			::com::sun::star::beans::XPropertySet> & rPropertySet);
};


TYPEINIT1( XMLImageMapObjectContext, SvXMLImportContext );

XMLImageMapObjectContext::XMLImageMapObjectContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	Reference<XIndexContainer> xMap,
	const sal_Char* pServiceName) :
		SvXMLImportContext(rImport, nPrefix, rLocalName),
		sBoundary(RTL_CONSTASCII_USTRINGPARAM("Boundary")),
		sCenter(RTL_CONSTASCII_USTRINGPARAM("Center")),
		sTitle(RTL_CONSTASCII_USTRINGPARAM("Title")),
		sDescription(RTL_CONSTASCII_USTRINGPARAM("Description")),
		sImageMap(RTL_CONSTASCII_USTRINGPARAM("ImageMap")),
		sIsActive(RTL_CONSTASCII_USTRINGPARAM("IsActive")),
		sName(RTL_CONSTASCII_USTRINGPARAM("Name")),
		sPolygon(RTL_CONSTASCII_USTRINGPARAM("Polygon")),
		sRadius(RTL_CONSTASCII_USTRINGPARAM("Radius")),
		sTarget(RTL_CONSTASCII_USTRINGPARAM("Target")),
		sURL(RTL_CONSTASCII_USTRINGPARAM("URL")),
		xImageMap(xMap),
		bIsActive(sal_True),
		bValid(sal_False)
{
	DBG_ASSERT(NULL != pServiceName, 
			   "Please supply the image map object service name");

	Reference<XMultiServiceFactory> xFactory(GetImport().GetModel(),UNO_QUERY);
	if( xFactory.is() )
	{
		Reference<XInterface> xIfc = xFactory->createInstance(
			OUString::createFromAscii(pServiceName));
		DBG_ASSERT(xIfc.is(), "can't create image map object!");
		if( xIfc.is() )
		{
			Reference<XPropertySet> xPropertySet( xIfc, UNO_QUERY );

			xMapEntry = xPropertySet;
		}
		// else: can't create service -> ignore
	}
	// else: can't even get factory -> ignore
}

void XMLImageMapObjectContext::StartElement( 
	const Reference<XAttributeList >& xAttrList )
{
	SvXMLTokenMap aMap(aImageMapObjectTokenMap);

	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 );
		OUString sValue = xAttrList->getValueByIndex(nAttr);

		ProcessAttribute(
			(enum XMLImageMapToken)aMap.Get(nPrefix, sLocalName), sValue);
	}
}

void XMLImageMapObjectContext::EndElement()
{
	// only create and insert image map object if validity flag is set
	// (and we actually have an image map)
	if ( bValid && xImageMap.is() && xMapEntry.is() )
	{
		// set values
		Prepare( xMapEntry );

		// insert into image map
		Any aAny;
		aAny <<= xMapEntry;
		xImageMap->insertByIndex( xImageMap->getCount(), aAny );
	}
	// else: not valid -> don't create and insert
}

SvXMLImportContext* XMLImageMapObjectContext::CreateChildContext( 
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	const Reference<XAttributeList> & xAttrList )
{
	if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
		 IsXMLToken(rLocalName, XML_EVENT_LISTENERS) )
	{
		Reference<XEventsSupplier> xEvents( xMapEntry, UNO_QUERY );
		return new XMLEventsImportContext(
			GetImport(), nPrefix, rLocalName, xEvents);
	}
	else if ( (XML_NAMESPACE_SVG == nPrefix) &&
			  IsXMLToken(rLocalName, XML_TITLE) )
	{
		return new XMLStringBufferImportContext(
			GetImport(), nPrefix, rLocalName, sTitleBuffer);
	}
	else if ( (XML_NAMESPACE_SVG == nPrefix) &&
			  IsXMLToken(rLocalName, XML_DESC) )
	{
		return new XMLStringBufferImportContext(
			GetImport(), nPrefix, rLocalName, sDescriptionBuffer);
	}
	else
		return SvXMLImportContext::CreateChildContext(nPrefix, rLocalName, 
													  xAttrList);

}

void XMLImageMapObjectContext::ProcessAttribute(
	enum XMLImageMapToken eToken,
	const OUString& rValue)
{
	switch (eToken)
	{
		case XML_TOK_IMAP_URL:
			sUrl = GetImport().GetAbsoluteReference(rValue);
			break;

		case XML_TOK_IMAP_TARGET:
			sTargt = rValue;
			break;

		case XML_TOK_IMAP_NOHREF:
			bIsActive = ! IsXMLToken(rValue, XML_NOHREF);
			break;
				
		case XML_TOK_IMAP_NAME:
			sNam = rValue;
			break;
		default:
			// do nothing
			break;
	}
}

void XMLImageMapObjectContext::Prepare(
	Reference<XPropertySet> & rPropertySet)
{
	rPropertySet->setPropertyValue( sURL, Any( sUrl ) );
	rPropertySet->setPropertyValue( sTitle, Any( sTitleBuffer.makeStringAndClear() ) );
	rPropertySet->setPropertyValue( sDescription, Any( sDescriptionBuffer.makeStringAndClear() ) );
	rPropertySet->setPropertyValue( sTarget, Any( sTargt ) );
	rPropertySet->setPropertyValue( sIsActive, Any( bIsActive ) );
	rPropertySet->setPropertyValue( sName, Any( sNam ) );
}



class XMLImageMapRectangleContext : public XMLImageMapObjectContext
{
	awt::Rectangle aRectangle;

	sal_Bool bXOK;
	sal_Bool bYOK;
	sal_Bool bWidthOK;
	sal_Bool bHeightOK;

public:
	TYPEINFO();

	XMLImageMapRectangleContext(
		SvXMLImport& rImport,
		sal_uInt16 nPrefix,
		const ::rtl::OUString& rLocalName,
		::com::sun::star::uno::Reference<
			::com::sun::star::container::XIndexContainer> xMap);

	virtual ~XMLImageMapRectangleContext();

protected:
	virtual void ProcessAttribute(
		enum XMLImageMapToken eToken,
		const ::rtl::OUString& rValue);

	virtual void Prepare(
		::com::sun::star::uno::Reference<
			::com::sun::star::beans::XPropertySet> & rPropertySet);
};



TYPEINIT1(XMLImageMapRectangleContext, XMLImageMapObjectContext);

XMLImageMapRectangleContext::XMLImageMapRectangleContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	Reference<XIndexContainer> xMap) :
		XMLImageMapObjectContext(rImport, nPrefix, rLocalName, xMap,
								 "com.sun.star.image.ImageMapRectangleObject"),
		bXOK(sal_False),
		bYOK(sal_False),
		bWidthOK(sal_False),
		bHeightOK(sal_False)
{
}

XMLImageMapRectangleContext::~XMLImageMapRectangleContext()
{
}

void XMLImageMapRectangleContext::ProcessAttribute(
	enum XMLImageMapToken eToken,
	const OUString& rValue)
{
	sal_Int32 nTmp;
	switch (eToken)
	{
		case XML_TOK_IMAP_X:
			if (GetImport().GetMM100UnitConverter().convertMeasure(nTmp, 
																   rValue))
			{
				aRectangle.X = nTmp;
				bXOK = sal_True;
			}
			break;
		case XML_TOK_IMAP_Y:
			if (GetImport().GetMM100UnitConverter().convertMeasure(nTmp, 
																   rValue))
			{
				aRectangle.Y = nTmp;
				bYOK = sal_True;
			}
			break;
		case XML_TOK_IMAP_WIDTH:
			if (GetImport().GetMM100UnitConverter().convertMeasure(nTmp, 
																   rValue))
			{
				aRectangle.Width = nTmp;
				bWidthOK = sal_True;
			}
			break;
		case XML_TOK_IMAP_HEIGTH:
			if (GetImport().GetMM100UnitConverter().convertMeasure(nTmp, 
																   rValue))
			{
				aRectangle.Height = nTmp;
				bHeightOK = sal_True;
			}
			break;
		default:
			XMLImageMapObjectContext::ProcessAttribute(eToken, rValue);
	}

	bValid = bHeightOK && bXOK && bYOK && bWidthOK;
}

void XMLImageMapRectangleContext::Prepare(
	Reference<XPropertySet> & rPropertySet)
{
	Any aAny;
	aAny <<= aRectangle;
	rPropertySet->setPropertyValue( sBoundary, aAny );

	// common properties handled by super class
	XMLImageMapObjectContext::Prepare(rPropertySet);
}


class XMLImageMapPolygonContext : public XMLImageMapObjectContext
{
	::rtl::OUString sViewBoxString;
	::rtl::OUString sPointsString;

	sal_Bool bViewBoxOK;
	sal_Bool bPointsOK;

public:
	TYPEINFO();

	XMLImageMapPolygonContext(
		SvXMLImport& rImport,
		sal_uInt16 nPrefix,
		const ::rtl::OUString& rLocalName,
		::com::sun::star::uno::Reference<
			::com::sun::star::container::XIndexContainer> xMap);

	virtual ~XMLImageMapPolygonContext();

protected:
	virtual void ProcessAttribute(
		enum XMLImageMapToken eToken,
		const ::rtl::OUString& rValue);

	virtual void Prepare(
		::com::sun::star::uno::Reference<
			::com::sun::star::beans::XPropertySet> & rPropertySet);
};



TYPEINIT1(XMLImageMapPolygonContext, XMLImageMapObjectContext);

XMLImageMapPolygonContext::XMLImageMapPolygonContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	Reference<XIndexContainer> xMap) :
		XMLImageMapObjectContext(rImport, nPrefix, rLocalName, xMap,
								 "com.sun.star.image.ImageMapPolygonObject"),
		bViewBoxOK(sal_False),
		bPointsOK(sal_False)
{
}

XMLImageMapPolygonContext::~XMLImageMapPolygonContext()
{
}

void XMLImageMapPolygonContext::ProcessAttribute(
	enum XMLImageMapToken eToken,
	const OUString& rValue)
{
	switch (eToken)
	{
		case XML_TOK_IMAP_POINTS:
			sPointsString = rValue;
			bPointsOK = sal_True;
			break;
		case XML_TOK_IMAP_VIEWBOX:
			sViewBoxString = rValue;
			bViewBoxOK = sal_True;
			break;
		default:
			XMLImageMapObjectContext::ProcessAttribute(eToken, rValue);
			break;
	}

	bValid = bViewBoxOK && bPointsOK;
}

void XMLImageMapPolygonContext::Prepare(Reference<XPropertySet> & rPropertySet)
{
    // process view box
    SdXMLImExViewBox aViewBox(sViewBoxString, GetImport().GetMM100UnitConverter());

    // get polygon sequence
    basegfx::B2DPolygon aPolygon;

    if(basegfx::tools::importFromSvgPoints(aPolygon, sPointsString))
    {
        if(aPolygon.count())
        {
            com::sun::star::drawing::PointSequence aPointSequence;
            uno::Any aAny;

            basegfx::tools::B2DPolygonToUnoPointSequence(aPolygon, aPointSequence);
            aAny <<= aPointSequence;
            rPropertySet->setPropertyValue(sPolygon, aAny);
        }
    }

    // parent properties
    XMLImageMapObjectContext::Prepare(rPropertySet);
}

class XMLImageMapCircleContext : public XMLImageMapObjectContext
{
	awt::Point aCenter;
	sal_Int32 nRadius;

	sal_Bool bXOK;
	sal_Bool bYOK;
	sal_Bool bRadiusOK;

public:
	TYPEINFO();

	XMLImageMapCircleContext(
		SvXMLImport& rImport,
		sal_uInt16 nPrefix,
		const ::rtl::OUString& rLocalName,
		::com::sun::star::uno::Reference<
			::com::sun::star::container::XIndexContainer> xMap);

	virtual ~XMLImageMapCircleContext();

protected:
	virtual void ProcessAttribute(
		enum XMLImageMapToken eToken,
		const ::rtl::OUString& rValue);

	virtual void Prepare(
		::com::sun::star::uno::Reference<
			::com::sun::star::beans::XPropertySet> & rPropertySet);
};

TYPEINIT1(XMLImageMapCircleContext, XMLImageMapObjectContext);

XMLImageMapCircleContext::XMLImageMapCircleContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	Reference<XIndexContainer> xMap) :
		XMLImageMapObjectContext(rImport, nPrefix, rLocalName, xMap,
								 "com.sun.star.image.ImageMapCircleObject"),
		bXOK(sal_False),
		bYOK(sal_False),
		bRadiusOK(sal_False)
{
}

XMLImageMapCircleContext::~XMLImageMapCircleContext()
{
}

void XMLImageMapCircleContext::ProcessAttribute(
	enum XMLImageMapToken eToken,
	const OUString& rValue)
{
	sal_Int32 nTmp;
	switch (eToken)
	{
		case XML_TOK_IMAP_CENTER_X:
			if (GetImport().GetMM100UnitConverter().convertMeasure(nTmp, 
																   rValue))
			{
				aCenter.X = nTmp;
				bXOK = sal_True;
			}
			break;
		case XML_TOK_IMAP_CENTER_Y:
			if (GetImport().GetMM100UnitConverter().convertMeasure(nTmp, 
																   rValue))
			{
				aCenter.Y = nTmp;
				bYOK = sal_True;
			}
			break;
		case XML_TOK_IMAP_RADIUS:
			if (GetImport().GetMM100UnitConverter().convertMeasure(nTmp, 
																   rValue))
			{
				nRadius = nTmp;
				bRadiusOK = sal_True;
			}
			break;
		default:
			XMLImageMapObjectContext::ProcessAttribute(eToken, rValue);
	}

	bValid = bRadiusOK && bXOK && bYOK;
}

void XMLImageMapCircleContext::Prepare(
	Reference<XPropertySet> & rPropertySet)
{
	// center (x,y)
	Any aAny;
	aAny <<= aCenter;
	rPropertySet->setPropertyValue( sCenter, aAny );

	// radius
	aAny <<= nRadius;
	rPropertySet->setPropertyValue( sRadius, aAny );

	// common properties handled by super class
	XMLImageMapObjectContext::Prepare(rPropertySet);
}










TYPEINIT1(XMLImageMapContext, SvXMLImportContext);

XMLImageMapContext::XMLImageMapContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	Reference<XPropertySet> & rPropertySet) :
		SvXMLImportContext(rImport, nPrefix, rLocalName),
		sImageMap(RTL_CONSTASCII_USTRINGPARAM("ImageMap")),
		xPropertySet(rPropertySet)

{
	try
	{
		Reference < XPropertySetInfo > xInfo = 
			xPropertySet->getPropertySetInfo();
		if( xInfo.is() && xInfo->hasPropertyByName( sImageMap ) )
			xPropertySet->getPropertyValue(sImageMap) >>= xImageMap;
	}
	catch( com::sun::star::uno::Exception e )
	{
		uno::Sequence<OUString> aSeq(0);
        rImport.SetError( XMLERROR_FLAG_WARNING | XMLERROR_API, aSeq, e.Message, NULL );
	}
}

XMLImageMapContext::~XMLImageMapContext()
{
}

SvXMLImportContext *XMLImageMapContext::CreateChildContext( 
	sal_uInt16 nPrefix,
	const OUString& rLocalName,
	const Reference<XAttributeList> & xAttrList )
{
	SvXMLImportContext* pContext = NULL;

	if ( XML_NAMESPACE_DRAW == nPrefix )
	{
		if ( IsXMLToken(rLocalName, XML_AREA_RECTANGLE) )
		{
			pContext = new XMLImageMapRectangleContext(
				GetImport(), nPrefix, rLocalName, xImageMap);
		}
		else if ( IsXMLToken(rLocalName, XML_AREA_POLYGON) )
		{
			pContext = new XMLImageMapPolygonContext(
				GetImport(), nPrefix, rLocalName, xImageMap);
		}
		else if ( IsXMLToken(rLocalName, XML_AREA_CIRCLE) )
		{
			pContext = new XMLImageMapCircleContext(
				GetImport(), nPrefix, rLocalName, xImageMap);
		}
	}
	else
		pContext = SvXMLImportContext::CreateChildContext(nPrefix, rLocalName, 
														  xAttrList);

	return pContext;
}

void XMLImageMapContext::EndElement()
{
	Reference < XPropertySetInfo > xInfo = 
		xPropertySet->getPropertySetInfo();
	if( xInfo.is() && xInfo->hasPropertyByName( sImageMap ) )
		xPropertySet->setPropertyValue(sImageMap, uno::makeAny( xImageMap ) );
}

