/*****************************************************************************
*
* Copyright (c) 2000 - 2017, Lawrence Livermore National Security, LLC
* Produced at the Lawrence Livermore National Laboratory
* LLNL-CODE-442911
* All rights reserved.
*
* This file is  part of VisIt. For  details, see https://visit.llnl.gov/.  The
* full copyright notice is contained in the file COPYRIGHT located at the root
* of the VisIt distribution or at http://www.llnl.gov/visit/copyright.html.
*
* Redistribution  and  use  in  source  and  binary  forms,  with  or  without
* modification, are permitted provided that the following conditions are met:
*
*  - Redistributions of  source code must  retain the above  copyright notice,
*    this list of conditions and the disclaimer below.
*  - Redistributions in binary form must reproduce the above copyright notice,
*    this  list of  conditions  and  the  disclaimer (as noted below)  in  the
*    documentation and/or other materials provided with the distribution.
*  - Neither the name of  the LLNS/LLNL nor the names of  its contributors may
*    be used to endorse or promote products derived from this software without
*    specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR  IMPLIED WARRANTIES, INCLUDING,  BUT NOT  LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND  FITNESS FOR A PARTICULAR  PURPOSE
* ARE  DISCLAIMED. IN  NO EVENT  SHALL LAWRENCE  LIVERMORE NATIONAL  SECURITY,
* LLC, THE  U.S.  DEPARTMENT OF  ENERGY  OR  CONTRIBUTORS BE  LIABLE  FOR  ANY
* DIRECT,  INDIRECT,   INCIDENTAL,   SPECIAL,   EXEMPLARY,  OR   CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT  LIMITED TO, PROCUREMENT OF  SUBSTITUTE GOODS OR
* SERVICES; LOSS OF  USE, DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER
* CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY,  WHETHER  IN  CONTRACT,  STRICT
* LIABILITY, OR TORT  (INCLUDING NEGLIGENCE OR OTHERWISE)  ARISING IN ANY  WAY
* OUT OF THE  USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*
*****************************************************************************/

#include <ThresholdOpAttributes.h>
#include <DataNode.h>

//
// Enum conversion methods for ThresholdOpAttributes::OutputMeshType
//

static const char *OutputMeshType_strings[] = {
"InputZones", "PointMesh"};

std::string
ThresholdOpAttributes::OutputMeshType_ToString(ThresholdOpAttributes::OutputMeshType t)
{
    int index = int(t);
    if(index < 0 || index >= 2) index = 0;
    return OutputMeshType_strings[index];
}

std::string
ThresholdOpAttributes::OutputMeshType_ToString(int t)
{
    int index = (t < 0 || t >= 2) ? 0 : t;
    return OutputMeshType_strings[index];
}

bool
ThresholdOpAttributes::OutputMeshType_FromString(const std::string &s, ThresholdOpAttributes::OutputMeshType &val)
{
    val = ThresholdOpAttributes::InputZones;
    for(int i = 0; i < 2; ++i)
    {
        if(s == OutputMeshType_strings[i])
        {
            val = (OutputMeshType)i;
            return true;
        }
    }
    return false;
}

//
// Enum conversion methods for ThresholdOpAttributes::ZonePortion
//

static const char *ZonePortion_strings[] = {
"EntireZone", "PartOfZone"};

std::string
ThresholdOpAttributes::ZonePortion_ToString(ThresholdOpAttributes::ZonePortion t)
{
    int index = int(t);
    if(index < 0 || index >= 2) index = 0;
    return ZonePortion_strings[index];
}

std::string
ThresholdOpAttributes::ZonePortion_ToString(int t)
{
    int index = (t < 0 || t >= 2) ? 0 : t;
    return ZonePortion_strings[index];
}

bool
ThresholdOpAttributes::ZonePortion_FromString(const std::string &s, ThresholdOpAttributes::ZonePortion &val)
{
    val = ThresholdOpAttributes::EntireZone;
    for(int i = 0; i < 2; ++i)
    {
        if(s == ZonePortion_strings[i])
        {
            val = (ZonePortion)i;
            return true;
        }
    }
    return false;
}

