// Copyright (c) Lawrence Livermore National Security, LLC and other VisIt
// Project developers.  See the top-level LICENSE file for dates and other
// details.  No copyright assignment is required to contribute to VisIt.

#include <View2DAttributes.h>
#include <DataNode.h>

const double View2DAttributes::DEFAULT_FULL_FRAME_AUTO_THRESHOLD = 100.0;

//
// Enum conversion methods for View2DAttributes::TriStateMode
//

static const char *TriStateMode_strings[] = {
"On", "Off", "Auto"
};

std::string
View2DAttributes::TriStateMode_ToString(View2DAttributes::TriStateMode t)
{
    int index = int(t);
    if(index < 0 || index >= 3) index = 0;
    return TriStateMode_strings[index];
}

std::string
View2DAttributes::TriStateMode_ToString(int t)
{
    int index = (t < 0 || t >= 3) ? 0 : t;
    return TriStateMode_strings[index];
}

bool
View2DAttributes::TriStateMode_FromString(const std::string &s, View2DAttributes::TriStateMode &val)
{
    val = View2DAttributes::On;
    for(int i = 0; i < 3; ++i)
    {
        if(s == TriStateMode_strings[i])
        {
            val = (TriStateMode)i;
            return true;
        }
    }
    return false;
}

// ****************************************************************************
// Method: View2DAttributes::View2DAttributes
//
// Purpose:
//   Init utility for the View2DAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void View2DAttributes::Init()
{
    windowCoords[0] = 0;
    windowCoords[1] = 0;
    windowCoords[2] = 1;
    windowCoords[3] = 1;
    viewportCoords[0] = 0.1;
    viewportCoords[1] = 0.1;
    viewportCoords[2] = 0.9;
    viewportCoords[3] = 0.9;
    fullFrameActivationMode = Auto;
    fullFrameAutoThreshold = 100;
    xScale = 0;
    yScale = 0;
    windowValid = false;

    View2DAttributes::SelectAll();
}

// ****************************************************************************
// Method: View2DAttributes::View2DAttributes
//
// Purpose:
//   Copy utility for the View2DAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void View2DAttributes::Copy(const View2DAttributes &obj)
{

    for(int i = 0; i < 4; ++i)
        windowCoords[i] = obj.windowCoords[i];

    for(int i = 0; i < 4; ++i)
        viewportCoords[i] = obj.viewportCoords[i];

    fullFrameActivationMode = obj.fullFrameActivationMode;
    fullFrameAutoThreshold = obj.fullFrameAutoThreshold;
    xScale = obj.xScale;
    yScale = obj.yScale;
    windowValid = obj.windowValid;

    View2DAttributes::SelectAll();
}

// Type map format string
const char *View2DAttributes::TypeMapFormatString = VIEW2DATTRIBUTES_TMFS;
const AttributeGroup::private_tmfs_t View2DAttributes::TmfsStruct = {VIEW2DATTRIBUTES_TMFS};


// ****************************************************************************
// Method: View2DAttributes::View2DAttributes
//
// Purpose:
//   Default constructor for the View2DAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

View2DAttributes::View2DAttributes() :
    AttributeSubject(View2DAttributes::TypeMapFormatString)
{
    View2DAttributes::Init();
}

// ****************************************************************************
// Method: View2DAttributes::View2DAttributes
//
// Purpose:
//   Constructor for the derived classes of View2DAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

View2DAttributes::View2DAttributes(private_tmfs_t tmfs) :
    AttributeSubject(tmfs.tmfs)
{
    View2DAttributes::Init();
}

// ****************************************************************************
// Method: View2DAttributes::View2DAttributes
//
// Purpose:
//   Copy constructor for the View2DAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

View2DAttributes::View2DAttributes(const View2DAttributes &obj) :
    AttributeSubject(View2DAttributes::TypeMapFormatString)
{
    View2DAttributes::Copy(obj);
}

// ****************************************************************************
// Method: View2DAttributes::View2DAttributes
//
// Purpose:
//   Copy constructor for derived classes of the View2DAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

View2DAttributes::View2DAttributes(const View2DAttributes &obj, private_tmfs_t tmfs) :
    AttributeSubject(tmfs.tmfs)
{
    View2DAttributes::Copy(obj);
}

// ****************************************************************************
// Method: View2DAttributes::~View2DAttributes
//
// Purpose:
//   Destructor for the View2DAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

