//////////////////////////////////////
// START of File: C1_ENGIN.HPP
//////////////////////////////////////

#ifndef C1_ENGIN_HPP
#define C1_ENGIN_HPP

//-------------------------------------------------------------------
// COPYRIGHT NOTICE:  This code is protected by Copyright!
//
// Copyright (c) 1994 through 1997 by DPC Technology Corporation.
// All rights reserved.
//
// 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    <api/include/c1_engin.hpp>
            // Chart Framework "Virtual Chart Engine" BASE class object.

//--------------------------------------------------------------------
// 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>
            // contains Chart Framework typedef(s)

#include    <cf_api/cf_const.h>
            // defines chart engine default values

class       cf_String;
#include    <cf_api/c0_dystr.hpp>

class       bf_Display;
class       bf_2DBitmap;
#include    <cf_api/b0_dspla.hpp>
            // which pulls in the classes above...

class       cf_DyArr;   // We'll use dynamic arrays of (void) ptrs
#include    <cf_api/c0_dyarr.hpp>  // to "virtual-3D-objects"

class       cf_Kernel;
#include    <cf_api/c1_kernl.hpp>

class       cf_3DPoint;
class       cf_3DPolygon;
#include    <cf_api/co1_pgon.hpp>
            // which pulls in the classes above...

class       cf_TitleMarkerMgr;
class       cf_3DTextMarkerSeries;
#include    <cf_api/co1_tms.hpp>

class       cf_3DGridTickSeries;
#include    <cf_api/co1_gts.hpp>

class       cf_3DBitmap;
#include    <cf_api/co1_cbmp.hpp>

class       cf_ChartModel;
#include    <cf_api/c1_cmodl.hpp>


//--------------------------------------------------------------
// Declare a Chart Framework "Virtual Chart Engine" Base Class:
//--------------------------------------------------------------
class CF_EXPORT   cf_ChartEngine
{

public:

    cf_ChartEngine( cf_ChartType    enumChartType,
                    cf_DispMode     enumDispMode );
                    // Chart-Types are specified in file: "cf_defs.h"
                    // Creates (and deletes) an encapsulated geometry-kernel.

    virtual         ~cf_ChartEngine();

    cf_Kernel*      activeKernel();
    BOOL            activeKernel(   cf_Kernel   *p_cf_kNewKernel,
                                    BOOL        bDeleteOldKernelNow,
                                    BOOL        bDeleteNewKernelAtDtor );
                    // Any chart-engine can create it's own kernel, or
                    // borrow/hot-swap its kernel in/out at run-time!
                    // A powerful member method -- for CF-Experts only!

    cf_3DGridTickSeries*    axis_X_BackFace();
    cf_3DGridTickSeries*    axis_X_BottomFace();
    cf_3DGridTickSeries*    axis_Y_LeftFace();
    cf_3DGridTickSeries*    axis_Y_BackFace();
    cf_3DGridTickSeries*    axis_Z_LeftFace();
    cf_3DGridTickSeries*    axis_Z_BottomFace();
    cf_3DGridTickSeries*    axis_Polar_Floor();
                            // accessor methods for implicit grid/tick
                            // series objects associated with a standard
                            // chart-engine.  If the objects do not yet
                            // exist they will be new()-ed by the engine.

    virtual void    applyDataUpdate( cf_ChartModel *p_cf_cmodlDataSource );
                    // When a chart-model has a data-update, it will
                    // call this "umbrella" chart-engine method to
                    // tell the chart-engine to begin (re)generating
                    // its components and collection of virtual-
                    // geometry objects according to the current
                    // data-state of the chart-model.  Derived chart-
                    // engines (including customized derivations)
                    // should use their own specific over-rides
                    // of this virtual method.  This method might
                    // also call one or more protected (and possibly
                    // re-derived update() methods, (such as
                    // updateYValsAtIntIs(), updateAxisGridTickSeries(),
                    // etc.) according to a given specific
                    // implementation of a derived chart-engine.


    virtual void    applyDispMetrics();
    virtual void    applyGeomXform();
    virtual void    applyProjXform();
                    // Causes cascading geometry/projection update(s)
                    // throughout this chart-engine's collection of
                    // components and/or virtual-geometry-objects...

