/////////////////////////////////////////
// START of File: B4_CVIEW.CPP
/////////////////////////////////////////

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

#include	<cf_api/bf_defs.h>
#include    <cf_api/c4_cview.hpp>

//-------------------------------------------------------------
// Implement the "Chart-View" Object(s).  Note that the
// "set-chart-engine-by-type-spec" method activeEngine( ... )
// is implemented in a product/version-dependent file-set:
// b3_cview.cpp or b2_cview.cpp.
//------------------------------------------------------------
cf_ChartView::cf_ChartView
            (   cf_ChartType    enumChartType,
                cf_DispMode     enumDispMode,
                cf_IndexMode    enumIndexMode )

    :   p_ViewsModel_( NULL ),
        bWasViewsModelNewed_( FALSE ),
        p_ViewsEngine_( NULL ),
        bWasViewsEngineNewed_( FALSE ),
        // until *explicitly* set by ctorInit()!

        bIsActivatedForControlsDisplay_( FALSE )
        // ...until set TRUE by the the parent chart-control's
        // first call to this->activate( bf_Display ), or FALSE
        // by a new call to this->activeEngine( cf_ChartEngine* )!

{
    // Allocate a chart-model to hold our user chart-data:
    p_ViewsModel_ = new cf_ChartModel(  this, enumIndexMode );
    bWasViewsModelNewed_ = TRUE; // so d-tor will know what we did!...

    // Allocate a chart-engine which will reference this chart-model
    // to generate its collection of components and chart-geom objects:
    activeEngine(   enumChartType,
                    enumDispMode,
                    FALSE );    // There is no previous engine to delete!

    //******************************************************************
    // Note these VERY IMPORTANT side-effects!
    //  bWasViewsEngineNewed_ = TRUE;
    //  p_ViewsModel_->activeEngine( p_ViewsEngine );
    //  bIsActivatedForControlsDisplay = FALSE;
    //******************************************************************
}



cf_ChartView::~cf_ChartView()
{
    if ( bWasViewsModelNewed_ == TRUE ) delete p_ViewsModel_;
    if ( bWasViewsEngineNewed_ == TRUE ) delete p_ViewsEngine_;
}




BOOL
cf_ChartView::activatedIs()
{
    return( bIsActivatedForControlsDisplay_ );
}


void
cf_ChartView::activate
            ( bf_Display *p_bf_dspToRenderInto )
{
    // Called by this chart-view's parent chart-control
    // to sychronize the chart-view's encapsulated kernel,
    // model, and engine for an initial display rendering.
    updateDisplayMetrics( p_bf_dspToRenderInto );
        // Note that if display context locks and/or mutexes are required,
        // the parent chart-control MUST have already done them for us!

    // Force a chart-engine update from the current chart-model...
    p_ViewsModel_->updateViewingEngines(    TRUE,   // force a data-update
                                            TRUE,   // and an auto-config
                                            TRUE,   // and a geom-xform
                                            TRUE,   // and a proj-xform
                                            TRUE ); // sync display-metrics

    // Note the alternate valid implementation:
    /*
    updateDisplayMetrics( p_bf_dspToRenderInto );
    p_ViewsEngine_->autoConfigure();
    p_ViewsEngine_->applyDispMetrics();
    p_ViewsEngine_->applyDataUpdate( p_ViewsModel_ );
    p_ViewsEngine_->applyGeomXform();
    p_ViewsEngine_->applyProjXform();
      */

    bIsActivatedForControlsDisplay_  = TRUE;
}




//================================================================
// Implement the parent Chart-Control's component-access methods:
//================================================================
cf_3DGridTickSeries*
cf_ChartView::activeAxis( cf_ChartAxis  enumChartAxisSelector )
{
    cf_3DGridTickSeries *p_ActivatedGTS = NULL;

    switch ( enumChartAxisSelector )
    {
        case    CF_AXIS_X_BOTTOM:
                p_ActivatedGTS = p_ViewsEngine_->axis_X_BottomFace();
                break;

        case    CF_AXIS_X_BACK:
                p_ActivatedGTS = p_ViewsEngine_->axis_X_BackFace();
                break;

        case    CF_AXIS_Y_LEFT:
                p_ActivatedGTS = p_ViewsEngine_->axis_Y_LeftFace();
                break;

        case    CF_AXIS_Y_BACK:
                p_ActivatedGTS = p_ViewsEngine_->axis_Y_BackFace();
                break;

        case    CF_AXIS_Z_BOTTOM:
                p_ActivatedGTS = p_ViewsEngine_->axis_Z_BottomFace();
                break;

        case    CF_AXIS_Z_LEFT:
                p_ActivatedGTS = p_ViewsEngine_->axis_Z_LeftFace();
                break;

        case    CF_AXIS_POLAR_FLOOR:
                p_ActivatedGTS = p_ViewsEngine_->axis_Polar_Floor();
                break;

        default:
                p_ActivatedGTS = p_ViewsEngine_->axis_X_BottomFace();
                break;
    }
    return( p_ActivatedGTS );
}


