/**************************************************************
 * 
 * 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);
	}
}

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