    cf_DispAttribs* attribChartFaceDisp( cf_ChartFace enumChartFaceSelector );
                    // Get method allows set display-attrib ops on chart-faces.

    virtual void    autoConfigure();
                    // Causes a chart-component reconfiguration to
                    // conform to latest user-programmer preferences
                    // (such as perspective, proportioning, etc.).

    BOOL            bitmapChartWallFile();
    void            bitmapChartWallFileName( const char *a_cFileNameString );
    const char*     bitmapChartWallFileName();
                    // Methods for a "background-bitmap" source file.
                    // Also see dispBitmapChartWall(); below...

    BOOL            bitmapWallPaperFile();
    void            bitmapWallPaperFileName( const char *a_cFileNameString );
    const char*     bitmapWallPaperFileName();
                    // Methods for a "wall-projected-bitmap" source file.
                    // Also see dispBitmapWallPaper(); below...

    cf_ChartType    chartType();
    BOOL            chartTypeBarColStackIs();
    BOOL            chartTypeCartesianIs();
    BOOL            chartTypePolarIs();
                    // Once we get beyond this "base" class, charts
                    // will be either "Cartesian" or "Polar".  This
                    // may cause different requirements for things
                    // like engine index-modes dialogs/displays/etc.
                    // Bar/Col/Stack-type charts have *slightly* different
                    // indexing requirements from "point"-type charts such
                    // as point series, line, and (integral) area charts,
                    // so it helps to keep track of this type/category.

    cf_DispMode     disp2D3DMode();
    virtual BOOL    disp2D3DMode( cf_DispMode enumNewDispMode );

    BOOL            dispBitmapChartWall();
    void            dispBitmapChartWall( BOOL bNewState );
                    // Displays a "wall-projected-bitmap" source file.
                    // Also see bitmapChartWallFileName(); above...

    BOOL            dispBitmapWallPaper();
    void            dispBitmapWallPaper( BOOL bNewState );
                    // Displays a "background-bitmap" source file.
                    // Also see bitmapWallPaperFileName(); above...

    bf_Color        dispColorBackground();
    void            dispColorBackground( const bf_Color &cr_bf_clrNew );

    bf_Color        dispColorFaceBack();
    void            dispColorFaceBack( const bf_Color &cr_bf_clrNew );

    bf_Color        dispColorFaceBottom();
    void            dispColorFaceBottom( const bf_Color &cr_bf_clrNew );

    bf_Color        dispColorFaceLeft();
    void            dispColorFaceLeft( const bf_Color &cr_bf_clrNew );

    bf_Color        dispColorFaceLines();
    void            dispColorFaceLines( const bf_Color &cr_bf_clrNew );
                    // display-attribute methods for chart-face-colors

    BOOL            dispFaceBack();
    void            dispFaceBack( BOOL bNewState );

    BOOL            dispFaceBottom();
    void            dispFaceBottom( BOOL bNewState );

    BOOL            dispFaceLeft();
    void            dispFaceLeft( BOOL bNewState );
                    // Manipulate the ON/OFF display attributes of
                    // the Back and/or Left and/or Bottom chart-faces

    BOOL            dispForceBackBorder();
    void            dispForceBackBorder( BOOL bNewState );
                    // Force background rect poly-line to render
                    // into the display.  Useful for "stubborn"
                    // print-display contexts.  C-tor inits OFF.

    BOOL            dispForceBackColor();
    void            dispForceBackColor( BOOL bNewState );
                    // Force FILLED background rectangle to render
                    // into the display.  Useful for "stubborn"
                    // print-display contexts.  C-tor inits OFF.

    void            dispVirtCentroid( BOOL bNewState );
    void            dispVirtObjMaxPoint( BOOL bNewState );
    void            dispVirtObjMinPoint( BOOL bNewState );
                    // Get/set "draw-virtual-points" modes ON/OFF.

    BOOL            dispWireFrameMode();
    void            dispWireFrameMode( BOOL bNewState );
                    // Wire-Frameing skips Hidden-Surface-Elimination
                    // and/or Depth-Sorting ops and so is MUCH more
                    // efficient when directly manipulating chart
                    // configurations (such as in dialogs, etc...)