cf_ChartEngine*
cf_ChartView::activeEngine()
{
    return this->p_ViewsEngine_;
}


BOOL
cf_ChartView::activeEngine
            (   cf_ChartEngine  *p_cf_engCustomized,
                BOOL            bDeleteOldEngine )
{
    // Don't step into this if something is FUBAR!
    if ( p_cf_engCustomized == NULL ) return FALSE;

    // IF any kind of new/malloc has already been made for this chart-
    // model's engine, we're gonna hafta do some kind of delete op...
    cf_ChartEngine  *p_cf_engOldEngine = p_ViewsEngine_;
    p_ViewsEngine_ = p_cf_engCustomized;

    // Now -- should (and can) we get rid of the old (original) engine?
    if( bDeleteOldEngine == TRUE )
        if ( bWasViewsEngineNewed_ == TRUE )
            if( p_cf_engOldEngine != NULL )
                delete p_cf_engOldEngine;

    // Keep track of what we did w.r.t. new()-ing, etc:
    bWasViewsEngineNewed_ = TRUE;

    // Let the chart-model know which engine to notify on data-state changes:
    p_ViewsModel_->activeEngine( p_ViewsEngine_ );

    // Make sure this new chart-engine will get re-synchronized to the
    // parent chart-control's display upon the first re-draw operation...
    bIsActivatedForControlsDisplay_ = FALSE;

    p_ViewsEngine_->applyDataUpdate( p_ViewsModel_ );

    return TRUE;

}   // end of cf_ChartView::activeEngine( cf_ChartEngine*, BOOL )



//********************************************************************
// NOTE that the primary chart-view "set-engine-type" member method:
//
//  BOOL
//  cf_ChartView::activeEngine
//              (   cf_ChartType    enumChartType,
//                  cf_DispMode     enumDispMode,
//                  BOOL            bDeleteOldEngine )
//
// Is implemented in ONE of these SEPARATE source files:
// "b2_cview.cpp", or "b3_cview.cpp"  -- depending upon the
// specific framework and version of the ChartFolio Product/SKU
//
//********************************************************************



cf_ChartModel*
cf_ChartView::activeModel()
{
    return this->p_ViewsModel_;
}




//==============================================================
// Facilitate the parent Chart-Control's add-data(...) methods:
//==============================================================
cf_XYZ&
cf_ChartView::addData
            (   int         iDataGroupNum,
                double      dYVal )
{
    if ( iDataGroupNum != p_ViewsModel_->dataGroupActive() )
        p_ViewsModel_->activateGroupUserData( iDataGroupNum );

    cf_XYZ  *p_ReturnVal = p_ViewsModel_->addDataYVal( dYVal );
    return( *p_ReturnVal );
}


cf_XYZ&
cf_ChartView::addData
            (   int         iDataGroupNum,
                double      dXVal,
                double      dYVal )
{
    if ( iDataGroupNum != p_ViewsModel_->dataGroupActive() )
        p_ViewsModel_->activateGroupUserData( iDataGroupNum );

    cf_XYZ  *p_ReturnVal = p_ViewsModel_->addDataXYVal( dXVal, dYVal );
    return( *p_ReturnVal );
}

cf_XYZ&
cf_ChartView::addData
            (   int         iDataGroupNum,
                double      dXVal,
                double      dYVal,
                double      dZVal )
{
    if ( iDataGroupNum != p_ViewsModel_->dataGroupActive() )
        p_ViewsModel_->activateGroupUserData( iDataGroupNum );

    cf_XYZ  *p_ReturnVal= p_ViewsModel_->addDataXYZVal( dXVal, dYVal, dZVal );
    return( *p_ReturnVal );
}



