/**************************************************************
 *
 * 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 <com/sun/star/drawing/HomogenMatrix.hpp>
#include <com/sun/star/drawing/PolyPolygonShape3D.hpp>
#include <com/sun/star/drawing/ProjectionMode.hpp>
#include <com/sun/star/drawing/ShadeMode.hpp>
#include <com/sun/star/drawing/Direction3D.hpp>
#include <com/sun/star/drawing/Position3D.hpp>
#include <com/sun/star/drawing/CameraGeometry.hpp>
#include <com/sun/star/drawing/DoubleSequence.hpp>
#include <tools/gen.hxx>
#include <xmloff/shapeexport.hxx>
#include "sdpropls.hxx"
#include <tools/debug.hxx>
#include <rtl/ustrbuf.hxx>
#include <xmloff/xmlexp.hxx>
#include <xmloff/xmluconv.hxx>
#include "xexptran.hxx"
#include <xmloff/xmltoken.hxx>
#include <basegfx/vector/b3dvector.hxx>
#include <xmloff/xmlnmspe.hxx>
#include <basegfx/polygon/b3dpolypolygon.hxx>
#include <basegfx/polygon/b3dpolypolygontools.hxx>
#include <basegfx/matrix/b3dhommatrix.hxx>
#include <basegfx/polygon/b2dpolypolygon.hxx>
#include <basegfx/polygon/b2dpolypolygontools.hxx>

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

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


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

void XMLShapeExport::ImpExport3DSceneShape( const uno::Reference< drawing::XShape >& xShape, XmlShapeType, sal_Int32 nFeatures, awt::Point* pRefPoint)
{
	uno::Reference< drawing::XShapes > xShapes(xShape, uno::UNO_QUERY);
	if(xShapes.is() && xShapes->getCount())
	{
		uno::Reference< beans::XPropertySet > xPropSet( xShape, uno::UNO_QUERY );
		DBG_ASSERT( xPropSet.is(), "XMLShapeExport::ImpExport3DSceneShape can't export a scene without a propertyset" );
		if( xPropSet.is() )
		{
			// Transformation
			ImpExportNewTrans(xPropSet, nFeatures, pRefPoint);

			// 3d attributes
			export3DSceneAttributes( xPropSet );

			// write 3DScene shape
			sal_Bool bCreateNewline( (nFeatures & SEF_EXPORT_NO_WS) == 0 ); // #86116#/#92210#
			SvXMLElementExport aOBJ( mrExport, XML_NAMESPACE_DR3D, XML_SCENE, bCreateNewline, sal_True);

			ImpExportDescription( xShape ); // #i68101#
			ImpExportEvents( xShape );

			// write 3DSceneLights
			export3DLamps( xPropSet );

			// #89764# if export of position is suppressed for group shape,
			// positions of contained objects should be written relative to
			// the upper left edge of the group.
			awt::Point aUpperLeft;

			if(!(nFeatures & SEF_EXPORT_POSITION))
			{
				nFeatures |= SEF_EXPORT_POSITION;
				aUpperLeft = xShape->getPosition();
				pRefPoint = &aUpperLeft;
			}

			// write members
			exportShapes( xShapes, nFeatures, pRefPoint );
		}
	}
}

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

void XMLShapeExport::ImpExport3DShape(
	const uno::Reference< drawing::XShape >& xShape,
	XmlShapeType eShapeType, sal_Int32 /* nFeatures = SEF_DEFAULT */, awt::Point* /*pRefPoint = NULL */)
{
	const uno::Reference< beans::XPropertySet > xPropSet(xShape, uno::UNO_QUERY);
	if(xPropSet.is())
	{
		OUString aStr;
		OUStringBuffer sStringBuffer;

		// transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
		uno::Any aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DTransformMatrix")));
		drawing::HomogenMatrix xHomMat;
		aAny >>= xHomMat;
		SdXMLImExTransform3D aTransform;
		aTransform.AddHomogenMatrix(xHomMat);
		if(aTransform.NeedsAction())
			mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_TRANSFORM, aTransform.GetExportString(mrExport.GetMM100UnitConverter()));

		switch(eShapeType)
		{
			case XmlShapeTypeDraw3DCubeObject:
			{
				// minEdge
				aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DPosition")));
				drawing::Position3D aPosition3D;
				aAny >>= aPosition3D;
				::basegfx::B3DVector aPos3D(aPosition3D.PositionX, aPosition3D.PositionY, aPosition3D.PositionZ);

				// maxEdge
				aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSize")));
				drawing::Direction3D aDirection3D;
				aAny >>= aDirection3D;
				::basegfx::B3DVector aDir3D(aDirection3D.DirectionX, aDirection3D.DirectionY, aDirection3D.DirectionZ);

				// transform maxEdge from distance to pos
				aDir3D = aPos3D + aDir3D;

				// write minEdge
				if(aPos3D != ::basegfx::B3DVector(-2500.0, -2500.0, -2500.0)) // write only when not default
				{
					mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aPos3D);
					aStr = sStringBuffer.makeStringAndClear();
					mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_MIN_EDGE, aStr);
				}

				// write maxEdge
				if(aDir3D != ::basegfx::B3DVector(2500.0, 2500.0, 2500.0)) // write only when not default
				{
					mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aDir3D);
					aStr = sStringBuffer.makeStringAndClear();
					mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_MAX_EDGE, aStr);
				}

				// write 3DCube shape
                // #123542# Do this *after* the attributes are added, else these will be lost since opening
                // the scope will clear the global attribute list at the exporter
				SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_CUBE, sal_True, sal_True);

                break;
			}
			case XmlShapeTypeDraw3DSphereObject:
			{
				// Center
				aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DPosition")));
				drawing::Position3D aPosition3D;
				aAny >>= aPosition3D;
				::basegfx::B3DVector aPos3D(aPosition3D.PositionX, aPosition3D.PositionY, aPosition3D.PositionZ);

				// Size
				aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSize")));
				drawing::Direction3D aDirection3D;
				aAny >>= aDirection3D;
				::basegfx::B3DVector aDir3D(aDirection3D.DirectionX, aDirection3D.DirectionY, aDirection3D.DirectionZ);

				// write Center
				if(aPos3D != ::basegfx::B3DVector(0.0, 0.0, 0.0)) // write only when not default
				{
					mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aPos3D);
					aStr = sStringBuffer.makeStringAndClear();
					mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_CENTER, aStr);
				}

				// write Size
				if(aDir3D != ::basegfx::B3DVector(5000.0, 5000.0, 5000.0)) // write only when not default
				{
					mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aDir3D);
					aStr = sStringBuffer.makeStringAndClear();
					mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SIZE, aStr);
				}

				// write 3DSphere shape
                // #123542# Do this *after* the attributes are added, else these will be lost since opening
                // the scope will clear the global attribute list at the exporter
				SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_SPHERE, sal_True, sal_True);

				break;
			}
			case XmlShapeTypeDraw3DLatheObject:
			case XmlShapeTypeDraw3DExtrudeObject:
			{
                // write special 3DLathe/3DExtrude attributes, get 3D PolyPolygon as drawing::PolyPolygonShape3D
                aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DPolyPolygon3D")));
                drawing::PolyPolygonShape3D xPolyPolygon3D;
                aAny >>= xPolyPolygon3D;

                // convert to 3D PolyPolygon
                const basegfx::B3DPolyPolygon aPolyPolygon3D(
                    basegfx::tools::UnoPolyPolygonShape3DToB3DPolyPolygon(
                        xPolyPolygon3D));

                // convert to 2D PolyPolygon using identity 3D transformation (just grep X and Y)
                const basegfx::B3DHomMatrix aB3DHomMatrixFor2DConversion;
                const basegfx::B2DPolyPolygon aPolyPolygon(
                    basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(
                        aPolyPolygon3D,
                        aB3DHomMatrixFor2DConversion));

                // get 2D range of it
                const basegfx::B2DRange aPolyPolygonRange(aPolyPolygon.getB2DRange());

                // export ViewBox
                SdXMLImExViewBox aViewBox(
                    aPolyPolygonRange.getMinX(),
                    aPolyPolygonRange.getMinY(),
                    aPolyPolygonRange.getWidth(),
                    aPolyPolygonRange.getHeight());

                mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_VIEWBOX, aViewBox.GetExportString());

                // prepare svg:d string
                const ::rtl::OUString aPolygonString(
                    basegfx::tools::exportToSvgD(
                        aPolyPolygon,
                        true,           // bUseRelativeCoordinates
                        false,          // bDetectQuadraticBeziers TTTT: not used in old, but maybe activated now
                        true));         // bHandleRelativeNextPointCompatible

                // write point array
                mrExport.AddAttribute(XML_NAMESPACE_SVG, XML_D, aPolygonString);

				if(eShapeType == XmlShapeTypeDraw3DLatheObject)
				{
					// write 3DLathe shape
					SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_ROTATE, sal_True, sal_True);
				}
				else
				{
					// write 3DExtrude shape
					SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_EXTRUDE, sal_True, sal_True);
				}
				break;
			}
			default:
				break;
		}
	}
}

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

