/**************************************************************
 * 
 * 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 <comphelper/extract.hxx>
#include "ximp3dobject.hxx"
#include <xmloff/XMLShapeStyleContext.hxx>
#include <xmloff/xmluconv.hxx>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/drawing/PointSequenceSequence.hpp>
#include <com/sun/star/drawing/PointSequence.hpp>
#include "xexptran.hxx"
#include <com/sun/star/drawing/PolyPolygonBezierCoords.hpp>
#include <xmloff/families.hxx>
#include "ximpstyl.hxx"
#include <xmloff/xmltoken.hxx>
#include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
#include <com/sun/star/drawing/DoubleSequence.hpp>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>
#include <basegfx/polygon/b3dpolypolygontools.hxx>

using ::rtl::OUString;
using ::rtl::OUStringBuffer;

using namespace ::com::sun::star;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SdXML3DObjectContext::SdXML3DObjectContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    bool bTemporaryShape)
:	SdXMLShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
	mbSetTransform( sal_False )
{
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for(sal_Int16 i=0; i < nAttrCount; i++)
	{
		OUString sAttrName = xAttrList->getNameByIndex( i );
		OUString aLocalName;
		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
		OUString sValue = xAttrList->getValueByIndex( i );
		const SvXMLTokenMap& rAttrTokenMap = GetImport().GetShapeImport()->Get3DObjectAttrTokenMap();

		switch(rAttrTokenMap.Get(nPrefix, aLocalName))
		{
			case XML_TOK_3DOBJECT_DRAWSTYLE_NAME:
			{
				maDrawStyleName = sValue;
				break;
			}
			case XML_TOK_3DOBJECT_TRANSFORM:
			{
				SdXMLImExTransform3D aTransform(sValue, GetImport().GetMM100UnitConverter());
				if(aTransform.NeedsAction())
					mbSetTransform = aTransform.GetFullHomogenTransform(mxHomMat);
				break;
			}
		}
	}
}

//////////////////////////////////////////////////////////////////////////////

SdXML3DObjectContext::~SdXML3DObjectContext()
{
}

//////////////////////////////////////////////////////////////////////////////

void SdXML3DObjectContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
	if(xPropSet.is())
	{
		// set parameters
		if(mbSetTransform)
		{
			uno::Any aAny;
			aAny <<= mxHomMat;
			xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DTransformMatrix")), aAny);
		}

		// call parent
		SdXMLShapeContext::StartElement(xAttrList);
	}
}

//////////////////////////////////////////////////////////////////////////////

void SdXML3DObjectContext::EndElement()
{
	// call parent
	SdXMLShapeContext::EndElement();
}

//////////////////////////////////////////////////////////////////////////////
/*
void SdXML3DObjectContext::AddShape(uno::Reference< drawing::XShape >& xShape)
{
	if(xShape.is() && mxShapes.is())
	{
		// set shape local
		mxShape = xShape;

		// add new shape to parent
		mxShapes->add( xShape );
	}
}
*/
//////////////////////////////////////////////////////////////////////////////
/*
void SdXML3DObjectContext::SetStyle()
{
	// set style on shape
	if(maDrawStyleName.getLength() && mxShape.is())
	{
		const SvXMLStyleContext* pStyle = 0L;
		sal_Bool bAutoStyle(sal_False);

		if(GetImport().GetShapeImport()->GetAutoStylesContext())
			pStyle = GetImport().GetShapeImport()->GetAutoStylesContext()->FindStyleChildContext(
			XML_STYLE_FAMILY_SD_GRAPHICS_ID, maDrawStyleName);

		if(pStyle)
			bAutoStyle = sal_True;

		if(!pStyle && GetImport().GetShapeImport()->GetStylesContext())
			pStyle = GetImport().GetShapeImport()->GetStylesContext()->
			FindStyleChildContext(XML_STYLE_FAMILY_SD_GRAPHICS_ID, maDrawStyleName);

		if(pStyle && dynamic_cast< XMLShapeStyleContext* >(pStyle))
		{
			uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
			if(xPropSet.is())
			{
				XMLShapeStyleContext* pDocStyle = (XMLShapeStyleContext*)pStyle;

				if(pDocStyle->GetStyle().is())
				{
					// set style on object
					uno::Any aAny;
					aAny <<= pDocStyle->GetStyle();
					xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("Style")), aAny);
				}

				if(bAutoStyle)
				{
					// set PropertySet on object
					pDocStyle->FillPropertySet(xPropSet);
				}
			}
		}
	}
}
*/
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SdXML3DCubeObjectShapeContext::SdXML3DCubeObjectShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    bool bTemporaryShape)
:	SdXML3DObjectContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
	maMinEdge(-2500.0, -2500.0, -2500.0),
	maMaxEdge(2500.0, 2500.0, 2500.0),
	mbMinEdgeUsed(sal_False),
	mbMaxEdgeUsed(sal_False)
{
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for(sal_Int16 i=0; i < nAttrCount; i++)
	{
		OUString sAttrName = xAttrList->getNameByIndex( i );
		OUString aLocalName;
		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
		OUString sValue = xAttrList->getValueByIndex( i );
		const SvXMLTokenMap& rAttrTokenMap = GetImport().GetShapeImport()->Get3DCubeObjectAttrTokenMap();

		switch(rAttrTokenMap.Get(nPrefix, aLocalName))
		{
			case XML_TOK_3DCUBEOBJ_MINEDGE:
			{
				::basegfx::B3DVector aNewVec;
				GetImport().GetMM100UnitConverter().convertB3DVector(aNewVec, sValue);

				if(aNewVec != maMinEdge)
				{
					maMinEdge = aNewVec;
					mbMinEdgeUsed = sal_True;
				}
				break;
			}
			case XML_TOK_3DCUBEOBJ_MAXEDGE:
			{
				::basegfx::B3DVector aNewVec;
				GetImport().GetMM100UnitConverter().convertB3DVector(aNewVec, sValue);

				if(aNewVec != maMaxEdge)
				{
					maMaxEdge = aNewVec;
					mbMaxEdgeUsed = sal_True;
				}
				break;
			}
		}
	}
}