//===============================================================
// Facilitate the parent Chart-Control's add-label(...) methods:
//===============================================================
cf_DataGroup&
cf_ChartView::setLabelAxisName
            (   const char      *p_strAxisLabel,
                cf_ChartAxis    enumChartAxisSelector,
                double          dPercentFromXCenterCoord,
                double          dPercentFromYCenterCoord,
                double          dPercentFromZCenterCoord )
{
    cf_DataGroup  *p_cf_dgReturnVal
                    = p_ViewsModel_->labelAxis( p_strAxisLabel,
                                                enumChartAxisSelector,
                                                dPercentFromXCenterCoord,
                                                dPercentFromYCenterCoord,
                                                dPercentFromZCenterCoord );
    bIsActivatedForControlsDisplay_ = FALSE;
    return( *p_cf_dgReturnVal );
}


cf_DataGroup&
cf_ChartView::setLabelAxisName
            (   const char      *p_strAxisLabel,
                cf_ChartAxis    enumChartAxisSelector )
{
    cf_DataGroup  *p_cf_dgRetVal = NULL;

    switch ( enumChartAxisSelector )
    {
        case    CF_AXIS_POLAR_FLOOR:
                p_cf_dgRetVal = p_ViewsModel_->labelAxis(   p_strAxisLabel,
                                                            CF_AXIS_POLAR_FLOOR,
                                                            0, -120, 120 );
                break;

        case    CF_AXIS_Z_LEFT:
                p_cf_dgRetVal = p_ViewsModel_->labelAxis(   p_strAxisLabel,
                                                            CF_AXIS_Z_LEFT,
                                                            -110, 110, 0 );
                break;

        case    CF_AXIS_Z_BOTTOM:
                p_cf_dgRetVal = p_ViewsModel_->labelAxis(   p_strAxisLabel,
                                                            CF_AXIS_Z_BOTTOM,
                                                            110, -110, 0 );
                break;

        case    CF_AXIS_Y_BACK:
                p_cf_dgRetVal = p_ViewsModel_->labelAxis(   p_strAxisLabel,
                                                            CF_AXIS_Y_BACK,
                                                            125, 100, -125 );
                break;

        case    CF_AXIS_Y_LEFT:
                p_cf_dgRetVal = p_ViewsModel_->labelAxis(   p_strAxisLabel,
                                                            CF_AXIS_Y_LEFT,
                                                            -125, -100, 125 );
                break;

        case    CF_AXIS_X_BACK:
                p_cf_dgRetVal = p_ViewsModel_->labelAxis(   p_strAxisLabel,
                                                            CF_AXIS_X_BACK,
                                                            100, 120, -120 );
                break;

        case    CF_AXIS_X_BOTTOM:
        default:
                p_cf_dgRetVal = p_ViewsModel_->labelAxis(   p_strAxisLabel,
                                                            CF_AXIS_X_BOTTOM,
                                                            -100, -125, 125 );
                break;

    }

    bIsActivatedForControlsDisplay_ = FALSE;
    return( *p_cf_dgRetVal );
}



cf_XYZ&
cf_ChartView::addLabelAxisItem
            (   const char      *p_strAxisItemLabel,
                cf_AxisData     enumAxisDataSource,
                double          dAxisIndexLocation )
{
    cf_XYZ  *p_RetVal = NULL;

    if ( ( enumAxisDataSource == CF_AXIS_DOMAIN_LABELS )
            ||  ( enumAxisDataSource == CF_AXIS_DOMAIN_DATA ) )
    {
        p_RetVal = p_ViewsModel_->addLabelDomainItem(   dAxisIndexLocation,
                                                        p_strAxisItemLabel );
    }
    else if ( ( enumAxisDataSource == CF_AXIS_RANGE_LABELS )
            || ( enumAxisDataSource == CF_AXIS_RANGE_DATA ) )
    {
        p_RetVal = p_ViewsModel_->addLabelRangeValue(   dAxisIndexLocation,
                                                        p_strAxisItemLabel );
    }
    else if ( ( enumAxisDataSource == CF_AXIS_GROUP_LABELS )
            || ( enumAxisDataSource == CF_AXIS_GROUP_DATA ) )
    {
        p_RetVal = p_ViewsModel_->addLabelGroupsList(   dAxisIndexLocation,
                                                        p_strAxisItemLabel );
    }

    bIsActivatedForControlsDisplay_ = FALSE;
    return( *p_RetVal );
}

