/////////////////////////////////////////
// START of File: C1_XYZ.CPP
/////////////////////////////////////////

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

//
// Include this source file's header file:
//
#include	<cf_api/bf_defs.h>
#include    <cf_api/c1_xyz.hpp> 
            // relative to the IDE's (global) include path: ~/cfrz

//==============================================================
//
// Implement the Chart Framework "XYZ" class.  
// All functions not implemented here are in the *.hpp file.
//
//==============================================================

//
// Default C-Tor:
//
cf_XYZ
    ::cf_XYZ()
{ 
    // Define the "Data point":
    this->dX = this->dY = this->dZ = 0.0; 

    // No "label" -- yet...
    this->p_cf_strLabel = NULL;
    this->bWasLabelNewed = FALSE;
    this->bWasLabelSet  = FALSE;

    this->bInUse = TRUE;
}

cf_XYZ
    ::cf_XYZ( double dInitX, double dInitY, double dInitZ ) 
{
    // Define the "Data point":
    this->dX = dInitX; 
    this->dY = dInitY; 
    this->dZ = dInitZ;

    // No "label" -- yet...
    this->p_cf_strLabel = NULL;
    this->bWasLabelNewed = FALSE;
    this->bWasLabelSet  = FALSE;

    this->bInUse = TRUE;
}

//
// Std D-Tor MUST delete ANY heap allocations from C-Tor:
//
cf_XYZ
    ::~cf_XYZ() 
{
    if ( this->bWasLabelNewed == TRUE )
        if ( this->p_cf_strLabel != NULL )
            delete this->p_cf_strLabel;
            // If we new()ed it -- LOOSE it!
}                   


//
// Implement the '=' operator:
//
cf_XYZ
    cf_XYZ
        ::operator=( const cf_XYZ&  cr_cf_xyzUserVal ) 
{
    // Copy the reference's XYZ Data points:
    this->dX = cr_cf_xyzUserVal.dX;
    this->dY = cr_cf_xyzUserVal.dY;
    this->dZ = cr_cf_xyzUserVal.dZ;

    // Copy the reference's "label" state:
    if ( cr_cf_xyzUserVal.bWasLabelSet == TRUE )
    {
        // Did the target "new" their label?
        if ( cr_cf_xyzUserVal.bWasLabelNewed == TRUE )
        {
            // Let's be careful NOT to RE-new() our own label!
            if ( this->bWasLabelNewed == FALSE )
            {
                this->p_cf_strLabel = new cf_String();
                this->bWasLabelNewed = TRUE;
            }
            *(this->p_cf_strLabel) 
                    = *(cr_cf_xyzUserVal.p_cf_strLabel);
        }
        // Or was the target just pointing to someone else's?
        else
        {
            this->p_cf_strLabel = cr_cf_xyzUserVal.p_cf_strLabel;
            this->bWasLabelNewed = FALSE;
        }
        this->bWasLabelSet = TRUE;  
            // Make note of the fact that we DID set our own label.
    }
    
    this->bInUse = cr_cf_xyzUserVal.bInUse;

    return *this;
} 


//
// Implement the '+' operator:
//
cf_XYZ  cf_XYZ::operator+( const cf_XYZ&    cr_cf_xyzUserVal )
{
    cf_XYZ  cf_xyzReturnVal;

    cf_xyzReturnVal.dX = this->dX + cr_cf_xyzUserVal.dX;
    cf_xyzReturnVal.dY = this->dY + cr_cf_xyzUserVal.dY;
    cf_xyzReturnVal.dZ = this->dZ + cr_cf_xyzUserVal.dZ;

    return cf_xyzReturnVal;
}


//
// Implement the '*' operator:
//
cf_XYZ  cf_XYZ::operator*( const cf_XYZ&    cr_cf_xyzUserVal ) 
{
    cf_XYZ  cf_xyzReturnVal;

    cf_xyzReturnVal.dX = this->dX * cr_cf_xyzUserVal.dX;
    cf_xyzReturnVal.dY = this->dY * cr_cf_xyzUserVal.dY;
    cf_xyzReturnVal.dZ = this->dZ * cr_cf_xyzUserVal.dZ;

    return cf_xyzReturnVal;
}