View2DAttributes::~View2DAttributes()
{
    // nothing here
}

// ****************************************************************************
// Method: View2DAttributes::operator =
//
// Purpose:
//   Assignment operator for the View2DAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

View2DAttributes&
View2DAttributes::operator = (const View2DAttributes &obj)
{
    if (this == &obj) return *this;

    View2DAttributes::Copy(obj);

    return *this;
}

// ****************************************************************************
// Method: View2DAttributes::operator ==
//
// Purpose:
//   Comparison operator == for the View2DAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
View2DAttributes::operator == (const View2DAttributes &obj) const
{
    // Compare the windowCoords arrays.
    bool windowCoords_equal = true;
    for(int i = 0; i < 4 && windowCoords_equal; ++i)
        windowCoords_equal = (windowCoords[i] == obj.windowCoords[i]);

    // Compare the viewportCoords arrays.
    bool viewportCoords_equal = true;
    for(int i = 0; i < 4 && viewportCoords_equal; ++i)
        viewportCoords_equal = (viewportCoords[i] == obj.viewportCoords[i]);

    // Create the return value
    return (windowCoords_equal &&
            viewportCoords_equal &&
            (fullFrameActivationMode == obj.fullFrameActivationMode) &&
            (fullFrameAutoThreshold == obj.fullFrameAutoThreshold) &&
            (xScale == obj.xScale) &&
            (yScale == obj.yScale) &&
            (windowValid == obj.windowValid));
}

// ****************************************************************************
// Method: View2DAttributes::operator !=
//
// Purpose:
//   Comparison operator != for the View2DAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
View2DAttributes::operator != (const View2DAttributes &obj) const
{
    return !(this->operator == (obj));
}

// ****************************************************************************
// Method: View2DAttributes::TypeName
//
// Purpose:
//   Type name method for the View2DAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

const std::string
View2DAttributes::TypeName() const
{
    return "View2DAttributes";
}

// ****************************************************************************
// Method: View2DAttributes::CopyAttributes
//
// Purpose:
//   CopyAttributes method for the View2DAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
View2DAttributes::CopyAttributes(const AttributeGroup *atts)
{
    if(TypeName() != atts->TypeName())
        return false;

    // Call assignment operator.
    const View2DAttributes *tmp = (const View2DAttributes *)atts;
    *this = *tmp;

    return true;
}

// ****************************************************************************
// Method: View2DAttributes::CreateCompatible
//
// Purpose:
//   CreateCompatible method for the View2DAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeSubject *
View2DAttributes::CreateCompatible(const std::string &tname) const
{
    AttributeSubject *retval = 0;
    if(TypeName() == tname)
        retval = new View2DAttributes(*this);
    // Other cases could go here too.

    return retval;
}

// ****************************************************************************
// Method: View2DAttributes::NewInstance
//
// Purpose:
//   NewInstance method for the View2DAttributes class.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeSubject *
View2DAttributes::NewInstance(bool copy) const
{
    AttributeSubject *retval = 0;
    if(copy)
        retval = new View2DAttributes(*this);
    else
        retval = new View2DAttributes;

    return retval;
}

// ****************************************************************************
// Method: View2DAttributes::SelectAll
//
// Purpose:
//   Selects all attributes.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
View2DAttributes::SelectAll()
{
    Select(ID_windowCoords,            (void *)windowCoords, 4);
    Select(ID_viewportCoords,          (void *)viewportCoords, 4);
    Select(ID_fullFrameActivationMode, (void *)&fullFrameActivationMode);
    Select(ID_fullFrameAutoThreshold,  (void *)&fullFrameAutoThreshold);
    Select(ID_xScale,                  (void *)&xScale);
    Select(ID_yScale,                  (void *)&yScale);
    Select(ID_windowValid,             (void *)&windowValid);
}

