/*****************************************************************************
*
* Copyright (c) 2000 - 2018, 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 <avtMaterialMetaData.h>
#include <DataNode.h>

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

void avtMaterialMetaData::Init()
{
    numMaterials = 0;

    avtMaterialMetaData::SelectAll();
}

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

void avtMaterialMetaData::Copy(const avtMaterialMetaData &obj)
{
    numMaterials = obj.numMaterials;
    materialNames = obj.materialNames;
    colorNames = obj.colorNames;

    avtMaterialMetaData::SelectAll();
}

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


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

avtMaterialMetaData::avtMaterialMetaData() : 
    avtBaseVarMetaData(avtMaterialMetaData::TmfsStruct)
{
    avtMaterialMetaData::Init();
}

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

avtMaterialMetaData::avtMaterialMetaData(private_tmfs_t tmfs) : 
    avtBaseVarMetaData(tmfs)
{
    avtMaterialMetaData::Init();
}

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

avtMaterialMetaData::avtMaterialMetaData(const avtMaterialMetaData &obj) : 
    avtBaseVarMetaData(obj,avtMaterialMetaData::TmfsStruct)
{
    avtMaterialMetaData::Copy(obj);
}

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

avtMaterialMetaData::avtMaterialMetaData(const avtMaterialMetaData &obj, private_tmfs_t tmfs) : 
    avtBaseVarMetaData(obj,tmfs)
{
    avtMaterialMetaData::Copy(obj);
}

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

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

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

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

    // call the base class' assignment operator first
    avtBaseVarMetaData::operator=(obj);

    avtMaterialMetaData::Copy(obj);

    return *this;
}

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

bool
avtMaterialMetaData::operator == (const avtMaterialMetaData &obj) const
{
    // Create the return value
    return ((numMaterials == obj.numMaterials) &&
            (materialNames == obj.materialNames) &&
            (colorNames == obj.colorNames) &&
            avtBaseVarMetaData::operator==(obj));
}

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

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

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

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

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

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

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

    return true;
}

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

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

    return retval;
}

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

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

    return retval;
}

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

void
avtMaterialMetaData::SelectAll()
{
    // call the base class' SelectAll() first
    avtBaseVarMetaData::SelectAll();
    Select(ID_numMaterials,  (void *)&numMaterials);
    Select(ID_materialNames, (void *)&materialNames);
    Select(ID_colorNames,    (void *)&colorNames);
}

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

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

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

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

std::string
avtMaterialMetaData::GetFieldName(int index) const
{
    switch (index)
    {
    case ID_numMaterials:  return "numMaterials";
    case ID_materialNames: return "materialNames";
    case ID_colorNames:    return "colorNames";
    default:  return avtBaseVarMetaData::GetFieldName(index);
    }
}

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

AttributeGroup::FieldType
avtMaterialMetaData::GetFieldType(int index) const
{
    switch (index)
    {
    case ID_numMaterials:  return FieldType_int;
    case ID_materialNames: return FieldType_stringVector;
    case ID_colorNames:    return FieldType_stringVector;
    default:  return avtBaseVarMetaData::GetFieldType(index);
    }
}

// ****************************************************************************
// Method: avtMaterialMetaData::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
avtMaterialMetaData::GetFieldTypeName(int index) const
{
    switch (index)
    {
    case ID_numMaterials:  return "int";
    case ID_materialNames: return "stringVector";
    case ID_colorNames:    return "stringVector";
    default:  return avtBaseVarMetaData::GetFieldTypeName(index);
    }
}

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

bool
avtMaterialMetaData::FieldsEqual(int index_, const AttributeGroup *rhs) const
{
    const avtMaterialMetaData &obj = *((const avtMaterialMetaData*)rhs);
    bool retval = false;
    switch (index_)
    {
    case ID_numMaterials:
        {  // new scope
        retval = (numMaterials == obj.numMaterials);
        }
        break;
    case ID_materialNames:
        {  // new scope
        retval = (materialNames == obj.materialNames);
        }
        break;
    case ID_colorNames:
        {  // new scope
        retval = (colorNames == obj.colorNames);
        }
        break;
    default: retval = avtBaseVarMetaData::FieldsEqual(index_, rhs);
    }

    return retval;
}

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

// ****************************************************************************
//  Method: avtMaterialMetaData constructor
//
//  Arguments:
//      n            The name of the material.
//      mesh         The name of the mesh the material is defined on.
//      nm           The number of materials.
//      names        The name of each material.
//
//  Programmer: Hank Childs
//  Creation:   August 28, 2000
//
//  Modifications:
//
//    Hank Childs, Mon Dec  9 17:04:39 PST 2002
//    Initialized validVariable.
//
//    Hank Childs, Mon Feb 14 14:16:49 PST 2005
//    Added original name.
//
//    Mark C. Miller, Thu Jul 13 22:41:56 PDT 2006
//    Added colorNames stringVector
//
// ****************************************************************************

avtMaterialMetaData::avtMaterialMetaData(const std::string &n, const std::string &mesh,
    int nm, const stringVector &names) :
    avtBaseVarMetaData(avtMaterialMetaData::TmfsStruct, n, mesh)
{
    avtMaterialMetaData::Init();
    numMaterials = nm;
    materialNames = names;
}

// ****************************************************************************
//  Method: avtMaterialMetaData constructor
//
//  Purpose: constructor that includes material colors
//
//  Programmer: Mark C. Miller 
//  Creation:   July 12, 2006
//
// ****************************************************************************

avtMaterialMetaData::avtMaterialMetaData(const std::string &n, 
    const std::string &mesh, int nm, const stringVector &names,
    const stringVector &colors)
    : avtBaseVarMetaData(avtMaterialMetaData::TmfsStruct, n, mesh)
{
    avtMaterialMetaData::Init();
    numMaterials = nm;
    materialNames = names;
    colorNames = colors;
}

// ****************************************************************************
//  Method: avtMaterialMetaData constructor
//
//  Purpose: constructor that uses only material count 
//
//  Programmer: Mark C. Miller 
//  Creation:   Wed May 13 14:05:26 PDT 2009
// ****************************************************************************

avtMaterialMetaData::avtMaterialMetaData(const std::string &n, 
    const std::string &mesh, int nm)
    : avtBaseVarMetaData(avtMaterialMetaData::TmfsStruct, n, mesh)
{
    avtMaterialMetaData::Init();
    numMaterials = nm;
    for (int i = 0; i < numMaterials; i++)
    {
        char tmpn[32];
        sprintf(tmpn, "mat_%d", i);
        materialNames.push_back(tmpn);
    }
}

// ****************************************************************************
//  Method: avtMaterialMetaData::Print
//
//  Purpose:
//      Print statement for debugging.
//
//  Arguments:
//      out      The stream to output to.
//      indent   The number of tabs to indent each line with.
//
//  Programmer:  Hank Childs
//  Creation:    August 28, 2000
//
//  Modifications:
//    Brad Whitlock, Tue Aug 20 15:18:26 PST 2002
//    Changed to remove a trailing comma.
//
//    Hank Childs, Mon Dec  9 17:04:39 PST 2002
//    Added validVariable.
//
//    Hank Childs, Mon Feb 14 14:16:49 PST 2005
//    Added original name.
//
//    Mark C. Miller, Thu Jul 13 22:41:56 PDT 2006
//    Added colorNames stringVector
//
// ****************************************************************************
inline void
Indent(ostream &out, int indent)
{
    for (int i = 0 ; i < indent ; i++)
    {
        out << "\t";
    }
}
void
avtMaterialMetaData::Print(ostream &out, int indent) const
{
    avtBaseVarMetaData::Print(out, indent);

    Indent(out, indent);
    out << "Materials names:" << endl;
    Indent(out, indent+1);
    for (size_t i = 0; i < materialNames.size() ; ++i)
    {
        out << "\"" << materialNames[i].c_str() << "\"";

        if (colorNames.size())
        {
            if (colorNames[i] != "")
                out << "(color=\"" << colorNames[i].c_str() << "\")";
            if (i < materialNames.size() - 1)
                out << ", ";
            if((i+1)%3 == 0)
            {
                out << endl;
                Indent(out, indent+1);
            }
        }
        else
        {
            if (i < materialNames.size() - 1)
                out << ", ";
            if((i+1)%6 == 0)
            {
                out << endl;
                Indent(out, indent+1);
            }
        }
    }
    out << endl;
}

