/*===========================================================================
 *
 * File:	DF_DXFExp.CPP
 * Author:	Dave Humphrey (uesp@m0use.net)
 * Created On:	Friday, March 22, 2002
 *
 * Implements DXF related export routines for DF 3d objects.
 *
 *=========================================================================*/

	/* Include Files */
#include "df3dexpo.h"
#include "bsa/df3dutil.h"


/*===========================================================================
 *
 * Begin Local Variable Definitions
 *
 *=========================================================================*/
  DEFINE_FILE();
/*===========================================================================
 *		End of Local Variable Definitions
 *=========================================================================*/


/*===========================================================================
 *
 * Function - int l_ExportDF3dFaceToDXF (DFFace, pCallbackData);
 *
 * Local function used as a callback function for the CDF3dObject::ForEachFace()
 * method.  Outputs one face to the current position in the DXF file stream 
 * contained in the callback data pointer.  Returns 0 on success.
 *
 * Faces are output as 3D polylines exactly as they are stored in the DF
 * 3D object (no sub-division into triangle fans as in the 3DS export).
 * The Y and Z coordinates are swapped and the new Z coordinate is negated
 * as before.
 *
 *=========================================================================*/
int l_ExportDF3dFaceToDXF (const df3dface_t& DFFace, void* pData) {
  //DEFINE_FUNCTION("l_ExportDF3dFaceToDXF()");
  df3dexportdxf_t* pCallbackData = (df3dexportdxf_t *) pData;
  df3dpoint_t* pPoint;
  boolean      Result;
  long         PointIndex;
  int          OffsetDivisor;
  int          FacePointIndex;
  float        X, Y, Z;
   
	/* Ignore if no points in face to export */
  if (DFFace.NumPoints <= 0) return (0);
  OffsetDivisor = GetDF3dFacePointOffsetDivisor(pCallbackData->ObjectVersion);

	/* Output the DXF section headers to start face */
  Result  = pCallbackData->pFileDxf->Start3DPolyline();
  Result &= pCallbackData->pFileDxf->WriteLayer(pCallbackData->Layer);

	/* Output each point in the face */
  for (PointIndex = 0; PointIndex < DFFace.NumPoints; PointIndex++) {

		/* Compute the point data index */
    FacePointIndex = DFFace.FaceData[PointIndex].PointOffset / OffsetDivisor;
    pPoint = &(pCallbackData->pPoints[FacePointIndex]);

    		/* Compute the point coordinates */
    X = (float)  pPoint->X / DF3D_3DS_FACTOR;
    Z = (float) -pPoint->Y / DF3D_3DS_FACTOR;
    Y = (float)  pPoint->Z / DF3D_3DS_FACTOR;

		/* Output the point */
    Result &= pCallbackData->pFileDxf->Write3DVertex(X, Y, Z);
    Result &= pCallbackData->pFileDxf->WriteLayer(pCallbackData->Layer);  
   }

	/* Output first point again to close the face */
  FacePointIndex = DFFace.FaceData[0].PointOffset / OffsetDivisor;
  pPoint = &(pCallbackData->pPoints[FacePointIndex]);
  Result &= pCallbackData->pFileDxf->Write3DVertex(pPoint->X/DF3D_DXF_FACTOR, pPoint->Z/DF3D_DXF_FACTOR, -pPoint->Y/DF3D_DXF_FACTOR);
  Result &= pCallbackData->pFileDxf->WriteLayer(pCallbackData->Layer);

	/* End the polyline section */
  Result &= pCallbackData->pFileDxf->EndPolyline();
  return (Result ? 0 : -1);
 }
/*===========================================================================
 *		End of Function l_ExportDF3dFaceToDXF()
 *=========================================================================*/



/*===========================================================================
 *
 * Function - 
 *	boolean ExportDF3dObjectToDXF (FileDXF, DF3dObject, pMeshMatrix, Layer);
 *
 * Exports the given Daggerfall 3D object to a single entity in the
 * DXF file.  Returns FALSE on any error.  The optional mesh matrix
 * gives the 3x4 sized transformation matrix to use for transforming each
 * point.  The layer value gives the optional layer value for the object.
 *
 *=========================================================================*/
boolean ExportDF3dObjectToDXF (CDxfFile& FileDXF, const CDF3dObject& DF3dObject, 
			       const float* pMeshMatrix, const int Layer) {
  DEFINE_FUNCTION("ExportDF3dObjectToDXF()");
  df3dexportdxf_t CallbackData;
  int		  iResult;

  	/* Setup the callback data structure */
  CallbackData.pFileDxf      = &FileDXF;
  CallbackData.pMeshMatrix   = pMeshMatrix;
  CallbackData.ObjectVersion = DF3dObject.GetVersionNum();
  CallbackData.Layer	     = Layer;
  CallbackData.pPoints       = DF3dObject.GetPointData();
 
  	/* Output the face data */
  iResult = DF3dObject.ForEachFaceC(l_ExportDF3dFaceToDXF, &CallbackData);
  if (iResult != 0) return (FALSE);
  
  return (TRUE);
 }
/*===========================================================================
 *		End of Function ExportDF3dObjectToDXF()
 *=========================================================================*/