///////////////////////////////////////////////////////////////////////////////
// Persistence methods
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: View2DAttributes::CreateNode
//
// Purpose:
//   This method creates a DataNode representation of the object so it can be saved to a config file.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
View2DAttributes::CreateNode(DataNode *parentNode, bool completeSave, bool forceAdd)
{
    if(parentNode == 0)
        return false;

    View2DAttributes defaultObject;
    bool addToParent = false;
    // Create a node for View2DAttributes.
    DataNode *node = new DataNode("View2DAttributes");

    if(completeSave || !FieldsEqual(ID_windowCoords, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("windowCoords", windowCoords, 4));
    }

    if(completeSave || !FieldsEqual(ID_viewportCoords, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("viewportCoords", viewportCoords, 4));
    }

    if(completeSave || !FieldsEqual(ID_fullFrameActivationMode, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("fullFrameActivationMode", TriStateMode_ToString(fullFrameActivationMode)));
    }

    if(completeSave || !FieldsEqual(ID_fullFrameAutoThreshold, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("fullFrameAutoThreshold", fullFrameAutoThreshold));
    }

    if(completeSave || !FieldsEqual(ID_xScale, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("xScale", xScale));
    }

    if(completeSave || !FieldsEqual(ID_yScale, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("yScale", yScale));
    }

    if(completeSave || !FieldsEqual(ID_windowValid, &defaultObject))
    {
        addToParent = true;
        node->AddNode(new DataNode("windowValid", windowValid));
    }


    // Add the node to the parent node.
    if(addToParent || forceAdd)
        parentNode->AddNode(node);
    else
        delete node;

    return (addToParent || forceAdd);
}

// ****************************************************************************
// Method: View2DAttributes::SetFromNode
//
// Purpose:
//   This method sets attributes in this object from values in a DataNode representation of the object.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

void
View2DAttributes::SetFromNode(DataNode *parentNode)
{
    if(parentNode == 0)
        return;

    DataNode *searchNode = parentNode->GetNode("View2DAttributes");
    if(searchNode == 0)
        return;

    DataNode *node;
    if((node = searchNode->GetNode("windowCoords")) != 0)
        SetWindowCoords(node->AsDoubleArray());
    if((node = searchNode->GetNode("viewportCoords")) != 0)
        SetViewportCoords(node->AsDoubleArray());
    if((node = searchNode->GetNode("fullFrameActivationMode")) != 0)
    {
        // Allow enums to be int or string in the config file
        if(node->GetNodeType() == INT_NODE)
        {
            int ival = node->AsInt();
            if(ival >= 0 && ival < 3)
                SetFullFrameActivationMode(TriStateMode(ival));
        }
        else if(node->GetNodeType() == STRING_NODE)
        {
            TriStateMode value;
            if(TriStateMode_FromString(node->AsString(), value))
                SetFullFrameActivationMode(value);
        }
    }
    if((node = searchNode->GetNode("fullFrameAutoThreshold")) != 0)
        SetFullFrameAutoThreshold(node->AsDouble());
    if((node = searchNode->GetNode("xScale")) != 0)
        SetXScale(node->AsInt());
    if((node = searchNode->GetNode("yScale")) != 0)
        SetYScale(node->AsInt());
    if((node = searchNode->GetNode("windowValid")) != 0)
        SetWindowValid(node->AsBool());
}

///////////////////////////////////////////////////////////////////////////////
// Set property methods
///////////////////////////////////////////////////////////////////////////////

void
View2DAttributes::SetWindowCoords(const double *windowCoords_)
{
    windowCoords[0] = windowCoords_[0];
    windowCoords[1] = windowCoords_[1];
    windowCoords[2] = windowCoords_[2];
    windowCoords[3] = windowCoords_[3];
    Select(ID_windowCoords, (void *)windowCoords, 4);
}

void
View2DAttributes::SetViewportCoords(const double *viewportCoords_)
{
    viewportCoords[0] = viewportCoords_[0];
    viewportCoords[1] = viewportCoords_[1];
    viewportCoords[2] = viewportCoords_[2];
    viewportCoords[3] = viewportCoords_[3];
    Select(ID_viewportCoords, (void *)viewportCoords, 4);
}

void
View2DAttributes::SetFullFrameActivationMode(View2DAttributes::TriStateMode fullFrameActivationMode_)
{
    fullFrameActivationMode = fullFrameActivationMode_;
    Select(ID_fullFrameActivationMode, (void *)&fullFrameActivationMode);
}

void
View2DAttributes::SetFullFrameAutoThreshold(double fullFrameAutoThreshold_)
{
    fullFrameAutoThreshold = fullFrameAutoThreshold_;
    Select(ID_fullFrameAutoThreshold, (void *)&fullFrameAutoThreshold);
}