/** helper for chart that adds all attributes of a 3d scene element to the export */
void XMLShapeExport::export3DSceneAttributes( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet )
{
	OUString aStr;
	OUStringBuffer sStringBuffer;

	// world transformation (UNO_NAME_3D_TRANSFORM_MATRIX == "D3DTransformMatrix")
	uno::Any aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DTransformMatrix")));
	drawing::HomogenMatrix xHomMat;
	aAny >>= xHomMat;
	SdXMLImExTransform3D aTransform;
	aTransform.AddHomogenMatrix(xHomMat);
	if(aTransform.NeedsAction())
		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_TRANSFORM, aTransform.GetExportString(mrExport.GetMM100UnitConverter()));

	// VRP, VPN, VUP
	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DCameraGeometry")));
	drawing::CameraGeometry aCamGeo;
	aAny >>= aCamGeo;

	::basegfx::B3DVector aVRP(aCamGeo.vrp.PositionX, aCamGeo.vrp.PositionY, aCamGeo.vrp.PositionZ);
	if(aVRP != ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
	{
		mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aVRP);
		aStr = sStringBuffer.makeStringAndClear();
		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_VRP, aStr);
	}

	::basegfx::B3DVector aVPN(aCamGeo.vpn.DirectionX, aCamGeo.vpn.DirectionY, aCamGeo.vpn.DirectionZ);
	if(aVPN != ::basegfx::B3DVector(0.0, 0.0, 1.0)) // write only when not default
	{
		mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aVPN);
		aStr = sStringBuffer.makeStringAndClear();
		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_VPN, aStr);
	}

	::basegfx::B3DVector aVUP(aCamGeo.vup.DirectionX, aCamGeo.vup.DirectionY, aCamGeo.vup.DirectionZ);
	if(aVUP != ::basegfx::B3DVector(0.0, 1.0, 0.0)) // write only when not default
	{
		mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aVUP);
		aStr = sStringBuffer.makeStringAndClear();
		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_VUP, aStr);
	}

	// projection "D3DScenePerspective" drawing::ProjectionMode
	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DScenePerspective")));
	drawing::ProjectionMode xPrjMode;
	aAny >>= xPrjMode;
	if(xPrjMode == drawing::ProjectionMode_PARALLEL)
		aStr = GetXMLToken(XML_PARALLEL);
	else
		aStr = GetXMLToken(XML_PERSPECTIVE);
	mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_PROJECTION, aStr);

	// distance
	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneDistance")));
	sal_Int32 nDistance = 0;
	aAny >>= nDistance;
	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nDistance);
	aStr = sStringBuffer.makeStringAndClear();
	mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_DISTANCE, aStr);

	// focalLength
	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneFocalLength")));
	sal_Int32 nFocalLength = 0;
	aAny >>= nFocalLength;
	mrExport.GetMM100UnitConverter().convertMeasure(sStringBuffer, nFocalLength);
	aStr = sStringBuffer.makeStringAndClear();
	mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_FOCAL_LENGTH, aStr);

	// shadowSlant
	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneShadowSlant")));
	sal_Int16 nShadowSlant = 0;
	aAny >>= nShadowSlant;
	mrExport.GetMM100UnitConverter().convertNumber(sStringBuffer, (sal_Int32)nShadowSlant);
	aStr = sStringBuffer.makeStringAndClear();
	mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SHADOW_SLANT, aStr);

	// shadeMode
	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneShadeMode")));
	drawing::ShadeMode xShadeMode;
	if(aAny >>= xShadeMode)
	{
		if(xShadeMode == drawing::ShadeMode_FLAT)
			aStr = GetXMLToken(XML_FLAT);
		else if(xShadeMode == drawing::ShadeMode_PHONG)
			aStr = GetXMLToken(XML_PHONG);
		else if(xShadeMode == drawing::ShadeMode_SMOOTH)
			aStr = GetXMLToken(XML_GOURAUD);
		else
			aStr = GetXMLToken(XML_DRAFT);
	}
	else
	{
		// ShadeMode enum not there, write default
		aStr = GetXMLToken(XML_GOURAUD);
	}
	mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SHADE_MODE, aStr);

	// ambientColor
	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneAmbientColor")));
	sal_Int32 aColTemp = 0;
	Color aAmbientColor;
	aAny >>= aColTemp; aAmbientColor.SetColor(aColTemp);
	mrExport.GetMM100UnitConverter().convertColor(sStringBuffer, aAmbientColor);
	aStr = sStringBuffer.makeStringAndClear();
	mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_AMBIENT_COLOR, aStr);

	// lightingMode
	aAny = xPropSet->getPropertyValue(OUString(RTL_CONSTASCII_USTRINGPARAM("D3DSceneTwoSidedLighting")));
	sal_Bool bTwoSidedLighting = false;
	aAny >>= bTwoSidedLighting;
	mrExport.GetMM100UnitConverter().convertBool(sStringBuffer, bTwoSidedLighting);
	aStr = sStringBuffer.makeStringAndClear();
	mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_LIGHTING_MODE, aStr);
}