//
// Enum conversion methods for ThresholdOpAttributes::BoundsInputType
//

static const char *BoundsInputType_strings[] = {
"Default", "Custom"};

std::string
ThresholdOpAttributes::BoundsInputType_ToString(ThresholdOpAttributes::BoundsInputType t)
{
    int index = int(t);
    if(index < 0 || index >= 2) index = 0;
    return BoundsInputType_strings[index];
}

std::string
ThresholdOpAttributes::BoundsInputType_ToString(int t)
{
    int index = (t < 0 || t >= 2) ? 0 : t;
    return BoundsInputType_strings[index];
}

bool
ThresholdOpAttributes::BoundsInputType_FromString(const std::string &s, ThresholdOpAttributes::BoundsInputType &val)
{
    val = ThresholdOpAttributes::Default;
    for(int i = 0; i < 2; ++i)
    {
        if(s == BoundsInputType_strings[i])
        {
            val = (BoundsInputType)i;
            return true;
        }
    }
    return false;
}

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

void ThresholdOpAttributes::Init()
{
    outputMeshType = 0;
    boundsInputType = 0;
    listedVarNames.push_back("default");
    defaultVarName = "default";
    defaultVarIsScalar = false;

    ThresholdOpAttributes::SelectAll();
}

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

void ThresholdOpAttributes::Copy(const ThresholdOpAttributes &obj)
{
    outputMeshType = obj.outputMeshType;
    boundsInputType = obj.boundsInputType;
    listedVarNames = obj.listedVarNames;
    zonePortions = obj.zonePortions;
    lowerBounds = obj.lowerBounds;
    upperBounds = obj.upperBounds;
    defaultVarName = obj.defaultVarName;
    defaultVarIsScalar = obj.defaultVarIsScalar;
    boundsRange = obj.boundsRange;

    ThresholdOpAttributes::SelectAll();
}

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


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

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

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

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

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

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

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

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

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

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

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

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

    ThresholdOpAttributes::Copy(obj);

    return *this;
}

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

bool
ThresholdOpAttributes::operator == (const ThresholdOpAttributes &obj) const
{
    // Create the return value
    return ((outputMeshType == obj.outputMeshType) &&
            (boundsInputType == obj.boundsInputType) &&
            (listedVarNames == obj.listedVarNames) &&
            (zonePortions == obj.zonePortions) &&
            (lowerBounds == obj.lowerBounds) &&
            (upperBounds == obj.upperBounds) &&
            (defaultVarName == obj.defaultVarName) &&
            (defaultVarIsScalar == obj.defaultVarIsScalar) &&
            (boundsRange == obj.boundsRange));
}

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

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

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

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

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

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

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

    return true;
}

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

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

    return retval;
}

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

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

    return retval;
}

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

void
ThresholdOpAttributes::SelectAll()
{
    Select(ID_outputMeshType,     (void *)&outputMeshType);
    Select(ID_boundsInputType,    (void *)&boundsInputType);
    Select(ID_listedVarNames,     (void *)&listedVarNames);
    Select(ID_zonePortions,       (void *)&zonePortions);
    Select(ID_lowerBounds,        (void *)&lowerBounds);
    Select(ID_upperBounds,        (void *)&upperBounds);
    Select(ID_defaultVarName,     (void *)&defaultVarName);
    Select(ID_defaultVarIsScalar, (void *)&defaultVarIsScalar);
    Select(ID_boundsRange,        (void *)&boundsRange);
}

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

// ****************************************************************************
// Method: ThresholdOpAttributes::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
ThresholdOpAttributes::CreateNode(DataNode *parentNode, bool completeSave, bool forceAdd)
{
    if(parentNode == 0)
        return false;

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

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

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

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

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

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

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

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

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

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


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

    return (addToParent || forceAdd);
}