//
// Std "Assignment" Member Function:
//
void
    cf_XYZ
        ::assign( double dNewX, double dNewY, double dNewZ ) 
{ this->dX = dNewX; this->dY = dNewY; this->dZ = dNewZ; }
// Try for an in-line compilation which smarter compilers might yield...


// Some user objects will want to mark this XYX 
// triplet as being "in-use" or "not-in-use".
BOOL
    cf_XYZ
        ::inUse() 
            { return this->bInUse; }
void
    cf_XYZ
        ::inUse( BOOL bNewState )
            { this->bInUse = bNewState; }

// 
// Optional Label operations:
//
cf_String* 
    cf_XYZ
        ::labelIs()
            { return this->p_cf_strLabel; }
void            
    cf_XYZ
        ::labelNew( const char *a_cStringForNewLabel ) 
{ 
    // Screen to TRY to eliminate bogus values...
    if ( a_cStringForNewLabel != NULL ) 
    // ...which it MAY or MAY NOT, w.r.t. the skill of a given user...
    {
        // ONLY allocate a new label IF we haven't yet done so!
        if ( this->bWasLabelNewed == FALSE )
        {
            this->p_cf_strLabel = new cf_String();
            this->bWasLabelNewed = TRUE;
        }
        // NOW we're OK to copy the string constant...
        *(this->p_cf_strLabel) = a_cStringForNewLabel;
                                //... to the CURRENTLY ALLOCATED label.
    }
    this->bWasLabelSet = TRUE;
    return;
}

void
    cf_XYZ
        ::labelNew( const double    cdValueForNewLabel,
                    const char      *ca_cFormatString )
{
    // ONLY allocate a new label IF we haven't yet done so!
    if ( this->bWasLabelNewed == FALSE )
    {
        this->p_cf_strLabel = new cf_String();
        this->bWasLabelNewed = TRUE;
    }
    // NOW we're OK to reset the CURRENTLY ALLOCATED label...
    this->p_cf_strLabel->reset();
    this->p_cf_strLabel->cf_append( cdValueForNewLabel, ca_cFormatString );
    this->bWasLabelSet = TRUE;
    return;
}

void
    cf_XYZ
        ::labelNew( const int   ciValueForNewLabel,
                    const char  *ca_cFormatString )
{
    // ONLY allocate a new label IF we haven't yet done so!
    if ( this->bWasLabelNewed == FALSE )
    {
        this->p_cf_strLabel = new cf_String();
        this->bWasLabelNewed = TRUE;
    }
    // NOW we're OK to reset the CURRENTLY ALLOCATED label...
    this->p_cf_strLabel->reset();
    this->p_cf_strLabel->cf_append( ciValueForNewLabel, ca_cFormatString );
    this->bWasLabelSet = TRUE;
    return;
}


BOOL
    cf_XYZ
        ::labelSet()
            { return this->bWasLabelSet; }

void
    cf_XYZ
        ::labelUsing( cf_String *p_cf_strSomeoneElsesLabel )
{
    if ( p_cf_strSomeoneElsesLabel != NULL )   
    // ...which it MAY or MAY NOT, w.r.t. the skill of a given user...
    {
        // IF we allocate a string -- it's time to loose it!
        if ( this->bWasLabelNewed == TRUE )
        {
            delete this->p_cf_strLabel;
            this->bWasLabelNewed = FALSE;
        }
        // Point to the other object's string/label:
        this->p_cf_strLabel = p_cf_strSomeoneElsesLabel;
     
        // Update status vars:
        this->bWasLabelSet = TRUE;
    }
    return;
}



//
// Std "Get Member" Functions:
//
double  cf_XYZ::x() { return this->dX; }
double  cf_XYZ::y() { return this->dY; }
double  cf_XYZ::z() { return this->dZ; }

//
// End of class cf_XYZ Implementation.
//

/////////////////////////////////////////
// END of File: C1_XYZ.CPP
/////////////////////////////////////////