//////////////////////////////////////////////////////////////////////////////

SdXML3DCubeObjectShapeContext::~SdXML3DCubeObjectShapeContext()
{
}

//////////////////////////////////////////////////////////////////////////////

void SdXML3DCubeObjectShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	// create shape
	AddShape( "com.sun.star.drawing.Shape3DCubeObject" );
	if(mxShape.is())
	{
		// add, set style and properties from base shape
		SetStyle();
		SdXML3DObjectContext::StartElement(xAttrList);

		// set local parameters on shape
		uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
		if(xPropSet.is())
		{
			// set parameters
			drawing::Position3D aPosition3D;
			drawing::Direction3D aDirection3D;

			// convert from min, max to size to be set
			maMaxEdge = maMaxEdge - maMinEdge;

			aPosition3D.PositionX = maMinEdge.getX();
			aPosition3D.PositionY = maMinEdge.getY();
			aPosition3D.PositionZ = maMinEdge.getZ();

			aDirection3D.DirectionX = maMaxEdge.getX();
			aDirection3D.DirectionY = maMaxEdge.getY();
			aDirection3D.DirectionZ = maMaxEdge.getZ();

			uno::Any aAny;
			aAny <<= aPosition3D;
			xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DPosition")), aAny);
			aAny <<= aDirection3D;
			xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSize")), aAny);
		}
	}
}

//////////////////////////////////////////////////////////////////////////////

void SdXML3DCubeObjectShapeContext::EndElement()
{
	// call parent
	SdXML3DObjectContext::EndElement();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SdXML3DSphereObjectShapeContext::SdXML3DSphereObjectShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    bool bTemporaryShape)