// ****************************************************************************
// Method: ThresholdOpAttributes::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
ThresholdOpAttributes::SetFromNode(DataNode *parentNode)
{
    if(parentNode == 0)
        return;

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

    DataNode *node;
    if((node = searchNode->GetNode("outputMeshType")) != 0)
        SetOutputMeshType(node->AsInt());
    if((node = searchNode->GetNode("boundsInputType")) != 0)
        SetBoundsInputType(node->AsInt());
    if((node = searchNode->GetNode("listedVarNames")) != 0)
        SetListedVarNames(node->AsStringVector());
    if((node = searchNode->GetNode("zonePortions")) != 0)
        SetZonePortions(node->AsIntVector());
    if((node = searchNode->GetNode("lowerBounds")) != 0)
        SetLowerBounds(node->AsDoubleVector());
    if((node = searchNode->GetNode("upperBounds")) != 0)
        SetUpperBounds(node->AsDoubleVector());
    if((node = searchNode->GetNode("defaultVarName")) != 0)
        SetDefaultVarName(node->AsString());
    if((node = searchNode->GetNode("defaultVarIsScalar")) != 0)
        SetDefaultVarIsScalar(node->AsBool());
    if((node = searchNode->GetNode("boundsRange")) != 0)
        SetBoundsRange(node->AsStringVector());
}

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

void
ThresholdOpAttributes::SetOutputMeshType(int outputMeshType_)
{
    outputMeshType = outputMeshType_;
    Select(ID_outputMeshType, (void *)&outputMeshType);
}

void
ThresholdOpAttributes::SetBoundsInputType(int boundsInputType_)
{
    boundsInputType = boundsInputType_;
    Select(ID_boundsInputType, (void *)&boundsInputType);
}

void
ThresholdOpAttributes::SetListedVarNames(const stringVector &listedVarNames_)
{
    listedVarNames = listedVarNames_;
    Select(ID_listedVarNames, (void *)&listedVarNames);
}

void
ThresholdOpAttributes::SetZonePortions(const intVector &zonePortions_)
{
    zonePortions = zonePortions_;
    Select(ID_zonePortions, (void *)&zonePortions);
}

void
ThresholdOpAttributes::SetLowerBounds(const doubleVector &lowerBounds_)
{
    lowerBounds = lowerBounds_;
    Select(ID_lowerBounds, (void *)&lowerBounds);
}

void
ThresholdOpAttributes::SetUpperBounds(const doubleVector &upperBounds_)
{
    upperBounds = upperBounds_;
    Select(ID_upperBounds, (void *)&upperBounds);
}

void
ThresholdOpAttributes::SetDefaultVarName(const std::string &defaultVarName_)
{
    defaultVarName = defaultVarName_;
    Select(ID_defaultVarName, (void *)&defaultVarName);
}

void
ThresholdOpAttributes::SetDefaultVarIsScalar(bool defaultVarIsScalar_)
{
    defaultVarIsScalar = defaultVarIsScalar_;
    Select(ID_defaultVarIsScalar, (void *)&defaultVarIsScalar);
}

void
ThresholdOpAttributes::SetBoundsRange(const stringVector &boundsRange_)
{
    boundsRange = boundsRange_;
    Select(ID_boundsRange, (void *)&boundsRange);
}

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

int
ThresholdOpAttributes::GetOutputMeshType() const
{
    return outputMeshType;
}

int
ThresholdOpAttributes::GetBoundsInputType() const
{
    return boundsInputType;
}

const stringVector &
ThresholdOpAttributes::GetListedVarNames() const
{
    return listedVarNames;
}

stringVector &
ThresholdOpAttributes::GetListedVarNames()
{
    return listedVarNames;
}

const intVector &
ThresholdOpAttributes::GetZonePortions() const
{
    return zonePortions;
}

intVector &
ThresholdOpAttributes::GetZonePortions()
{
    return zonePortions;
}

const doubleVector &
ThresholdOpAttributes::GetLowerBounds() const
{
    return lowerBounds;
}

doubleVector &
ThresholdOpAttributes::GetLowerBounds()
{
    return lowerBounds;
}

const doubleVector &
ThresholdOpAttributes::GetUpperBounds() const
{
    return upperBounds;
}

doubleVector &
ThresholdOpAttributes::GetUpperBounds()
{
    return upperBounds;
}

const std::string &
ThresholdOpAttributes::GetDefaultVarName() const
{
    return defaultVarName;
}