    BOOL            dispZoomMode();
    void            dispZoomMode( BOOL bNewState );
                    // When Zoom-Mode is TRUE, the chart-engine IGNORES
                    // any user-specified margins when it calcs the
                    // display-context rendering projection-rectangle.

    virtual void    draw( bf_Display *p_bf_dspOutputDisplay );
                    // Self-explanatory.  Chart-Engines render into
                    // a display-context provided by their parent
                    // chart-model, which itself has a display-
                    // context provided by a parent chart-view.

    cf_TitleMarkerMgr*
                    markerMgrTitlesAxes();
                    // Access the chart-engine "Text-Marker-Manager"
                    // object that can be used to control and access
                    // the EXISTING set of title, sub-title, and
                    // axis-label 3D-Text-Markers.


    cf_3DTextMarkerSeries*
                    markerMgrUserLegends();
                    // Access the chart-engine "3D-Text-Marker-Series"
                    // that can be used to create and control EXTRA
                    // user-specified 3D-text-markers for use as
                    // chart-legends, etc.


    double          measuredDataXRangeMin();
    double          measuredDataXRangeMax();
    double          measuredDataYRangeMin();
    double          measuredDataYRangeMax();
    double          measuredDataZRangeMin();
    double          measuredDataZRangeMax();

    double          measuredVirtXOrigin();
    double          measuredVirtYOrigin();
    double          measuredVirtZOrigin();

    double          measuredVirtXRangeMin();
    double          measuredVirtXRangeMax();
    double          measuredVirtYRangeMin();
    double          measuredVirtYRangeMax();
    double          measuredVirtZRangeMin();
    double          measuredVirtZRangeMax();
                    // Data-query methods used by chart-objects
                    // encapsulated by this chart-engine (which likely
                    // do NOT have direct access to this chart-engine's
                    // parent-chart-model) -- such as automatic-axis
                    // grid/tick-series objects.


    BOOL    positPointAt(   cf_3DPoint  *p_cf_3dpTargetPoint,
                            double      dPctWidthFromCtr,
                            double      dPctHeightFromCtr,
                            double      dPctDepthFromCtr = 0.0,
                            BOOL        bCorrectOriginOffset = FALSE );
            // Allows user classes (e.g. axis grid/tick/series) to
            // over-ride any default positioning of a 3D Point (e.g.
            // Axis Label Text Marker Points) and specify a new posit
            // as an X/Y/Z % val away from the CENTER of the 3D Box
            // of the chart.  Positive OR negative % vals are allowed.
            // Note that optional correction for default origin xlation
            // (e.g. when grid/tick-series are added to engines via
            // the "add-Component-Object(...)" method) is available,
            // but is NOT the default mode of operation.

    //------------------------------------------------------------
    // The chart-engine "preference" methods below typically
    // pass their parameters directly to a corresponding member
    // method of the geometry-kernel object associated with this
    // chart-engine, and are provided in this chart-engine object
    // basically for convenience...
    //------------------------------------------------------------
    void    preferMarginTop(    int iMarginInTwips );
    void    preferMarginBottom( int iMarginInTwips );
    void    preferMarginLeft(   int iMarginInTwips );
    void    preferMarginRight(  int iMarginInTwips );

    void    preferMargins(  int iTopMarginInTwips,
                            int iBottomMarginInTwips,
                            int iLeftMarginInTwips,
                            int iRightMarginInTwips );
            // Adds a margin in Twips (1/20 of a standard typographic
            // point, which is 1/72 of an English Inch) to the the
            // display-context rendering projection-rectangle.

    void    preferPerspective(  double  dPercentPerspective,
                                BOOL    bReCalcKernelGeom = TRUE,
                                BOOL    bApplyGeomXform = TRUE );
    void    preferPerspectiveMax();
    void    preferPerspectiveNormal();
    void    preferPerspectiveZero();
            // The "normal" chart-engine disply mode is ISOMETRIC
            // projection (i.e. zero-perspective).  However, any
            // given chart-engine has full visual perspective
            // rendering capability.