cf_XYZ&
cf_ChartView::addLabelAxisItem
            (   double          dValueForLabel,
                cf_AxisData     enumAxisDataSource,
                double          dAxisIndexLocation )
{
    cf_XYZ  *p_RetVal = NULL;

    if ( enumAxisDataSource == CF_AXIS_DOMAIN_LABELS )
        p_RetVal = p_ViewsModel_->addLabelDomainItem(   dAxisIndexLocation,
                                                        dValueForLabel );
    else if ( enumAxisDataSource == CF_AXIS_RANGE_DATA )
        p_RetVal = p_ViewsModel_->addLabelRangeValue(   dAxisIndexLocation,
                                                        dValueForLabel );
    else
        p_RetVal = p_ViewsModel_->addLabelGroupsList(   dAxisIndexLocation,
                                                        dValueForLabel );
    bIsActivatedForControlsDisplay_ = FALSE;
    return( *p_RetVal );
}



cf_DataGroup&
cf_ChartView::addLabelLegend
            (   const char  *p_strLegendLabel,
                double      dPercentFromXCenterCoord,
                double      dPercentFromYCenterCoord,
                double      dPercentFromZCenterCoord )
{
    cf_DataGroup  *p_cf_dgReturnVal
                    = p_ViewsModel_->labelLegendNew(    p_strLegendLabel,
                                                dPercentFromXCenterCoord,
                                                dPercentFromYCenterCoord,
                                                dPercentFromZCenterCoord );
    bIsActivatedForControlsDisplay_ = FALSE;
    return( *p_cf_dgReturnVal );
}


cf_DataGroup&
cf_ChartView::setLabelTitle
            (   const char      *p_strTitleLabel,
                cf_ChartTitle   enumChartTitleSelector,
                double          dPercentFromXCenterCoord,
                double          dPercentFromYCenterCoord,
                double          dPercentFromZCenterCoord )
{
    cf_DataGroup  *p_cf_dgReturnVal
                    = p_ViewsModel_->labelTitle(    p_strTitleLabel,
                                                    enumChartTitleSelector,
                                                    dPercentFromXCenterCoord,
                                                    dPercentFromYCenterCoord,
                                                    dPercentFromZCenterCoord );
    bIsActivatedForControlsDisplay_ = FALSE;
    return( *p_cf_dgReturnVal );
}

cf_DataGroup&
cf_ChartView::setLabelTitle
            (   const char      *p_strTitleLabel,
                cf_ChartTitle   enumChartTitleSelector )
{
    cf_DataGroup  *p_cf_dgRetVal = NULL;

    switch ( enumChartTitleSelector )
    {
        case    CF_TITLE_SUB:
                p_cf_dgRetVal = p_ViewsModel_->labelTitle(  p_strTitleLabel,
                                                            CF_TITLE_SUB,
                                                            0, 115, -115 );
                break;

        case    CF_TITLE_MAIN:
        default:
                p_cf_dgRetVal = p_ViewsModel_->labelTitle(  p_strTitleLabel,
                                                            CF_TITLE_MAIN,
                                                            0, 125, -125 );
                break;
    }

    bIsActivatedForControlsDisplay_ = FALSE;
    return( *p_cf_dgRetVal );
}



//=========================================================================
// Facilitate the parent Chart-Control's display/text-attrib(...) methods:
//=========================================================================
cf_DispAttribs*
cf_ChartView::attribAxisItemDisp
            ( cf_ChartAxis  enumChartAxisSelector )
{
    cf_DataGroup *p_DG = p_ViewsModel_->activateGroupAxis( enumChartAxisSelector );
    return( p_DG->dispAttribs() );
}


cf_TextAttribs*
cf_ChartView::attribAxisItemText
            ( cf_ChartAxis  enumChartAxisSelector )
{
    cf_DataGroup *p_DG = p_ViewsModel_->activateGroupAxis( enumChartAxisSelector );
    return( p_DG->textAttribs() );
}



cf_DispAttribs*
cf_ChartView::attribAxisNameDisp
            ( cf_ChartAxis  enumChartAxisSelector )
{
    cf_DataGroup *p_DG = p_ViewsModel_->activateGroupAxisLabel( enumChartAxisSelector );
    return( p_DG->dispAttribs() );
}


cf_TextAttribs*
cf_ChartView::attribAxisNameText
            ( cf_ChartAxis  enumChartAxisSelector )
{
    cf_DataGroup *p_DG = p_ViewsModel_->activateGroupAxisLabel( enumChartAxisSelector );
    return( p_DG->textAttribs() );
}


cf_DispAttribs*
cf_ChartView::attribChartFaceDisp( cf_ChartFace enumChartFaceSelector )
{
    return( p_ViewsEngine_->attribChartFaceDisp( enumChartFaceSelector ) );
}