:	SdXML3DObjectContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape ),
	maCenter(0.0, 0.0, 0.0),
	maSize(5000.0, 5000.0, 5000.0),
	mbCenterUsed(sal_False),
	mbSizeUsed(sal_False)
{
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for(sal_Int16 i=0; i < nAttrCount; i++)
	{
		OUString sAttrName = xAttrList->getNameByIndex( i );
		OUString aLocalName;
		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
		OUString sValue = xAttrList->getValueByIndex( i );
		const SvXMLTokenMap& rAttrTokenMap = GetImport().GetShapeImport()->Get3DSphereObjectAttrTokenMap();

		switch(rAttrTokenMap.Get(nPrefix, aLocalName))
		{
			case XML_TOK_3DSPHEREOBJ_CENTER:
			{
				::basegfx::B3DVector aNewVec;
				GetImport().GetMM100UnitConverter().convertB3DVector(aNewVec, sValue);

				if(aNewVec != maCenter)
				{
					maCenter = aNewVec;
					mbCenterUsed = sal_True;
				}
				break;
			}
			case XML_TOK_3DSPHEREOBJ_SIZE:
			{
				::basegfx::B3DVector aNewVec;
				GetImport().GetMM100UnitConverter().convertB3DVector(aNewVec, sValue);

				if(aNewVec != maSize)
				{
					maSize = aNewVec;
					mbSizeUsed = sal_True;
				}
				break;
			}
		}
	}
}

//////////////////////////////////////////////////////////////////////////////

SdXML3DSphereObjectShapeContext::~SdXML3DSphereObjectShapeContext()
{
}

//////////////////////////////////////////////////////////////////////////////

void SdXML3DSphereObjectShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	// create shape
	AddShape( "com.sun.star.drawing.Shape3DSphereObject" );
	if(mxShape.is())
	{
		// add, set style and properties from base shape
		SetStyle();
		SdXML3DObjectContext::StartElement(xAttrList);

		// set local parameters on shape
		uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);
		if(xPropSet.is())
		{
			// set parameters
			drawing::Position3D aPosition3D;
			drawing::Direction3D aDirection3D;

			aPosition3D.PositionX = maCenter.getX();
			aPosition3D.PositionY = maCenter.getY();
			aPosition3D.PositionZ = maCenter.getZ();

			aDirection3D.DirectionX = maSize.getX();
			aDirection3D.DirectionY = maSize.getY();
			aDirection3D.DirectionZ = maSize.getZ();

			uno::Any aAny;
			aAny <<= aPosition3D;
			xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DPosition")), aAny);
			aAny <<= aDirection3D;
			xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSize")), aAny);
		}
	}
}

//////////////////////////////////////////////////////////////////////////////

void SdXML3DSphereObjectShapeContext::EndElement()
{
	// call parent
	SdXML3DObjectContext::EndElement();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SdXML3DPolygonBasedShapeContext::SdXML3DPolygonBasedShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    bool bTemporaryShape)
:	SdXML3DObjectContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape )
{
	sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
	for(sal_Int16 i=0; i < nAttrCount; i++)
	{
		OUString sAttrName = xAttrList->getNameByIndex( i );
		OUString aLocalName;
		sal_uInt16 nPrefix = GetImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
		OUString sValue = xAttrList->getValueByIndex( i );
		const SvXMLTokenMap& rAttrTokenMap = GetImport().GetShapeImport()->Get3DPolygonBasedAttrTokenMap();

		switch(rAttrTokenMap.Get(nPrefix, aLocalName))
		{
			case XML_TOK_3DPOLYGONBASED_VIEWBOX:
			{
				maViewBox = sValue;
				break;
			}
			case XML_TOK_3DPOLYGONBASED_D:
			{
				maPoints = sValue;
				break;
			}
		}
	}
}

//////////////////////////////////////////////////////////////////////////////

SdXML3DPolygonBasedShapeContext::~SdXML3DPolygonBasedShapeContext()
{
}

//////////////////////////////////////////////////////////////////////////////