std::string &
ThresholdOpAttributes::GetDefaultVarName()
{
    return defaultVarName;
}

bool
ThresholdOpAttributes::GetDefaultVarIsScalar() const
{
    return defaultVarIsScalar;
}

const stringVector &
ThresholdOpAttributes::GetBoundsRange() const
{
    return boundsRange;
}

stringVector &
ThresholdOpAttributes::GetBoundsRange()
{
    return boundsRange;
}

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

void
ThresholdOpAttributes::SelectListedVarNames()
{
    Select(ID_listedVarNames, (void *)&listedVarNames);
}

void
ThresholdOpAttributes::SelectZonePortions()
{
    Select(ID_zonePortions, (void *)&zonePortions);
}

void
ThresholdOpAttributes::SelectLowerBounds()
{
    Select(ID_lowerBounds, (void *)&lowerBounds);
}

void
ThresholdOpAttributes::SelectUpperBounds()
{
    Select(ID_upperBounds, (void *)&upperBounds);
}

void
ThresholdOpAttributes::SelectDefaultVarName()
{
    Select(ID_defaultVarName, (void *)&defaultVarName);
}

void
ThresholdOpAttributes::SelectBoundsRange()
{
    Select(ID_boundsRange, (void *)&boundsRange);
}

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

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

std::string
ThresholdOpAttributes::GetFieldName(int index) const
{
    switch (index)
    {
    case ID_outputMeshType:     return "outputMeshType";
    case ID_boundsInputType:    return "boundsInputType";
    case ID_listedVarNames:     return "listedVarNames";
    case ID_zonePortions:       return "zonePortions";
    case ID_lowerBounds:        return "lowerBounds";
    case ID_upperBounds:        return "upperBounds";
    case ID_defaultVarName:     return "defaultVarName";
    case ID_defaultVarIsScalar: return "defaultVarIsScalar";
    case ID_boundsRange:        return "boundsRange";
    default:  return "invalid index";
    }
}

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

AttributeGroup::FieldType
ThresholdOpAttributes::GetFieldType(int index) const
{
    switch (index)
    {
    case ID_outputMeshType:     return FieldType_int;
    case ID_boundsInputType:    return FieldType_int;
    case ID_listedVarNames:     return FieldType_stringVector;
    case ID_zonePortions:       return FieldType_intVector;
    case ID_lowerBounds:        return FieldType_doubleVector;
    case ID_upperBounds:        return FieldType_doubleVector;
    case ID_defaultVarName:     return FieldType_string;
    case ID_defaultVarIsScalar: return FieldType_bool;
    case ID_boundsRange:        return FieldType_stringVector;
    default:  return FieldType_unknown;
    }
}

// ****************************************************************************
// Method: ThresholdOpAttributes::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
ThresholdOpAttributes::GetFieldTypeName(int index) const
{
    switch (index)
    {
    case ID_outputMeshType:     return "int";
    case ID_boundsInputType:    return "int";
    case ID_listedVarNames:     return "stringVector";
    case ID_zonePortions:       return "intVector";
    case ID_lowerBounds:        return "doubleVector";
    case ID_upperBounds:        return "doubleVector";
    case ID_defaultVarName:     return "string";
    case ID_defaultVarIsScalar: return "bool";
    case ID_boundsRange:        return "stringVector";
    default:  return "invalid index";
    }
}

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

bool
ThresholdOpAttributes::FieldsEqual(int index_, const AttributeGroup *rhs) const
{
    const ThresholdOpAttributes &obj = *((const ThresholdOpAttributes*)rhs);
    bool retval = false;
    switch (index_)
    {
    case ID_outputMeshType:
        {  // new scope
        retval = (outputMeshType == obj.outputMeshType);
        }
        break;
    case ID_boundsInputType:
        {  // new scope
        retval = (boundsInputType == obj.boundsInputType);
        }
        break;
    case ID_listedVarNames:
        {  // new scope
        retval = (listedVarNames == obj.listedVarNames);
        }
        break;
    case ID_zonePortions:
        {  // new scope
        retval = (zonePortions == obj.zonePortions);
        }
        break;
    case ID_lowerBounds:
        {  // new scope
        retval = (lowerBounds == obj.lowerBounds);
        }
        break;
    case ID_upperBounds:
        {  // new scope
        retval = (upperBounds == obj.upperBounds);
        }
        break;
    case ID_defaultVarName:
        {  // new scope
        retval = (defaultVarName == obj.defaultVarName);
        }
        break;
    case ID_defaultVarIsScalar:
        {  // new scope
        retval = (defaultVarIsScalar == obj.defaultVarIsScalar);
        }
        break;
    case ID_boundsRange:
        {  // new scope
        retval = (boundsRange == obj.boundsRange);
        }
        break;
    default: retval = false;
    }

    return retval;
}

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