    void    preferProportions(  double  dPrefHWPercentRatio,
                                double  dPrefDHPercentRatio = 1.00,
                                BOOL    bPerformAutoConfigure = TRUE );
            // Sets the height-to-width and depth-to-height ratios
            // of the 3D-Box that the chart-engine renders its
            // collection of objects into...

    void    preferViewAngle(    double  dSetXAngle,
                                double  dSetYAngle,
                                BOOL    bReCalcKernelGeom = TRUE,
                                BOOL    bApplyGeomXform = TRUE );
            // Sets a view-angle used in 3D-display mode.  Note that
            // the y-view angle parameter should be NEGATIVE, as
            // per a right-hand-rule/system rotation..,



    virtual void    resetEngineObjects();
                    // This modular functionality is usually called immediately
                    // before applying a chart-engine update from a chart-model.


protected:  //===================================================
            // ChartFolio "Chart-Engine" classes derived from
            // this virtual base class MIGHT need to be able to
            // touch these vars & methods, but (non-expert)
            // users should NOT muck around with this stuff...
            //===================================================


    cf_Kernel   *p_cf_kEnginesKernel_;
    BOOL        bWasEnginesKernelNewed_;
                // Keep track if we are *borrowing* someone else's kernel!


    void    addCompoObject( cf_Virt3DObj *p_cf_objAddThisObject );
    void    addFaceObject( cf_Virt3DObj *p_cf_objAddThisObject );
    void    addSpaceObject( cf_Virt3DObj *p_cf_objAddThisObject );
    void    addMarkerObject( cf_Virt3DObj *p_cf_objAddThisObject );
            // As (derived) chart-engines generate 2D/3D geometric
            // chart-objects based on the data-state of the parent
            // chart-model, they call these methods to add these
            // newly-created objects into one of a set of dynamic
            // arrays so they can be tracked for geometric
            // transforms and projections, scaling and xlation,
            // rendering ops, etc.

    //-------------------------------------------------------------
    // These *virtual* methods provide modular functional
    // implmentations that are OFTEN over-ridden for specific
    // and/or added functionality in derived chart-engine classes...
    //-------------------------------------------------------------
    virtual void    applyVirtScalings();
    virtual void    applyVirtTranslations();
                    // Modular functions used during the auto-configure
                    // phase of chart-engine update ops.  These guys
                    // use values calc-ed by the "calc-methods" below...

    virtual void    calcVirtScaleFactors();
    virtual void    calcVirtTransFactors();
                    // These modular functions calc values used during
                    // the auto-configure phase of chart-engine update
                    // ops. These guys use values measured by the
                    // "measure-methods" below...

    virtual void    config3DBoxETC();
                    // Modular sub-functions used in auto-configuration.

    virtual void    draw2D( bf_Display *p_bf_dspOutputDisplay );
    virtual void    draw3D( bf_Display *p_bf_dspOutputDisplay );

    virtual void    init3DBoxETC();
    virtual void    initDrawingAttribs();
    virtual void    initGridTickSeries();
    virtual void    initObjectDynamicStorage();
    virtual void    initTextMarkers();
                    // Modular initializers for use in c-tor(s)

    virtual void    measureDataMinMax( cf_ChartModel *p_cf_cmodlDataSource );
    virtual void    measureVirtMinMax();
    virtual void    measureVirtOrigin();
                    // These modular functions measure values used
                    // during the auto-configure phase of chart-engine
                    // update ops. These guys yield values used by the
                    // "calc-methods" above...

    virtual void    updateAxisGridTickSeries
                    ( cf_ChartModel *p_cf_cmodlDataSource );
                    // Modular sub-method called by the chart-engine's
                    // updateFromChartModel() "master-update-method".

    virtual void    updateAxisRangeBufferPoints
                    ( cf_ChartModel *p_cf_cmodlDataSource );

    cf_3DPoint      cf_3dpEngObjVirtMin_;
    cf_3DPoint      cf_3dpEngObjVirtMax_;
    cf_3DPoint      cf_3dpEngineCentroid_;