cf_DispAttribs*
cf_ChartView::attribDataGroupDisp
            ( int iDataGroupNumber )
{
    cf_DataGroup *p_DG = p_ViewsModel_->activateGroupUserData( iDataGroupNumber );
    return( p_DG->dispAttribs() );
}


cf_TextAttribs*
cf_ChartView::attribDataGroupText
            ( int iDataGroupNumber )
{
    cf_DataGroup *p_DG = p_ViewsModel_->activateGroupUserData( iDataGroupNumber );
    return( p_DG->textAttribs() );
}



cf_DispAttribs*
cf_ChartView::attribLegendDisp
            ( int iUserLegendNumber )
{
    cf_DataGroup *p_DG = p_ViewsModel_->activateGroupLegend( iUserLegendNumber );
    return( p_DG->dispAttribs() );
}


cf_TextAttribs*
cf_ChartView::attribLegendText
            ( int iUserLegendNumber )
{
    cf_DataGroup *p_DG = p_ViewsModel_->activateGroupLegend( iUserLegendNumber );
    return( p_DG->textAttribs() );
}



cf_DispAttribs*
cf_ChartView::attribTitleDisp
            ( cf_ChartTitle   enumChartTitleSelector )
{
    cf_DataGroup *p_DG = p_ViewsModel_->activateGroupTitle( enumChartTitleSelector );
    return( p_DG->dispAttribs() );
}


cf_TextAttribs*
cf_ChartView::attribTitleText
            ( cf_ChartTitle   enumChartTitleSelector )
{
    cf_DataGroup *p_DG = p_ViewsModel_->activateGroupTitle( enumChartTitleSelector );
    return( p_DG->textAttribs() );
}



//===================================================================
// Facilitate the parent Chart-Control's component-behavior methods:
//===================================================================
cf_3DGridTickSeries*
cf_ChartView::axisBehavior
            (   cf_ChartAxis    enumChartAxisSelector,
                double          dFreqTicksToData,
                int             iRatioLabelsToTicks,
                int             iRatioGridsToTicks,
                int             iRatioMajorToMinor,
                double          dPercentTickSizeToChart,
                long            lFlags )
{
    cf_3DGridTickSeries *p_gtsTarget = activeAxis( enumChartAxisSelector );
    p_gtsTarget->on();

    BOOL    bDomainAxis = p_gtsTarget->useDomainItemsIs();

    if ( p_gtsTarget->useDomainItemsIs() == TRUE )
    {
        p_gtsTarget->freqTicksToDomainItems( (int) dFreqTicksToData );
    }
    else if ( ( p_gtsTarget->useDataRangeIs() == TRUE )
                || ( p_gtsTarget->useRangeValuesIs() == TRUE ) )
    {
        p_gtsTarget->freqTicksToRangeValues( dFreqTicksToData );
    }
    else if ( ( p_gtsTarget->useDataRangeSumsIs() == TRUE )
                || ( p_gtsTarget->useRangeValSumsIs() == TRUE ) )
    {
        p_gtsTarget->freqTicksToRangeValues( dFreqTicksToData );
    }
    else
    {
        p_gtsTarget->freqTicksToRangeValues( dFreqTicksToData );
    }

    p_gtsTarget->freqTextsToTicks( iRatioLabelsToTicks );
    p_gtsTarget->freqGridsToTicks( iRatioGridsToTicks );
    p_gtsTarget->freqMajorToMinorTicks( iRatioMajorToMinor );
    p_gtsTarget->preferTickSizeRatio( dPercentTickSizeToChart );

    // Resolve flag params relevant to *this* method:
    p_gtsTarget->dispWithHiddenTicks( lFlags & CF_FLAGS_HIDE_TICKS );
    p_gtsTarget->dispWithInvertedTicks( lFlags & CF_FLAGS_INVERT_TICKS );
    if ( ( lFlags & CF_FLAGS_STAGGER_LABELS ) == TRUE )
        attribAxisItemText( enumChartAxisSelector )->staggerDownUp();

    return( p_gtsTarget );
}