/** helper for chart that exports all lamps from the propertyset */
void XMLShapeExport::export3DLamps( const com::sun::star::uno::Reference< com::sun::star::beans::XPropertySet >& xPropSet )
{
	// write lamps 1..8 as content
	OUString aStr;
	OUStringBuffer sStringBuffer;

	const OUString aColorPropName(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightColor") );
	const OUString aDirectionPropName(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightDirection") );
	const OUString aLightOnPropName(RTL_CONSTASCII_USTRINGPARAM("D3DSceneLightOn") );

	OUString aPropName;
	OUString aIndexStr;
	sal_Int32 aColTemp = 0;
	Color aLightColor;
	::basegfx::B3DVector aLightDirection;
	drawing::Direction3D xLightDir;
	sal_Bool bLightOnOff = false;
	for(sal_Int32 nLamp = 1; nLamp <= 8; nLamp++)
	{
		aIndexStr = OUString::valueOf( nLamp );

		// lightcolor
		aPropName = aColorPropName;
		aPropName += aIndexStr;
		xPropSet->getPropertyValue( aPropName ) >>= aColTemp;
		aLightColor.SetColor(aColTemp);
		mrExport.GetMM100UnitConverter().convertColor(sStringBuffer, aLightColor);
		aStr = sStringBuffer.makeStringAndClear();
		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_DIFFUSE_COLOR, aStr);

		// lightdirection
		aPropName = aDirectionPropName;
		aPropName += aIndexStr;
		xPropSet->getPropertyValue(aPropName) >>= xLightDir;
		aLightDirection = ::basegfx::B3DVector(xLightDir.DirectionX, xLightDir.DirectionY, xLightDir.DirectionZ);
		mrExport.GetMM100UnitConverter().convertB3DVector(sStringBuffer, aLightDirection);
		aStr = sStringBuffer.makeStringAndClear();
		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_DIRECTION, aStr);

		// lighton
		aPropName = aLightOnPropName;
		aPropName += aIndexStr;
		xPropSet->getPropertyValue(aPropName) >>= bLightOnOff;
		mrExport.GetMM100UnitConverter().convertBool(sStringBuffer, bLightOnOff);
		aStr = sStringBuffer.makeStringAndClear();
		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_ENABLED, aStr);

		// specular
		mrExport.AddAttribute(XML_NAMESPACE_DR3D, XML_SPECULAR,
			nLamp == 1 ? XML_TRUE : XML_FALSE);

		// write light entry
		SvXMLElementExport aOBJ(mrExport, XML_NAMESPACE_DR3D, XML_LIGHT, sal_True, sal_True);
	}
}

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