void
View2DAttributes::SetXScale(int xScale_)
{
    xScale = xScale_;
    Select(ID_xScale, (void *)&xScale);
}

void
View2DAttributes::SetYScale(int yScale_)
{
    yScale = yScale_;
    Select(ID_yScale, (void *)&yScale);
}

void
View2DAttributes::SetWindowValid(bool windowValid_)
{
    windowValid = windowValid_;
    Select(ID_windowValid, (void *)&windowValid);
}

///////////////////////////////////////////////////////////////////////////////
// Get property methods
///////////////////////////////////////////////////////////////////////////////

const double *
View2DAttributes::GetWindowCoords() const
{
    return windowCoords;
}

double *
View2DAttributes::GetWindowCoords()
{
    return windowCoords;
}

const double *
View2DAttributes::GetViewportCoords() const
{
    return viewportCoords;
}

double *
View2DAttributes::GetViewportCoords()
{
    return viewportCoords;
}

View2DAttributes::TriStateMode
View2DAttributes::GetFullFrameActivationMode() const
{
    return TriStateMode(fullFrameActivationMode);
}

double
View2DAttributes::GetFullFrameAutoThreshold() const
{
    return fullFrameAutoThreshold;
}

int
View2DAttributes::GetXScale() const
{
    return xScale;
}

int
View2DAttributes::GetYScale() const
{
    return yScale;
}

bool
View2DAttributes::GetWindowValid() const
{
    return windowValid;
}

///////////////////////////////////////////////////////////////////////////////
// Select property methods
///////////////////////////////////////////////////////////////////////////////

void
View2DAttributes::SelectWindowCoords()
{
    Select(ID_windowCoords, (void *)windowCoords, 4);
}

void
View2DAttributes::SelectViewportCoords()
{
    Select(ID_viewportCoords, (void *)viewportCoords, 4);
}

///////////////////////////////////////////////////////////////////////////////
// Keyframing methods
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: View2DAttributes::GetFieldName
//
// Purpose:
//   This method returns the name of a field given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

std::string
View2DAttributes::GetFieldName(int index) const
{
    switch (index)
    {
    case ID_windowCoords:            return "windowCoords";
    case ID_viewportCoords:          return "viewportCoords";
    case ID_fullFrameActivationMode: return "fullFrameActivationMode";
    case ID_fullFrameAutoThreshold:  return "fullFrameAutoThreshold";
    case ID_xScale:                  return "xScale";
    case ID_yScale:                  return "yScale";
    case ID_windowValid:             return "windowValid";
    default:  return "invalid index";
    }
}

// ****************************************************************************
// Method: View2DAttributes::GetFieldType
//
// Purpose:
//   This method returns the type of a field given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

AttributeGroup::FieldType
View2DAttributes::GetFieldType(int index) const
{
    switch (index)
    {
    case ID_windowCoords:            return FieldType_doubleArray;
    case ID_viewportCoords:          return FieldType_doubleArray;
    case ID_fullFrameActivationMode: return FieldType_enum;
    case ID_fullFrameAutoThreshold:  return FieldType_double;
    case ID_xScale:                  return FieldType_scalemode;
    case ID_yScale:                  return FieldType_scalemode;
    case ID_windowValid:             return FieldType_bool;
    default:  return FieldType_unknown;
    }
}

// ****************************************************************************
// Method: View2DAttributes::GetFieldTypeName
//
// Purpose:
//   This method returns the name of a field type given its index.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

std::string
View2DAttributes::GetFieldTypeName(int index) const
{
    switch (index)
    {
    case ID_windowCoords:            return "doubleArray";
    case ID_viewportCoords:          return "doubleArray";
    case ID_fullFrameActivationMode: return "enum";
    case ID_fullFrameAutoThreshold:  return "double";
    case ID_xScale:                  return "scalemode";
    case ID_yScale:                  return "scalemode";
    case ID_windowValid:             return "bool";
    default:  return "invalid index";
    }
}

// ****************************************************************************
// Method: View2DAttributes::FieldsEqual
//
// Purpose:
//   This method compares two fields and return true if they are equal.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//
// ****************************************************************************