cf_3DGridTickSeries*
cf_ChartView::axisDataSource
            (   cf_ChartAxis    enumChartAxisSelector,
                cf_AxisData     enumAxisDataSource,
                BOOL            bNewState )
{
    cf_3DGridTickSeries *p_gtsTarget = activeAxis( enumChartAxisSelector );
    p_gtsTarget->on();

    switch ( enumAxisDataSource )
    {
        case    CF_AXIS_DOMAIN_LABELS:
        case    CF_AXIS_DOMAIN_DATA:
                p_gtsTarget->useDomainItems( bNewState );
                break;

        case    CF_AXIS_RANGE_LABELS:
                if ( p_ViewsEngine_->chartType() == CF_TYPE_STACK )
                    p_gtsTarget->useRangeValSums( bNewState );
                else
                    p_gtsTarget->useRangeValues( bNewState );
                break;

        case    CF_AXIS_RANGE_DATA:
                if ( p_ViewsEngine_->chartType() == CF_TYPE_STACK )
                    p_gtsTarget->useDataRangeSums( bNewState );
                else
                    p_gtsTarget->useDataRange( bNewState );
                break;

        case    CF_AXIS_GROUP_LABELS:
        case    CF_AXIS_GROUP_DATA:
                p_gtsTarget->useDataGroupsList( bNewState );
                break;

        default:
                p_gtsTarget->useNoUpdateSource();
                break;
    }
    return( p_gtsTarget );
}


cf_3DGridTickSeries*
cf_ChartView::axisTicks
            (   cf_ChartAxis    enumChartAxisSelector,
                double          dFreqTicksToData,
                int             iRatioMajorToMinor,
                double          dPercentTickSizeToChart,
                long            lFlags )
{
    cf_3DGridTickSeries *p_gtsTarget = activeAxis( enumChartAxisSelector );
    p_gtsTarget->on();

    if ( p_gtsTarget->useDomainItemsIs() == TRUE )
    {
        p_gtsTarget->freqTicksToDomainItems( (int) dFreqTicksToData );
    }
    else if ( ( p_gtsTarget->useDataRangeIs() == TRUE )
                || ( p_gtsTarget->useRangeValuesIs() == TRUE ) )
    {
        p_gtsTarget->freqTicksToRangeValues( dFreqTicksToData );
    }
    else if ( ( p_gtsTarget->useDataRangeSumsIs() == TRUE )
                || ( p_gtsTarget->useRangeValSumsIs() == TRUE ) )
    {
        p_gtsTarget->freqTicksToRangeValues( dFreqTicksToData );
    }
    else // i.e. ( p_gtsTarget->useDataGroupsListIs() == TRUE )
    {
        p_gtsTarget->freqTicksToRangeValues( dFreqTicksToData );
    }

    p_gtsTarget->freqMajorToMinorTicks( iRatioMajorToMinor );
    p_gtsTarget->preferTickSizeRatio( dPercentTickSizeToChart );

    // Resolve flag params relevant to *this* method:
    p_gtsTarget->dispWithHiddenTicks( lFlags & CF_FLAGS_HIDE_TICKS );
    p_gtsTarget->dispWithInvertedTicks( lFlags & CF_FLAGS_INVERT_TICKS );

    return( p_gtsTarget );
}


cf_3DGridTickSeries*
cf_ChartView::axisGrids
            (   cf_ChartAxis    enumChartAxisSelector,
                int             iRatioGridsToTicks,
                long            lFlags )
{
    cf_3DGridTickSeries *p_gtsTarget = activeAxis( enumChartAxisSelector );
    p_gtsTarget->on();

    p_gtsTarget->freqGridsToTicks( iRatioGridsToTicks );

    // Resolve flag params relevant to *this* method:
    if ( lFlags & CF_FLAGS_HIDE_TICKS  ) p_gtsTarget->dispWithHiddenTicks( TRUE );


    return( p_gtsTarget );
}


cf_3DGridTickSeries*
cf_ChartView::axisLabels
            (   cf_ChartAxis    enumChartAxisSelector,
                int             iRatioLabelsToTicks,
                long            lFlags )
{
    cf_3DGridTickSeries *p_gtsTarget = activeAxis( enumChartAxisSelector );
    p_gtsTarget->on();

    p_gtsTarget->freqTextsToTicks( iRatioLabelsToTicks );

    // Resolve flag params relevant to *this* method:
    if ( lFlags & CF_FLAGS_HIDE_TICKS ) p_gtsTarget->dispWithHiddenTicks( TRUE );
    if ( lFlags & CF_FLAGS_STAGGER_LABELS )
            attribAxisItemText( enumChartAxisSelector )->staggerDownUp();

    return( p_gtsTarget );
}



double
cf_ChartView::axisRangeMin()
{
    return( p_ViewsModel_->dataYValuesMin() );
}

double
cf_ChartView::axisRangeMax()
{
    return( p_ViewsModel_->dataYValuesMax() );
}