// ****************************************************************************
// Method: ThresholdOpAttributes::SupplyMissingDefaultsIfAppropriate
//
// Purpose: If attributes are set up for a single threshold variable, supply
//          default values for any attribute values that are missing.
//
// Programmer: Mark Blair
// Creation:   Thu Sep 28 12:07:05 PDT 2006
//
// Modifications:
//
//    Kevin Griffin, Wed Feb 15 11:50:13 PDT 2017
//    Added boundsRange field.
//   
// ****************************************************************************

void
ThresholdOpAttributes::SupplyMissingDefaultsIfAppropriate()
{
    size_t totalEntryCount = 0;
    
    if (listedVarNames.size() > 1) return;
    totalEntryCount += listedVarNames.size();
        
    if (zonePortions.size() > 1) return;
    totalEntryCount += zonePortions.size();
        
    if (lowerBounds.size() > 1) return;
    totalEntryCount += lowerBounds.size();
        
    if (upperBounds.size() > 1) return;
    totalEntryCount += upperBounds.size();
    
    if (boundsRange.size() > 1) return;
    totalEntryCount += boundsRange.size();

    if ((totalEntryCount & 3) == 0) return;
    
    stringVector singleVarName;
    intVector    singleZonePortion;
    doubleVector singleLowerBound;
    doubleVector singleUpperBound;
    stringVector singleBoundsRange;
    
    if (listedVarNames.size() == 0)
    {
        singleVarName.push_back(std::string("default"));
        SetListedVarNames(singleVarName);
    }
        
    if (zonePortions.size() == 0)
    {
        singleZonePortion.push_back((int)PartOfZone);
        SetZonePortions(singleZonePortion);
    }
        
    if (lowerBounds.size() == 0)
    {
        singleLowerBound.push_back(-1e+37);
        SetLowerBounds(singleLowerBound);
    }
        
    if (upperBounds.size() == 0)
    {
        singleUpperBound.push_back(+1e+37);
        SetUpperBounds(singleUpperBound);
    }

    if(boundsRange.size() == 0)
    {
        singleBoundsRange.push_back("min:max");
        SetBoundsRange(singleBoundsRange);
    }
}

// ****************************************************************************
// Method: ThresholdOpAttributes::AttributesAreConsistent
//
// Purpose: Returns true only if (1) all vector attributes are the same length
//          and (2) the index of the currently displayable variable information
//          in the Threshold GUI window is in range.
//
//
// Programmer: Mark Blair
// Creation:   Tue Mar  7 13:25:00 PST 2006
//
// Modifications:
//   
//   Mark Blair, Tue Aug  8 17:47:00 PDT 2006
//   Now accommodates an empty list of threshold variables.
//
//   Mark Blair, Tue Apr 17 16:24:42 PDT 2007
//   Rewritten to support new Threshold GUI; no more shown variable.
//
//   Kevin Griffin, Wed Feb 15 11:50:13 PDT 2017
//   Added boundsRange check.
//
// ****************************************************************************

bool
ThresholdOpAttributes::AttributesAreConsistent() const
{
    size_t varListSize = listedVarNames.size();
    
    if ((zonePortions.size() != varListSize) ||
        (lowerBounds.size()  != varListSize) ||
        (upperBounds.size()  != varListSize) ||
        (boundsRange.size() != varListSize))
    {
        return false;
    }
    
    return true;
}

