//////////////////////////////////////
// START of File: C1_KERNL.HPP
//////////////////////////////////////

#ifndef C1_KERNL_HPP
#define C1_KERNL_HPP

//===================================================================
//
// COPYRIGHT NOTICE:  This code is protected by Copyright!
//
// Copyright (c) 1994 through 1997 by DPC Technology Corporation.
// All rights reserved by DPC Technology Corporation.
//
// See files "cf_copyr.txt" and "cf_licen.txt" for details of
// copyright and license specifications, and contact information.
//
//===================================================================

// Master Header File Listing:
// Usage:   #include    <cf_api/c1_kernl.hpp>
            // Chart Framework Geometry/Projection Transform Kernel.

//--------------------------------------------------------------------
// Include Chart Framework class or ID defs/headers this file needs.
// Paths are relative to the IDE's (global) include path: ~/cfrz
//--------------------------------------------------------------------
#include    <cf_api/cf_defs.h>
            // Typedefs & Data Structs...

#include    <cf_api/cf_const.h>
            // Constant Definitions...

class 		cf_2DPoint;
class 		cf_2DRect;
#include    <cf_api/c0_dimen.hpp>

class 		bf_Display;
#include    <cf_api/b0_dspla.hpp>

#define 	CF_PRATIO_ZFACTOR       10.0
            // The User's Perspective "P-Ratio" (below) is converted to a
            // kernel "Perspective Value" by dividing the P-Ratio by this
            // factor applied to the current minimal Z-depth of the 3D Box.


//
// Define a "Chart-Framework Geometry-Kernel" Class:
//