BOOL
cf_ChartView::axisRangePref
            (   double  dMinCandidate,
                double  dMaxCandidate )
{
    axisRangeIncludesOrigin( 0.0 );

    p_ViewsModel_->dataRangeInclMinCandidate( dMinCandidate );
    p_ViewsModel_->dataRangeInclMaxCandidate( dMaxCandidate );

    BOOL bReturnVal = FALSE;
    if ( dMinCandidate <= p_ViewsModel_->dataYValuesMin() ) bReturnVal = TRUE;
    if ( dMaxCandidate >= p_ViewsModel_->dataYValuesMax() ) bReturnVal = TRUE;
    return( bReturnVal );
}


BOOL
cf_ChartView::axisRangeIncludesOrigin( BOOL bForceOriginInclusion )
{
    // Would this op have had *any* effect?
    BOOL bRetVal = TRUE;
    if ( ( p_ViewsModel_->dataYValuesMin() <= 0.0 )
            && ( 0.0 <= p_ViewsModel_->dataYValuesMax() ) )
        bRetVal = FALSE;

    p_ViewsModel_->dataRangeInclOrigAlways( bForceOriginInclusion );
    return( bRetVal );
}

BOOL
cf_ChartView::axisRangeIncludesOriginIs()
{
    return( p_ViewsModel_->dataRangeInclOrigAlways() );
}


BOOL
cf_ChartView::axisRangeIncludesOrigin( double dWithinNumDataDeltas )
{
    // Would this op have had *any* effect?
    BOOL bRetVal = TRUE;
    if ( ( p_ViewsModel_->dataYValuesMin() <= 0.0 )
            && ( 0.0 <= p_ViewsModel_->dataYValuesMax() ) )
        bRetVal = FALSE;

    p_ViewsModel_->dataRangeInclOrigFromDelta( dWithinNumDataDeltas );
    return( bRetVal );
}


double
cf_ChartView::axisRangeIncludesOrigin()
{
    return( p_ViewsModel_->dataRangeInclOrigFromDelta() );
}



//==================================================================
// Facilitate the parent Chart-Control's chart-typing(...) methods:
//==================================================================
BOOL
cf_ChartView::chartType
            ( cf_ChartType enumNewChartType )
{
    cf_DispMode     enumCurrDispMode = p_ViewsEngine_->disp2D3DMode();

    activeEngine(   enumNewChartType,
                    enumCurrDispMode,
                    TRUE ); // *deletes* this view's previous chart-engine!
    return TRUE;
}


cf_ChartType
cf_ChartView::chartType()
{
    return( p_ViewsEngine_->chartType() );
}

BOOL
cf_ChartView::chartDispMode
            ( cf_DispMode enumNewDispMode )
{
    cf_ChartType    enumCurrChartType = p_ViewsEngine_->chartType();

    activeEngine(   enumCurrChartType,
                    enumNewDispMode,
                    TRUE ); // *deletes* this view's previous chart-engine!
    return TRUE;
}

cf_DispMode
cf_ChartView::chartDispMode()
{
    return( p_ViewsEngine_->disp2D3DMode() );
}

BOOL
cf_ChartView::chartIndexMode
            ( cf_IndexMode enumNewIndexMode )
{
    return( p_ViewsModel_->dataIndexMethod( enumNewIndexMode, TRUE ) );
    // We reset the index-mode of this view's data-model, and
    // then *force* the model's chart-engine(s) to re-configure.
}

cf_IndexMode
cf_ChartView::chartIndexMode()
{
    return( p_ViewsModel_->dataIndexMethod() );
}



//========================================================================
// Facilitate the parent Chart-Control's geom/view(...) methods:
//========================================================================
BOOL
cf_ChartView::geomViewAngle
            ( cf_DispMode enumNewDispMode )
{
    p_ViewsEngine_->disp2D3DMode( enumNewDispMode );

    // Make sure this new chart-engine will get re-synchronized to the
    // parent chart-control's display upon the first re-draw operation...
    bIsActivatedForControlsDisplay_ = FALSE;

    return TRUE;
}