// ****************************************************************************
// Method: ThresholdOpAttributes::ForceAttributeConsistency
//
// Purpose: Forces Threshold attributes to be consistent.  Attributes can be
//          inconsistent, for instance, if the user has specified an invalid
//          combination of them in the CLI.  If current attributes are in fact
//          inconsistent, this is recorded in the debug log.
//
// Programmer: Mark Blair
// Creation:   Tue Mar 13 19:51:29 PDT 2007
//
// Modifications:
//
//   Kevin Griffin, Wed Feb 15 11:50:13 PDT 2017
//   Added boundsRange
//   
// ****************************************************************************
#include <DebugStream.h>
void
ThresholdOpAttributes::ForceAttributeConsistency()
{
    size_t varListSize = listedVarNames.size();
    size_t varNum;
    double boundValue;
    bool consistent = ((zonePortions.size() == varListSize) &&
                       ( lowerBounds.size() == varListSize) &&
                       ( upperBounds.size() == varListSize) &&
                       ( boundsRange.size() == varListSize));
                       
    if (!consistent)
    {
        if (zonePortions.size() > varListSize) zonePortions.resize(varListSize);
        if ( lowerBounds.size() > varListSize)  lowerBounds.resize(varListSize);
        if ( upperBounds.size() > varListSize)  upperBounds.resize(varListSize);
        if ( boundsRange.size() > varListSize)  boundsRange.resize(varListSize);

        for (varNum = 0; varNum < varListSize; varNum++ )
        {
            if (zonePortions.size() < varListSize)
                zonePortions.push_back((int)ThresholdOpAttributes::PartOfZone);
            if (lowerBounds.size() < varListSize)
                lowerBounds.push_back(-1e+37);
            if (upperBounds.size() < varListSize)
                upperBounds.push_back(+1e+37);
            if (boundsRange.size() < varListSize)
                boundsRange.push_back("min:max");
        }
    }

    for (varNum = 0; varNum < varListSize; varNum++ )
    {
        if (lowerBounds[varNum] > upperBounds[varNum])
        {
            consistent = false;
                
            boundValue          = lowerBounds[varNum];
            lowerBounds[varNum] = upperBounds[varNum];
            upperBounds[varNum] = boundValue;
        }
    }
    
    if (!consistent && (varListSize > 0))
    {
        if (defaultVarName == std::string("default"))
            defaultVarName = listedVarNames[0];
    }

    if (!consistent)
    {
        debug3 << "Threshold operator attributes are inconsistent; "
               << "corrections will be applied." << endl;
        SelectAll();
    }
}

// ****************************************************************************
// Method: ThresholdOpAttributes::SwitchDefaultVariableNameToTrueName
//
// Purpose: Replaces the anonymous "default" variable name with its true name
//          if the default variable is scalar.
//
// Programmer: Mark Blair
// Creation:   Tue Mar  7 13:25:00 PST 2006
//
// Modifications:
//   
//   Mark Blair, Tue Oct  3 13:19:11 PDT 2006
//   Deletes default variable from threshold variable list if not scalar.
//
//   Mark Blair, Tue Apr 17 16:24:42 PDT 2007
//   Rewritten to support new Threshold GUI; no more "shown variable".
//
//   Mark Blair, Tue Sep 18 17:06:28 PDT 2007
//   No longer deletes variable from threshold variable list if not scalar.
//   Also changed method name to reflect this.
//
// ****************************************************************************

void
ThresholdOpAttributes::SwitchDefaultVariableNameToTrueName()
{
    size_t varPosition;
    bool changedTheList;
    std::string listedVarName;

    do
    {
        for (varPosition = 0; varPosition < listedVarNames.size(); varPosition++)
        {
            listedVarName = listedVarNames[varPosition];

            if (listedVarName == std::string("default")) break;
            if (listedVarName == defaultVarName) break;
        }
        
        changedTheList = false;
    
        if (varPosition < listedVarNames.size())
        {
            if (listedVarName == std::string("default"))
            {
                listedVarNames[varPosition] = defaultVarName;
                Select(1, (void *)&listedVarNames);

                changedTheList = true;
            }
        }
    }
    while (changedTheList);
}