class CF_EXPORT	cf_Kernel
//===================================================================
// This class is used by the "3D Chart", and "2D/3D Engine"
// classes to set up the 3D view transformation and projection
// matrices, and by the "2D/3D Engine" and "3D Object" classes to
// perform the transformation and projection operations
// upon their components.
//===================================================================
{

public:

	cf_Kernel(	double	dXDimension = 100.0,
				double	dYDimension = 100.0,
				double	dZDimension = 100.0  );
				// Std (& Default) C-tor:

	~cf_Kernel();
				// Std (& Non-Virtual) D-tor:

	cf_Kernel&	operator=( const cf_Kernel& cr_cf_kUserVal );
				// We can swap kernels about freely using this = op...


	void 	copy3DBoxCoords(	double	*a_d8BoxXCoords,
								double	*a_d8BoxYCoords,
								double	*a_d8BoxZCoords )
								const;

	void 	copy3DBoxOrigin(	double	*dXCoord,
								double	*dYCoord,
								double	*dZCoord  )
								const;

	void 	copyBackFaceCoords(	double	*a_d4FaceXCoords,
								double	*a_d4FaceYCoords,
								double	*a_d4FaceZCoords )
								const;

	void 	copyBottomFaceCoords(	double	*a_d4FaceXCoords,
									double	*a_d4FaceYCoords,
									double	*a_d4FaceZCoords )
									const;

	void 	copyBitmapWallOrigin(	double	*dXCoord,
								double	*dYCoord,
								double	*dZCoord  )
								const;

	void 	copyHseRefPointCoords(	double	*dXCoord,
									double	*dYCoord,
									double	*dZCoord  )
									const;

	void 	copyLeftFaceCoords(	double	*a_d4FaceXCoords,
								double	*a_d4FaceYCoords,
								double	*a_d4FaceZCoords )
								const;

	double	dsortRefX();
	double	dsortRefY();
	double	dsortRefZ();

	int		getLeftMarginTwips();
	int		getRightMarginTwips();
	int		getTopMarginTwips();
	int		getBottomMarginTwips();

	double	getXAngle();
	double	getYAngle();
	double	getZAngle();
	double	getPerspectiveRatio();

    double  getXDim();
	double	getXMin();
	double	getXMax();

    double  getYDim();
	double	getYMin();
	double	getYMax();

    double  getZDim();
	double	getZMin();
	double	getZMax();
			// Std "get member values" methods:


	const CF_4BY4_MATRIX&	referToGeomMatrix()	const;
	const CF_4BY2_MATRIX&	referToProjMatrix()	const;
		  // Geometric "objects" will want to REFERENCE
		  // the geometry and projection matrices, because
		  // it's MUCH faster than COPYING them, but we want
		  // to PREVENT kernel USERS from CHANGING these
		  // protected/private values, so we'll make this
		  // a non-mutable method with the const keyword!


	const cf_2DRect&	referToDispRectEntire() const;
	const cf_2DRect&	referToDispRectMargin() const;

	const cf_2DRect&	referToProjRectFaceLeft() const;
	const cf_2DRect&	referToProjRectFaceBack() const;
	const cf_2DRect&    referToProjRectFaceBottom() const;
                        // Provide user acccess to calculated display
                        // projection rectangles via constant references:


	void	preferDimensions(   double	dXDimension,
							    double	dYDimension,
							    double	dZDimension,
                                BOOL    bRecalcGeomMatrix = TRUE  );


    void    preferMarginTop(    int     iMarginInTwips,
                                BOOL    bRecalcProjMatrix = TRUE  );

    void    preferMarginBottom( int     iMarginInTwips,
                                BOOL    bRecalcProjMatrix = TRUE  );

    void    preferMarginLeft(   int     iMarginInTwips,
                                BOOL    bRecalcProjMatrix = TRUE  );

    void    preferMarginRight(  int     iMarginInTwips,
                                BOOL    bRecalcProjMatrix = TRUE  );


	void 	preferPerspective(	double  dSetPercentPerspective,
                                BOOL    bRecalcGeomMatrix = TRUE  );

	void 	preferViewAngle(	double  dSetXAngle,
						        double  dSetYAngle,
                                BOOL    bRecalcGeomMatrix = TRUE  );

	BOOL	setZoomMode();
	void 	setZoomMode( BOOL bNewState );

    void    updateDisplayMetrics( bf_Display *p_bf_dspHasChanged );
            // Called by the parent chart-view/chart-model/chart-engine
            // configuration in response to display context changes (e.g.
            // re-size events) that the configuration should respond to.

protected:

	void 	    calcGeomMatrix();
			    // Calcs Geometry Transform Matrix.

	void	    calcProjMatrix();
			    // Calcs Projection Transform Matrix.
                // Note that this method requires a properly
                // -established display device context!

	cf_2DRect	calcProjRectAreaFaceCoords( double	   *a_d4XCoords,
									        double	   *a_d4YCoords );
                // A context-reusable utility for modularity/maintainibility.
                // The particular calculation context(s) are established by
                // other member methods, e.g. calcProjRectAreaFaceLeft( ... ).

	void    	calcProjRectAreaFaceLeft();
	void    	calcProjRectAreaFaceBack();
	void	    calcProjRectAreaFaceBottom();
                // We need to know how big the PROJECTED 3D Box faces are in
                // order to properly scale fonts, projected-bitmap(s), etc.
                // All three of these functions use the PROTECTED member
                // utility-function calcProjRectAreaFaceCoords( ... )
                // (above) in their own specifically-established contexts.

	void	    applyGeomXform(	double	*a_dInitXCoords,
				    			double	*a_dInitYCoords,
					    		double	*a_dInitZCoords,
						    	int		iNumXYZPoints );
                // Applies a Geom-Xform to the PRIVATE 3D-Points representng
                // the 3D-Box that defines this 2D/3D chart geometry kernel.


	void 	    applyProjXform(	double	    *a_dXformedXCoords,
				    			double	    *a_dXformedYCoords,
					    		cf_2DPoint	*a_cf_2dpScreenCoords,
						    	int			iNumXYZPoints );
                // Applies a Display/Projection-Xform to our PRIVATE 3D-Points.

    void	    measureDispRectEntire( bf_Display *p_bf_dspFromChartView );
    void	    measureDispRectMargin( bf_Display *p_bf_dspFromChartView );
                // Measure the device context passed by a chart-view/
                // chart-model configuration into a reference-able value.

private:

	// Declare essential kernel object member vars:
	double	dXRotAngle;
	double	dYRotAngle;
	double	dZRotAngle;
            // Keep track of the 3D Display view angle.

	double 	dPRatio;
            // Keep track of the 3D Display view factors.
            // Note that the "Real" "Perspective-Value is the derived
            // (calced) from this P-Ratio, which is the user's
            // chosen percent value for the perspective value.

	int		iLeftMarginTwips_,
            iRightMarginTwips_,
            iTopMarginTwips_,
            iBottomMarginTwips_;
            // Keep track of Margin offsets due to additional text spacing
            // that will be outside the borders of the 3D box -- These are
            // LOGICAL units of Twips -- where one logical unit == 1/20th
            // of a point, and there are 72 points/inch :

    cf_2DRect   cf_2drDispAreaEntire_;
    cf_2DRect   cf_2drDispAreaMargin_;

    cf_2DRect   cf_2drProjLeftFaceArea_;
    cf_2DRect   cf_2drProjBackFaceArea_;
    cf_2DRect   cf_2drProjBottomFaceArea_;

	BOOL	bIsZoomModeOn;
	int		iSavedTopMargin,
			iSavedBottomMargin,
			iSavedLeftMargin,
			iSavedRightMargin;
			// Declare state vars for "zoom-mode" (zero margins).
			// Note that this neccessitates saving the existing
			// chart margin params, so we can restore them.

	CF_4BY4_MATRIX 	cf_4by4mGeomMatrix;
					// Our geometric transformation matrix which transforms
                    // logical/virtual 3D coords according to the current
                    // geometry state rotation and perspective.)

	CF_4BY2_MATRIX	cf_4by2mProjMatrix;
					// Our projection transformation matrix. which transforms
                    // geometric/3D points to projected/2D screen coords.)

	double		a_d3DBoxInitXCoord[ 8 ];
	double 		a_d3DBoxInitYCoord[ 8 ];
	double 		a_d3DBoxInitZCoord[ 8 ];
				// The INITIAL (data) world coordinates of the bounding
                // box which encloses our 3D charting area.

	double		a_d3DBoxXformXCoord[ 8 ];
	double 		a_d3DBoxXformYCoord[ 8 ];
	double 		a_d3DBoxXformZCoord[ 8 ];
				// The TRANSFORMED (virtual) world coordinates of the
                // bounding box  which encloses our 3D charting area.

	double		a_d3DBoxProjXCoord[ 8 ];
	double 		a_d3DBoxProjYCoord[ 8 ];

	cf_2DPoint	a_cf_2dp3DBoxProjScreenPoints[ 8 ];
				// The PROJECTED screen coords of the bounding box
                // which encloses our 3D charting area.

	double	dChartBoxXOrigin;
	double	dChartBoxYOrigin;
	double	dChartBoxZOrigin;
			// These hold the virtual coords of the chart's 3D-box origin.

	double	dDsortRefPointX;
	double	dDsortRefPointY;
	double	dDsortRefPointZ;
			// The virtual coords of an HSE (Hidden Surface Elimination) point.

	double	dBitmapWallXOrigin;
	double	dBitmapWallYOrigin;
	double	dBitmapWallZOrigin;
            // These hold the virtual coords of the BitmapWall wall's origin.

	double	dXMin, dXMax, dYMin, dYMax, dZMin, dZMax;
			// Utility vars to hold the coords of the dimensions of
            // the kernel, which save re-calculation resources in the
            // context of calculations such as projection calcs, etc.

};	// End of cf_Kernel Declaration.

#endif

//////////////////////////////////////
// END of File: C1_KERNL.HPP
//////////////////////////////////////