                    // Modular sub-method called by the chart-engine's
                    // updateFromChartModel() "master-update-method".
                    // Implements axis range-buffering by updating
                    // "invisible 3D-points" which track the virtual
                    // max/min dimensions of the chart-engine and the
                    // objects therein...

    virtual void    updateYValsOnNatNs
                    ( cf_ChartModel *p_cf_cmodlDataSource );

    virtual void    updateYValsAtIntIs
                    ( cf_ChartModel *p_cf_cmodlDataSource );
                    // Modular sub-method called by the chart-engine's
                    // updateFromChartModel() "master-update-method".
                    // These are VERY virtual -- all the "real"
                    // work takes place in the derived engine types

    //====================================
    // Chart Engine "Type/Method-ID" vars:
    //====================================
    cf_ChartType    cf_enumChartEngineType_;
    cf_DispMode     cf_enumCurrentDisplayMode_;

    //--------------------------------------------------------
    // Declare vars for the 3D Box Faces (and background):
    //--------------------------------------------------------
    cf_3DPolygon    cf_3dpgBackFace_,
                    cf_3dpgLeftFace_,
                    cf_3dpgBottomFace_;

    cf_DispAttribs  *p_cf_datbBackFace_,
                    *p_cf_datbLeftFace_,
                    *p_cf_datbBottomFace_;

    bf_Color        bf_clrCurrentBackground_;

    BOOL        bDoWeDrawBackFace_,
                bDoWeDrawLeftFace_,
                bDoWeDrawBottomFace_;

    int         iPrefLeftFaceFontHeight_,
                iPrefLeftFaceFontWidth_,
                iPrefBackFaceFontHeight_,
                iPrefBackFaceFontWidth_,
                iPrefBottomFaceFontHeight_,
                iPrefBottomFaceFontWidth_;

    //---------------------------------------------
    // Declare vars for the Chart's Bitmap Wall:
    //---------------------------------------------
    cf_3DBitmap     *p_cf_3dbmpProjectedBitmap_;
    BOOL            bDoWeDrawBitmapWall_;

    //----------------------------------------
    // Declare vars for Grid/Tick Mark Series:
    //----------------------------------------
    cf_3DGridTickSeries *p_cf_3dgtsXonBackFace_;
    cf_3DGridTickSeries *p_cf_3dgtsXonBottomFace_;
    cf_3DGridTickSeries *p_cf_3dgtsYonLeftFace_;
    cf_3DGridTickSeries *p_cf_3dgtsYonBackFace_;
    cf_3DGridTickSeries *p_cf_3dgtsZonLeftFace_;
    cf_3DGridTickSeries *p_cf_3dgtsZonBottomFace_;
    cf_3DGridTickSeries *p_cf_3dgtsPolarOnFloor_;

    //-----------------------------------------------------------
    // Declare a Chart Text-Marker-Manager that can be used to
    // control and access the existing title, sub-title, and
    // axis-label text markers:
    //-----------------------------------------------------------
    cf_TitleMarkerMgr       *p_cf_tmmTitlesAxes_;

    //------------------------------------------------------------
    // Declare a Chart Text-Marker-Series Object that can be used
    // to create and control EXTRA user-specified 3D-text-markers
    // such as chart-legends, etc.
    //------------------------------------------------------------
    cf_3DTextMarkerSeries   *p_cf_3dtmsUserLegends_;

    //------------------------------------------------------------
    // Declare vars for an (optional) BACKGROUND Display Bitmap:
    //------------------------------------------------------------
    cf_String           cf_strWallPaperFile_;
    BOOL                bDoWeDrawWallPaper_;
    bf_2DBitmap         *p_bf_2dbmpWallPaper_;

    //---------------------------------------------------
    // Members for the chart origins and dimensions:
    //---------------------------------------------------
    double  d3DBoxXDim_, d3DBoxYDim_, d3DBoxZDim_;
            // To be set = this->p_cf_kEngineKernel->getXDim(), etc.

    double  dChartXOrigin_,  dChartYOrigin_,  dChartZOrigin_;
            // For cartestian/XYZ -- set equal to the far right corner,
            // for polar/pie -- set equal to the middle of the floor.