bool
View2DAttributes::FieldsEqual(int index_, const AttributeGroup *rhs) const
{
    const View2DAttributes &obj = *((const View2DAttributes*)rhs);
    bool retval = false;
    switch (index_)
    {
    case ID_windowCoords:
        {  // new scope
        // Compare the windowCoords arrays.
        bool windowCoords_equal = true;
        for(int i = 0; i < 4 && windowCoords_equal; ++i)
            windowCoords_equal = (windowCoords[i] == obj.windowCoords[i]);

        retval = windowCoords_equal;
        }
        break;
    case ID_viewportCoords:
        {  // new scope
        // Compare the viewportCoords arrays.
        bool viewportCoords_equal = true;
        for(int i = 0; i < 4 && viewportCoords_equal; ++i)
            viewportCoords_equal = (viewportCoords[i] == obj.viewportCoords[i]);

        retval = viewportCoords_equal;
        }
        break;
    case ID_fullFrameActivationMode:
        {  // new scope
        retval = (fullFrameActivationMode == obj.fullFrameActivationMode);
        }
        break;
    case ID_fullFrameAutoThreshold:
        {  // new scope
        retval = (fullFrameAutoThreshold == obj.fullFrameAutoThreshold);
        }
        break;
    case ID_xScale:
        {  // new scope
        retval = (xScale == obj.xScale);
        }
        break;
    case ID_yScale:
        {  // new scope
        retval = (yScale == obj.yScale);
        }
        break;
    case ID_windowValid:
        {  // new scope
        retval = (windowValid == obj.windowValid);
        }
        break;
    default: retval = false;
    }

    return retval;
}

///////////////////////////////////////////////////////////////////////////////
// User-defined methods.
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: View2DAttributes::GetUseFullFrame
//
// Purpose: Together with the full frame activation mode and, optionally,
// limits, this method determines if full frame mode should be used.
//
// Programmer: Mark C. Miller
// Creation:   July 20, 2005
//
//  Modifications:
//    Shelly Prevost, Fri Mar 23 15:03:31 PDT 2007
//    Added code to check for DBL_MAX to avoid doing math that
//    exceeded maximums and cause a crash.
// ****************************************************************************

bool
View2DAttributes::GetUseFullFrame(const double *limits) const
{
    if (fullFrameActivationMode == Off)
        return false;

    if (fullFrameActivationMode == On)
        return true;

    if (limits == 0)
        return false;

    // if the limits are not initialized then doing math
    // with them will cause an error so check them first.
    if ( (limits[1] == -DBL_MAX  && limits[0] == DBL_MAX) ||
         (limits[3] == -DBL_MAX  && limits[2] == DBL_MAX)   )
    {
        return false;
    }

    double dlimit1 = limits[1] - limits[0];
    double dlimit2 = limits[3] - limits[2];
    double aspect;

    if (dlimit1 > dlimit2)
    {
        if (dlimit2 != 0)
            aspect = dlimit1 / dlimit2;
        else
            aspect = fullFrameAutoThreshold;
    }
    else
    {
        if (dlimit1 != 0)
            aspect = dlimit2 / dlimit1;
        else
            aspect = fullFrameAutoThreshold;
    }

    if (aspect >= fullFrameAutoThreshold)
        return true;
    else
        return false;
}

// ****************************************************************************
// Method: View2DAttributes::SetUseFullFrame
//
// Purpose: Sets full frame activation mode to On/Off if it is not currently
// in Auto mode. Otherwise, it does not change the mode.
//
// Programmer: Mark C. Miller
// Creation:   July 20, 2005
//
// ****************************************************************************

void
View2DAttributes::SetUseFullFrame(bool ff)
{
    if (fullFrameActivationMode == Auto)
        return;

    if (ff)
        fullFrameActivationMode = On;
    else
        fullFrameActivationMode = Off;
}

#include <math.h>
// ****************************************************************************
// Method: View2DAttributes::ResetView
//
// Purpose:
//   Resets the view to something that can accommodate the bbox.
//
// Arguments:
//   bbox : The 2D extents that we're trying to look at.
//
// Programmer: Brad Whitlock
// Creation:   Tue Mar  3 16:21:14 PST 2009
//
// Modifications:
//
// ****************************************************************************
void
View2DAttributes::ResetView(const double *bbox)
{
    const double vpc[] = {0.2, 0.95, 0.15, 0.95};
    View2DAttributes view2D;
    view2D.SetWindowCoords(bbox);
    view2D.SetViewportCoords(vpc);

    // Copy the object into this.
    *this = view2D;
}