void SdXML3DPolygonBasedShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
    uno::Reference< beans::XPropertySet > xPropSet(mxShape, uno::UNO_QUERY);

    if(xPropSet.is())
    {
        // set parameters
        if(maPoints.getLength() && maViewBox.getLength())
        {
            // import 2d PolyPolygon from svg:d
            basegfx::B2DPolyPolygon aPolyPolygon;

            if(basegfx::tools::importFromSvgD(
                aPolyPolygon,
                maPoints,
                true,
                0))
            {
                // convert to 3D PolyPolygon
                const basegfx::B3DPolyPolygon aB3DPolyPolygon(
                    basegfx::tools::createB3DPolyPolygonFromB2DPolyPolygon(
                        aPolyPolygon));

                // convert to UNO API class PolyPolygonShape3D
                drawing::PolyPolygonShape3D xPolyPolygon3D;
                basegfx::tools::B3DPolyPolygonToUnoPolyPolygonShape3D(
                    aB3DPolyPolygon, 
                    xPolyPolygon3D);

                // set polygon data
                uno::Any aAny;
                aAny <<= xPolyPolygon3D;
                xPropSet->setPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DPolyPolygon3D")), aAny);
            }
            else
            {
                OSL_ENSURE(false, "Error on importing svg:d for 3D PolyPolygon (!)");
            }
        }

        // call parent
        SdXML3DObjectContext::StartElement(xAttrList);
    }
}

//////////////////////////////////////////////////////////////////////////////

void SdXML3DPolygonBasedShapeContext::EndElement()
{
	// call parent
	SdXML3DObjectContext::EndElement();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SdXML3DLatheObjectShapeContext::SdXML3DLatheObjectShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    bool bTemporaryShape)
:	SdXML3DPolygonBasedShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape )
{
}

//////////////////////////////////////////////////////////////////////////////

SdXML3DLatheObjectShapeContext::~SdXML3DLatheObjectShapeContext()
{
}

//////////////////////////////////////////////////////////////////////////////

void SdXML3DLatheObjectShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	// create shape
	AddShape( "com.sun.star.drawing.Shape3DLatheObject" );
	if(mxShape.is())
	{
		// add, set style and properties from base shape
		SetStyle();
		SdXML3DPolygonBasedShapeContext::StartElement(xAttrList);
	}
}

//////////////////////////////////////////////////////////////////////////////

void SdXML3DLatheObjectShapeContext::EndElement()
{
	// call parent
	SdXML3DPolygonBasedShapeContext::EndElement();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

SdXML3DExtrudeObjectShapeContext::SdXML3DExtrudeObjectShapeContext(
	SvXMLImport& rImport,
	sal_uInt16 nPrfx,
	const OUString& rLocalName,
	const com::sun::star::uno::Reference< com::sun::star::xml::sax::XAttributeList>& xAttrList,
	uno::Reference< drawing::XShapes >& rShapes,
    bool bTemporaryShape)
:	SdXML3DPolygonBasedShapeContext( rImport, nPrfx, rLocalName, xAttrList, rShapes, bTemporaryShape )
{
}

//////////////////////////////////////////////////////////////////////////////

SdXML3DExtrudeObjectShapeContext::~SdXML3DExtrudeObjectShapeContext()
{
}

//////////////////////////////////////////////////////////////////////////////

void SdXML3DExtrudeObjectShapeContext::StartElement(const uno::Reference< xml::sax::XAttributeList>& xAttrList)
{
	AddShape( "com.sun.star.drawing.Shape3DExtrudeObject" );
	if(mxShape.is())
	{
		// add, set style and properties from base shape
		SetStyle();
		SdXML3DPolygonBasedShapeContext::StartElement(xAttrList);
	}
}

//////////////////////////////////////////////////////////////////////////////

void SdXML3DExtrudeObjectShapeContext::EndElement()
{
	// call parent
	SdXML3DPolygonBasedShapeContext::EndElement();
}

// EOF