BOOL
cf_ChartView::geomViewAngle
            (   double  dXAngleZeroToPositive90,
                double  dYAngleZeroToNegative90 )
{
    // Correct any angle params that exceed current operational
    // specs for the chart-engine/geom-kernel view-angles:
    double  dXAngleVal = dXAngleZeroToPositive90;
    double  dYAngleVal = dYAngleZeroToNegative90;

    if ( dXAngleVal < 0.0 ) dXAngleVal = 0.0;
    if ( dXAngleVal > 90.0 ) dXAngleVal = 90.0;

    if ( dYAngleVal < -90.0 ) dYAngleVal = -90.0;
    if ( dYAngleVal > 0.0 ) dYAngleVal = 0.0;

    p_ViewsEngine_->preferViewAngle( dXAngleVal, dYAngleVal, TRUE, TRUE );

    // Make sure this new chart-engine will get re-synchronized to the
    // parent chart-control's display upon the first re-draw operation...
    bIsActivatedForControlsDisplay_ = FALSE;

    return TRUE;
}



//=================================================================
// Facilitate the parent Chart-Control's chart-reset(...) methods:
//=================================================================
void
cf_ChartView::resetAll
            ( BOOL  bForceImmediateReDraw )
{
    p_ViewsModel_->dataGroupsReset();
    p_ViewsModel_->labelAxesReset();
    p_ViewsModel_->labelLegendsReset();
    p_ViewsModel_->labelTitlesReset();
    if ( bForceImmediateReDraw == TRUE ) p_ViewsModel_->updateViewingEngines();
}

void
cf_ChartView::resetData
            ( BOOL  bForceImmediateReDraw )
{
    p_ViewsModel_->dataGroupsReset();
    if ( bForceImmediateReDraw == TRUE ) p_ViewsModel_->updateViewingEngines();
}

void
cf_ChartView::resetLabels
            ( BOOL  bForceImmediateReDraw )
{
    p_ViewsModel_->labelAxesReset();
    if ( bForceImmediateReDraw == TRUE ) p_ViewsModel_->updateViewingEngines();
}

void
cf_ChartView::resetLegends
            ( BOOL  bForceImmediateReDraw )
{
    p_ViewsModel_->labelLegendsReset();
    if ( bForceImmediateReDraw == TRUE ) p_ViewsModel_->updateViewingEngines();
}

void
cf_ChartView::resetTitles
            ( BOOL  bForceImmediateReDraw )
{
    p_ViewsModel_->labelTitlesReset();
    if ( bForceImmediateReDraw == TRUE ) p_ViewsModel_->updateViewingEngines();
}



//========================================================================
// Facilitate the parent Chart-Control's chart-display-mode(...) methods:
//========================================================================
void
cf_ChartView::disp3DBmp
            ( BOOL bNewState )
{
    p_ViewsEngine_->dispBitmapChartWall( bNewState );
}



BOOL
cf_ChartView::disp3DBmpIs()
{
    return( p_ViewsEngine_->dispBitmapChartWall() );
}



void
cf_ChartView::dispColorBackground
            ( bf_Color bf_clrNewVal )
{
    // Update our chart-view's chart-engine to match the
    // color param passed from the parent chart-control...
    p_ViewsEngine_->dispColorBackground( bf_clrNewVal );
                    // ...which will pass this update along
                    // to its encapsulated chart-objects...
}



BOOL
cf_ChartView::draw
            ( bf_Display  *p_bf_dspFromParentControl )
{
    // Are the chart-model and its engine(s) synchronized?
    if ( p_ViewsModel_->updateNeededIs() == TRUE )
        p_ViewsModel_->updateViewingEngines();
                       // Note: we are using 5 default BOOL = FALSE params!

    // Subtle point:  In previous (and perhaps new) versions (which is why
    // we're keeping this comment!) an explicit kernel projection-matrix
    // re-synch op USED to be required!
    /*
    p_ViewsEngine_->activeKernel()
        ->updateDisplayMetrics( p_bf_dspFromParentControl );
     */

    p_ViewsEngine_->draw( p_bf_dspFromParentControl );
    return TRUE;
}



void
cf_ChartView::updateDisplayMetrics
            ( bf_Display *p_bf_dspHasChanged )
{
    // Synchronize the kernel display projection info w/ the display:
    p_ViewsEngine_->activeKernel()->updateDisplayMetrics( p_bf_dspHasChanged );

    // Now update our collection of chart-engine-objects...
    p_ViewsEngine_->applyProjXform();
            //...which use the kernel's re-calc'ed projection state:
    p_ViewsEngine_->applyDispMetrics();
            //...or the kernel's re-measured display-area state.
}


//====================================================
// Implement Rogue Wave zApp-specific Helper-Methods:
//====================================================
void
cf_ChartView::rz_doNothing()
{
}


//-------------------------------------
// End of cf_ChartView Implementation.
//-------------------------------------


/////////////////////////////////////////
// END of File: B4_CVIEW.CPP
/////////////////////////////////////////