    //------------------------------------------------------------
    // Members to hold the Chart Engine's cf_Virt3DObj Components:
    //------------------------------------------------------------
    cf_DyArr    da_p_cf_objCompoObjects_;
    int         iNumCompoObjects_;
                // This list is primarily for cf_ChartEngine-derived
                // classes to add additional objects ONTO the chart,
                // e.g. class Cartesian Engines, will add X,Y,Z axis
                // grod/tick-mark series, etc.

    cf_DyArr    da_p_cf_objFaceObjects_;
    int         iNumFaceObjects_;
                // This list is primarily for DATA objects AGAINST
                // THE FACES of the cf_ChartModel, e.g., Control
                // Line objects, or the Marker-Line objects,
                // that are ON the faces of the 3D-Box:

    cf_DyArr    da_p_cf_objSpaceObjects_;
    int         iNumSpaceObjects_;
                // This list is primarily for objects IN THE 3D SPACE of
                // the engine's 3D-Box, e.g. Ribbons, PolyHedraSeries, etc,

    cf_DyArr    da_p_cf_objMarkerObjects_;
    int         iNumMarkerObjects_;
                // This list is primarily for text-marker/chart-legend
                // objects projected ON TOP OF the 2D/3D Objects in
                // a 2D/3D Chart-Engine's 3D-Box.

    //-------------------------------------------------------------
    // Member Vars to track this cf_ChartEngine's "DATA" (Data
    // & Range) Mins/Maxes for Dynamic and/or Data-Dependent Ops:
    //-------------------------------------------------------------
    double  dChartXRangeMin_, dChartYRangeMin_, dChartZRangeMin_;
    double  dChartXRangeMax_, dChartYRangeMax_, dChartZRangeMax_;
            // Keeping track of the original DATA values enables
            // operations such as tick marks resets (e.g. dynamically,
            // every time this Engine gets re-proportioned)...

    //------------------------------------------------------------
    // Member Vars to track this cf_ChartEngine's "VIRTUAL" (Data
    // & Range) Mins/Maxes. for Dynamic Chart (re)Scaling Ops:
    //------------------------------------------------------------
    double  dVirtXRangeMin_, dVirtYRangeMin_, dVirtZRangeMin_;
    double  dVirtXRangeMax_, dVirtYRangeMax_, dVirtZRangeMax_;
            // It is essential to keep track of the virtual
            // transformations resulting from operations such
            // as translations, scalings, geometric transformations,
            // etc of the  original DATA values, so that this
            // cf_ChartEngine's cf_Virt3DObjs can be re-scaled
            // correctly -- and dynamically -- with each Engine
            // re-proportioning event:

    //------------------------------------------------------
    // Member Vars for "User Preferences for Scale Ratios"
    //------------------------------------------------------
    double  dPrefChartHWRatio_, dPrefChartDHRatio_;
            // The user can set these two ratios, and they will
            // control the other Scale Factors and Ratios below:

    double  dChartObjectXScaleFactor_;
    double  dChartObjectYScaleFactor_;
    double  dChartObjectZScaleFactor_;
            // These are the ratios that this cf_ChartEngine's
            //"virtual" cf_Virt3DObjs will actualy get scaled to.

    double  dChartObjectXTransFactor_;
    double  dChartObjectYTransFactor_;
    double  dChartObjectZTransFactor_;

    //-------------------------------------------------------------
    // Member vars for "Run-Time Geometry/Draw States":
    //-------------------------------------------------------------
    BOOL    bInWireFrameMode_;               // C-tor inits to FALSE.
    BOOL    bForceRenderOfBackColorRect_;    // C-tor inits to FALSE.
    BOOL    bForceRenderOfBackBorder_;       // C-tor inits to FALSE.

    BOOL    bHasEverRendered_;              // C-tor inits to FALSE.
                                            // First draw() op sets TRUE.

    double  dSaveXAngle_, dSaveYAngle_, dSaveZAngle_, dSavePRatio_;
            // When we switch to 2D mode, we'll need to
            // save view params so we can restore 3D mode.

    int     i,j,k;  // Std "scratch" index vars...

};  // End of cf_ChartEngine declaration.

#endif

//////////////////////////////////////
// END of File: C1_ENGIN.HPP
//////////////////////////////////////
