/*****************************************************************************
*
* 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 <ViewerWindowManagerAttributes.h>
#include <DataNode.h>
#include <ActionGroupDescription.h>

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

void ViewerWindowManagerAttributes::Init()
{
    // Initialize the action groups.
    DataNode *parentNode = new DataNode("parent");
    parentNode->AddNode(new DataNode("ViewerWindowManagerAttributes"));
    ProcessOldVersions(parentNode, 0);
    SetFromNode(parentNode);
    delete parentNode;
    toolbarsVisible = true;
    largeIcons = false;

    ViewerWindowManagerAttributes::SelectAll();
}

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

void ViewerWindowManagerAttributes::Copy(const ViewerWindowManagerAttributes &obj)
{
    AttributeGroupVector::const_iterator pos;

    // *** Copy the actionConfigurations field ***
    // Delete the AttributeGroup objects and clear the vector.
    for(pos = actionConfigurations.begin(); pos != actionConfigurations.end(); ++pos)
        delete *pos;
    actionConfigurations.clear();
    if(obj.actionConfigurations.size() > 0)
        actionConfigurations.reserve(obj.actionConfigurations.size());
    // Duplicate the actionConfigurations from obj.
    for(pos = obj.actionConfigurations.begin(); pos != obj.actionConfigurations.end(); ++pos)
    {
        ActionGroupDescription *oldActionGroupDescription = (ActionGroupDescription *)(*pos);
        ActionGroupDescription *newActionGroupDescription = new ActionGroupDescription(*oldActionGroupDescription);
        actionConfigurations.push_back(newActionGroupDescription);
    }

    toolbarsVisible = obj.toolbarsVisible;
    largeIcons = obj.largeIcons;

    ViewerWindowManagerAttributes::SelectAll();
}

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


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

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

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

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

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

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

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

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

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

ViewerWindowManagerAttributes::~ViewerWindowManagerAttributes()
{
    AttributeGroupVector::iterator pos;

    // Destroy the actionConfigurations field.
    for(pos = actionConfigurations.begin(); pos != actionConfigurations.end(); ++pos)
        delete *pos;
}

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

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

    ViewerWindowManagerAttributes::Copy(obj);

    return *this;
}

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

bool
ViewerWindowManagerAttributes::operator == (const ViewerWindowManagerAttributes &obj) const
{
    bool actionConfigurations_equal = (obj.actionConfigurations.size() == actionConfigurations.size());
    for(size_t i = 0; (i < actionConfigurations.size()) && actionConfigurations_equal; ++i)
    {
        // Make references to ActionGroupDescription from AttributeGroup *.
        const ActionGroupDescription &actionConfigurations1 = *((const ActionGroupDescription *)(actionConfigurations[i]));
        const ActionGroupDescription &actionConfigurations2 = *((const ActionGroupDescription *)(obj.actionConfigurations[i]));
        actionConfigurations_equal = (actionConfigurations1 == actionConfigurations2);
    }

    // Create the return value
    return (actionConfigurations_equal &&
            (toolbarsVisible == obj.toolbarsVisible) &&
            (largeIcons == obj.largeIcons));
}

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

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

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

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

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

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

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

    return true;
}

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

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

    return retval;
}

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

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

    return retval;
}

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

void
ViewerWindowManagerAttributes::SelectAll()
{
    Select(ID_actionConfigurations, (void *)&actionConfigurations);
    Select(ID_toolbarsVisible,      (void *)&toolbarsVisible);
    Select(ID_largeIcons,           (void *)&largeIcons);
}

// ****************************************************************************
// Method: ViewerWindowManagerAttributes::CreateSubAttributeGroup
//
// Purpose: 
//   This class contains the attributes that dictate where viewer windows are positioned, etc.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

AttributeGroup *
ViewerWindowManagerAttributes::CreateSubAttributeGroup(int)
{
    return new ActionGroupDescription;
}

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

// ****************************************************************************
// Method: ViewerWindowManagerAttributes::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:   Wed Feb 5 12:27:55 PDT 2003
//
// Modifications:
//   Brad Whitlock, Wed Jul 23 14:00:55 PST 2003
//   Removed window size, location coding.
//
//   Brad Whitlock, Tue Feb 24 13:38:09 PST 2004
//   Added code to save the toolbarsVisible flag.
//
//   Brad Whitlock, Tue Mar 16 11:06:19 PDT 2004
//   Added code to save the large icons flag.
//
// ****************************************************************************

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

    // Create a node for ViewerWindowManagerAttributes.
    DataNode *node = new DataNode("ViewerWindowManagerAttributes");
    DataNode *attNode = new DataNode("ActionConfigurations");
    for(size_t i = 0; i < actionConfigurations.size(); ++i)
        actionConfigurations[i]->CreateNode(attNode, true, true);
    node->AddNode(attNode);

    // Add the toolbars saved flag.
    node->AddNode(new DataNode("toolbarsVisible", toolbarsVisible));

    // Add the large icons flag.
    node->AddNode(new DataNode("largeIcons", largeIcons));

    // Add the node to the parent node.
    parentNode->AddNode(node);

    return true;
}
// ****************************************************************************
// Method: ViewerWindowManagerAttributes::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:   Wed Feb 5 12:27:55 PDT 2003
//
// Modifications:
//   Brad Whitlock, Wed Jul 23 14:00:55 PST 2003
//   Removed window size, location coding.
//
//   Brad Whitlock, Tue Feb 24 13:38:40 PST 2004
//   Added code to read the toolbarsVisible flag.
//
//   Brad Whitlock, Tue Mar 16 12:01:25 PDT 2004
//   Added code to read the largeIcons flag.
//
// ****************************************************************************

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

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

    // Look for the action configuration.
    DataNode *attNode = searchNode->GetNode("ActionConfigurations");
    if(attNode)
    {
        // Clear all the ActionGroupDescriptions.
        ClearActionConfigurations();

        // Go through all of the children and construct a new
        // ActionGroupDescription for each one of them.
        DataNode **children = attNode->GetChildren();
        for(int i = 0; i < attNode->GetNumChildren(); ++i)
        {
            if(children[i]->GetKey() == "ActionGroupDescription")
            {
                ActionGroupDescription temp;
                temp.SetFromNode(children[i]);
                AddActionConfigurations(temp);
            }
        }
    }

    //
    // Read the toolbarsVisible flag.
    //
    DataNode *node;
    if((node = searchNode->GetNode("toolbarsVisible")) != 0)
        SetToolbarsVisible(node->AsBool());

    //
    // Read the largeIcons flag.
    //
    if((node = searchNode->GetNode("largeIcons")) != 0)
        SetLargeIcons(node->AsBool());
}
///////////////////////////////////////////////////////////////////////////////
// Set property methods
///////////////////////////////////////////////////////////////////////////////

void
ViewerWindowManagerAttributes::SetToolbarsVisible(bool toolbarsVisible_)
{
    toolbarsVisible = toolbarsVisible_;
    Select(ID_toolbarsVisible, (void *)&toolbarsVisible);
}

void
ViewerWindowManagerAttributes::SetLargeIcons(bool largeIcons_)
{
    largeIcons = largeIcons_;
    Select(ID_largeIcons, (void *)&largeIcons);
}

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

const AttributeGroupVector &
ViewerWindowManagerAttributes::GetActionConfigurations() const
{
    return actionConfigurations;
}

AttributeGroupVector &
ViewerWindowManagerAttributes::GetActionConfigurations()
{
    return actionConfigurations;
}

bool
ViewerWindowManagerAttributes::GetToolbarsVisible() const
{
    return toolbarsVisible;
}

bool
ViewerWindowManagerAttributes::GetLargeIcons() const
{
    return largeIcons;
}

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

void
ViewerWindowManagerAttributes::SelectActionConfigurations()
{
    Select(ID_actionConfigurations, (void *)&actionConfigurations);
}

///////////////////////////////////////////////////////////////////////////////
// AttributeGroupVector convenience methods.
///////////////////////////////////////////////////////////////////////////////

// ****************************************************************************
// Method: ViewerWindowManagerAttributes::AddActionConfigurations
//
// Purpose: 
//   This class contains the attributes that dictate where viewer windows are positioned, etc.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

void
ViewerWindowManagerAttributes::AddActionConfigurations(const ActionGroupDescription &obj)
{
    ActionGroupDescription *newActionGroupDescription = new ActionGroupDescription(obj);
    actionConfigurations.push_back(newActionGroupDescription);

    // Indicate that things have changed by selecting it.
    Select(ID_actionConfigurations, (void *)&actionConfigurations);
}

// ****************************************************************************
// Method: ViewerWindowManagerAttributes::ClearActionConfigurations
//
// Purpose: 
//   This class contains the attributes that dictate where viewer windows are positioned, etc.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

void
ViewerWindowManagerAttributes::ClearActionConfigurations()
{
    AttributeGroupVector::iterator pos;

    for(pos = actionConfigurations.begin(); pos != actionConfigurations.end(); ++pos)
        delete *pos;
    actionConfigurations.clear();

    // Indicate that things have changed by selecting the list.
    Select(ID_actionConfigurations, (void *)&actionConfigurations);
}

// ****************************************************************************
// Method: ViewerWindowManagerAttributes::RemoveActionConfigurations
//
// Purpose: 
//   This class contains the attributes that dictate where viewer windows are positioned, etc.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

void
ViewerWindowManagerAttributes::RemoveActionConfigurations(int index)
{
    AttributeGroupVector::iterator pos = actionConfigurations.begin();

    // Iterate through the vector "index" times. 
    for(int i = 0; i < index; ++i)
        if(pos != actionConfigurations.end()) ++pos;

    // If pos is still a valid iterator, remove that element.
    if(pos != actionConfigurations.end())
    {
        delete *pos;
        actionConfigurations.erase(pos);
    }

    // Indicate that things have changed by selecting the list.
    Select(ID_actionConfigurations, (void *)&actionConfigurations);
}

// ****************************************************************************
// Method: ViewerWindowManagerAttributes::GetNumActionConfigurations
//
// Purpose: 
//   This class contains the attributes that dictate where viewer windows are positioned, etc.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

int
ViewerWindowManagerAttributes::GetNumActionConfigurations() const
{
    return (int)actionConfigurations.size();
}

// ****************************************************************************
// Method: ViewerWindowManagerAttributes::GetActionConfigurations
//
// Purpose: 
//   This class contains the attributes that dictate where viewer windows are positioned, etc.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

ActionGroupDescription &
ViewerWindowManagerAttributes::GetActionConfigurations(int i)
{
    return *((ActionGroupDescription *)actionConfigurations[i]);
}

// ****************************************************************************
// Method: ViewerWindowManagerAttributes::GetActionConfigurations
//
// Purpose: 
//   This class contains the attributes that dictate where viewer windows are positioned, etc.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

const ActionGroupDescription &
ViewerWindowManagerAttributes::GetActionConfigurations(int i) const
{
    return *((ActionGroupDescription *)actionConfigurations[i]);
}

// ****************************************************************************
// Method: ViewerWindowManagerAttributes::operator []
//
// Purpose: 
//   This class contains the attributes that dictate where viewer windows are positioned, etc.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

ActionGroupDescription &
ViewerWindowManagerAttributes::operator [] (int i)
{
    return *((ActionGroupDescription *)actionConfigurations[i]);
}

// ****************************************************************************
// Method: ViewerWindowManagerAttributes::operator []
//
// Purpose: 
//   This class contains the attributes that dictate where viewer windows are positioned, etc.
//
// Note:       Autogenerated by xml2atts.
//
// Programmer: xml2atts
// Creation:   omitted
//
// Modifications:
//   
// ****************************************************************************

const ActionGroupDescription &
ViewerWindowManagerAttributes::operator [] (int i) const
{
    return *((ActionGroupDescription *)actionConfigurations[i]);
}

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

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

std::string
ViewerWindowManagerAttributes::GetFieldName(int index) const
{
    switch (index)
    {
    case ID_actionConfigurations: return "actionConfigurations";
    case ID_toolbarsVisible:      return "toolbarsVisible";
    case ID_largeIcons:           return "largeIcons";
    default:  return "invalid index";
    }
}

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

AttributeGroup::FieldType
ViewerWindowManagerAttributes::GetFieldType(int index) const
{
    switch (index)
    {
    case ID_actionConfigurations: return FieldType_attVector;
    case ID_toolbarsVisible:      return FieldType_bool;
    case ID_largeIcons:           return FieldType_bool;
    default:  return FieldType_unknown;
    }
}

// ****************************************************************************
// Method: ViewerWindowManagerAttributes::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
ViewerWindowManagerAttributes::GetFieldTypeName(int index) const
{
    switch (index)
    {
    case ID_actionConfigurations: return "attVector";
    case ID_toolbarsVisible:      return "bool";
    case ID_largeIcons:           return "bool";
    default:  return "invalid index";
    }
}

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

bool
ViewerWindowManagerAttributes::FieldsEqual(int index_, const AttributeGroup *rhs) const
{
    const ViewerWindowManagerAttributes &obj = *((const ViewerWindowManagerAttributes*)rhs);
    bool retval = false;
    switch (index_)
    {
    case ID_actionConfigurations:
        {  // new scope
        bool actionConfigurations_equal = (obj.actionConfigurations.size() == actionConfigurations.size());
        for(size_t i = 0; (i < actionConfigurations.size()) && actionConfigurations_equal; ++i)
        {
            // Make references to ActionGroupDescription from AttributeGroup *.
            const ActionGroupDescription &actionConfigurations1 = *((const ActionGroupDescription *)(actionConfigurations[i]));
            const ActionGroupDescription &actionConfigurations2 = *((const ActionGroupDescription *)(obj.actionConfigurations[i]));
            actionConfigurations_equal = (actionConfigurations1 == actionConfigurations2);
        }

        retval = actionConfigurations_equal;
        }
        break;
    case ID_toolbarsVisible:
        {  // new scope
        retval = (toolbarsVisible == obj.toolbarsVisible);
        }
        break;
    case ID_largeIcons:
        {  // new scope
        retval = (largeIcons == obj.largeIcons);
        }
        break;
    default: retval = false;
    }

    return retval;
}

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

// ****************************************************************************
// Method: ViewerWindowManagerAttributes::ProcessOldVersions
//
// Purpose: 
//   This method creates modifies a DataNode representation of the object
//   so it conforms to the newest representation of the object, which can
//   can be read back in.
//
// Programmer: Brad Whitlock
// Creation:   Fri Mar 21 10:37:49 PDT 2003
//
// Modifications:
//   Kathleen Bonnell, Thu May 15 13:13:52 PDT 2003 
//   Added ToggleFullFrameRPC to the viewGroup for 1.1.5.
//
//   Brad Whitlock, Mon Jun 23 16:39:49 PST 2003
//   I added the Clear action group for 1.1.6.
//
//   Brad Whitlock, Mon Dec 29 15:00:03 PST 2003
//   I added new actions.
//
//   Brad Whitlock, Sun Jan 25 19:48:23 PST 2004
//   I renamed some actions.
//
//   Brad Whitlock, Fri Mar 18 17:39:05 PST 2005
//   Added a "Lock" action group.
//
//   Brad Whitlock, Tue Mar 7 18:14:53 PST 2006
//   Added redo view.
//
//   Brad Whitlock, Wed Jan 23 10:58:27 PST 2008
//   Added "Copy active plots", "Disconnect from time slider".
//
//   Jeremy Meredith, Fri Feb 15 15:01:48 EST 2008
//   Added lock tools.
//
//   Hank Childs, Sat Mar 13 18:43:02 PST 2010
//   Remove reference to toggling bounding box mode.
//
// ****************************************************************************

void
ViewerWindowManagerAttributes::ProcessOldVersions(DataNode *parentNode,
    const char *configVersion)
{
    if(parentNode == 0)
        return;

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

    // Try and find the ActionConfigurations node. If there is no such
    // node, create one.
    DataNode *actionNode = searchNode->GetNode("ActionConfigurations");
    if(actionNode == 0)
    {
        actionNode = new DataNode("ActionConfigurations");
        searchNode->AddNode(actionNode);
    }

    //
    // Add actions that are new in 1.1
    //
    if(VersionLessThan(configVersion, "1.1"))
    {
        // Create an action group for the mode.
        ActionGroupDescription modeGroup("Mode");
        AddActionGroup(actionNode, modeGroup);

        // Create an action group for the tools.
        ActionGroupDescription toolGroup("Tools");
        AddActionGroup(actionNode, toolGroup);

        // Create an action group that contains window actions.
        ActionGroupDescription windowGroup("Window");
        windowGroup.AddAction(ViewerRPC::SetActiveWindowRPC);
        windowGroup.AddAction(ViewerRPC::AddWindowRPC);
        windowGroup.AddAction(ViewerRPC::CloneWindowRPC);
        windowGroup.AddAction(ViewerRPC::DeleteWindowRPC);
        windowGroup.AddAction(ViewerRPC::SetWindowLayoutRPC);
        windowGroup.AddAction(ViewerRPC::ToggleSpinModeRPC);
        windowGroup.AddAction(ViewerRPC::InvertBackgroundRPC);
        AddActionGroup(actionNode, windowGroup);

        // Create an action group that contains the view actions.
        ActionGroupDescription viewGroup("View");
        viewGroup.AddAction(ViewerRPC::TogglePerspectiveViewRPC);
        viewGroup.AddAction(ViewerRPC::ToggleLockViewModeRPC);
        viewGroup.AddAction(ViewerRPC::ResetViewRPC);
        viewGroup.AddAction(ViewerRPC::RecenterViewRPC);
        viewGroup.AddAction(ViewerRPC::UndoViewRPC);
        AddActionGroup(actionNode, viewGroup);

        // Create an action group that contains the animation options.
        ActionGroupDescription animationGroup("Animation");
        animationGroup.AddAction(ViewerRPC::TimeSliderPreviousStateRPC);
        animationGroup.AddAction(ViewerRPC::AnimationReversePlayRPC);
        animationGroup.AddAction(ViewerRPC::AnimationStopRPC);
        animationGroup.AddAction(ViewerRPC::AnimationPlayRPC);
        animationGroup.AddAction(ViewerRPC::TimeSliderNextStateRPC);
        AddActionGroup(actionNode, animationGroup);
    }

    //
    // Add actions that are new in 1.1.1
    //
    if(VersionLessThan(configVersion, "1.1.1"))
    {
        AddAction(actionNode, "View", ViewerRPC::SaveViewRPC);
    }

    //
    // Add actions that are new in 1.1.2
    //
    if(VersionLessThan(configVersion, "1.1.2"))
    {
        // Create an action group that contains the operator actions.
        ActionGroupDescription operatorGroup("Operators");
        operatorGroup.SetVisible(false);
        operatorGroup.AddAction(ViewerRPC::AddOperatorRPC);
        operatorGroup.AddAction(ViewerRPC::RemoveLastOperatorRPC);
        operatorGroup.AddAction(ViewerRPC::RemoveAllOperatorsRPC);
        AddActionGroup(actionNode, operatorGroup);

        // Create an action group that contains the operator actions.
        ActionGroupDescription plotGroup("Plots");
        plotGroup.SetVisible(false);
        plotGroup.AddAction(ViewerRPC::AddPlotRPC);
        plotGroup.AddAction(ViewerRPC::DrawPlotsRPC);
        plotGroup.AddAction(ViewerRPC::HideActivePlotsRPC);
        plotGroup.AddAction(ViewerRPC::DeleteActivePlotsRPC);
        AddActionGroup(actionNode, plotGroup);
    }

    //
    // Add actions that are new in 1.1.5
    //
    if(VersionLessThan(configVersion, "1.1.5"))
    {
        AddAction(actionNode, "View", ViewerRPC::ToggleFullFrameRPC);
    }

    //
    // Add actions that are new in 1.1.6
    //
    if(VersionLessThan(configVersion, "1.1.6"))
    {
        ActionGroupDescription clearGroup("Clear");
        clearGroup.SetVisible(true);
        clearGroup.AddAction(ViewerRPC::ClearWindowRPC);
        clearGroup.AddAction(ViewerRPC::ClearAllWindowsRPC);
        clearGroup.AddAction(ViewerRPC::ClearPickPointsRPC);
        clearGroup.AddAction(ViewerRPC::ClearRefLinesRPC);
        AddActionGroup(actionNode, clearGroup);

        // Remove ClearWindowRPC from the Window action group.
        RemoveActionFromNode(actionNode, "Window",
                             ViewerRPC::ClearWindowRPC);
    }

    //
    // Add actions that are new in 1.3
    //
    if(VersionLessThan(configVersion, "1.3"))
    {
        AddAction(actionNode, "View", ViewerRPC::ChooseCenterOfRotationRPC);
    }

    //
    // Add actions that are new in 1.4.3
    //
    if(VersionLessThan(configVersion, "1.4.3"))
    {
        // Remove "lock view" from the View group and make a new "Lock" group.
        RemoveActionFromNode(actionNode, "View", "ToggleLockViewModeRPC");
        ActionGroupDescription lockGroup("Lock");
        lockGroup.SetVisible(true);
        lockGroup.AddAction(ViewerRPC::ToggleLockViewModeRPC);
        lockGroup.AddAction(ViewerRPC::ToggleLockTimeRPC);
        AddActionGroup(actionNode, lockGroup);
    }

    // Add actions that are new in 1.5.2.
    if(VersionLessThan(configVersion, "1.5.2"))
    {
        // Remove some view actions so we can add RedoView and have it be
        // next to UndoView in the list of actions. Then re-add the removed
        // view actions so we don't lose them,
        RemoveActionFromNode(actionNode, "View", ViewerRPC::SaveViewRPC);
        RemoveActionFromNode(actionNode, "View", ViewerRPC::ChooseCenterOfRotationRPC);
        RemoveActionFromNode(actionNode, "View", ViewerRPC::ToggleFullFrameRPC);
        AddAction(actionNode, "View", ViewerRPC::RedoViewRPC);
        AddAction(actionNode, "View", ViewerRPC::ToggleFullFrameRPC);
        AddAction(actionNode, "View", ViewerRPC::SaveViewRPC);
        AddAction(actionNode, "View", ViewerRPC::ChooseCenterOfRotationRPC);
    }

    // Add actions that are new in 1.8.0
    if(VersionLessThan(configVersion, "1.8.0"))
    {
        AddAction(actionNode, "Plots", ViewerRPC::CopyActivePlotsRPC);
    }

    // Add actions that are new in 1.9.0
    if(VersionLessThan(configVersion, "1.9.0"))
    {
        AddAction(actionNode, "Plots", ViewerRPC::SetPlotFollowsTimeRPC);
        AddAction(actionNode, "Lock", ViewerRPC::ToggleLockToolsRPC);
        AddAction(actionNode, "Lock", ViewerRPC::TurnOffAllLocksRPC);
    }

    // Add actions that are new in 1.10.0
    if(VersionLessThan(configVersion, "1.10.0"))
    {
        // Make sure to add the "lock tools" button to the Lock group.
        RemoveActionFromNode(actionNode, "Lock", "ToggleLockToolsRPC");
        RemoveActionFromNode(actionNode, "Lock", "TurnOffAllLocksRPC");
        AddAction(actionNode, "Lock", ViewerRPC::ToggleLockToolsRPC);
        AddAction(actionNode, "Lock", ViewerRPC::TurnOffAllLocksRPC);
    }

    //
    // Remove all of the animation actions and then re-add them with
    // the new names in the right order.
    //
    RemoveActionFromNode(actionNode, "Animation", "TimeSliderPreviousStateRPC");
    RemoveActionFromNode(actionNode, "Animation", "AnimationPreviousFrameRPC");
    RemoveActionFromNode(actionNode, "Animation", "TimeSliderNextStateRPC");
    RemoveActionFromNode(actionNode, "Animation", "AnimationNextFrameRPC");
    RemoveActionFromNode(actionNode, "Animation", "AnimationStopRPC");
    RemoveActionFromNode(actionNode, "Animation", "AnimationReversePlayRPC");
    RemoveActionFromNode(actionNode, "Animation", "AnimationPlayRPC");
    AddAction(actionNode, "Animation", ViewerRPC::TimeSliderPreviousStateRPC);
    AddAction(actionNode, "Animation", ViewerRPC::AnimationReversePlayRPC);
    AddAction(actionNode, "Animation", ViewerRPC::AnimationStopRPC);
    AddAction(actionNode, "Animation", ViewerRPC::AnimationPlayRPC);
    AddAction(actionNode, "Animation", ViewerRPC::TimeSliderNextStateRPC);
}


// ****************************************************************************
// Method: ViewerWindowManagerAttributes::RemoveActionFromNode
//
// Purpose: 
//   Removes an action from an action group in a DataNode.
//
// Arguments:
//   node            : The node that contains the action groups.
//   actionGroupName : The name of the action group from which we're removing
//                     the action.
//   action          : The action to be removed.
//
// Programmer: Brad Whitlock
// Creation:   Tue Jun 24 11:33:38 PDT 2003
//
// Modifications:
//   
// ****************************************************************************

void
ViewerWindowManagerAttributes::RemoveActionFromNode(DataNode *node,
    const char *actionGroupName, ViewerRPC::ViewerRPCType action)
{
    std::string actionName(ViewerRPC::ViewerRPCType_ToString(action));
    RemoveActionFromNode(node, actionGroupName, actionName.c_str());
}


// ****************************************************************************
// Method: ViewerWindowManagerAttributes::RemoveActionFromNode
//
// Purpose: 
//   Removes an action from an action group in a DataNode.
//
// Arguments:
//   node            : The node that contains the action groups.
//   actionGroupName : The name of the action group from which we're removing
//                     the action.
//   action          : The action to be removed.
//
// Programmer: Brad Whitlock
// Creation:   Tue Jun 24 11:33:38 PDT 2003
//
// Modifications:
//   
// ****************************************************************************

void
ViewerWindowManagerAttributes::RemoveActionFromNode(DataNode *node,
    const char *actionGroupName, const char *aName)
{
    // See if the ClearWindow action is in the Window action group.
    // If it is, remove it.
    std::string AGName(actionGroupName);
    std::string actionName(aName);

    DataNode **actionNodes = node->GetChildren();
    for(int i = 0; i < node->GetNumChildren(); ++i)
    {
        DataNode *nameNode = actionNodes[i]->GetNode("name");
        DataNode *aNode = actionNodes[i]->GetNode("actions");
        if(nameNode != 0 && aNode != 0 &&
           nameNode->AsString() == AGName)
        {
            stringVector newActions;
            const stringVector &oldActions = aNode->AsStringVector();
            for(size_t j = 0; j < oldActions.size(); ++j)
            {
                if(oldActions[j] != actionName)
                    newActions.push_back(oldActions[j]);
            }

            aNode->SetStringVector(newActions);
            break;
        }
    }
}


// ****************************************************************************
// Method: ViewerWindowManagerAttributes::AddAction
//
// Purpose: 
//   Adds an action to an existing action group in the DataNode.
//
// Arguments:
//   node            : The node that contains the action groups.
//   actionGroupName : The name of the action group to which we'll add the
//                     new action.
//   action          : The action to be added.
//
// Programmer: Brad Whitlock
// Creation:   Fri Mar 21 13:22:11 PST 2003
//
// Modifications:
//   
// ****************************************************************************

void
ViewerWindowManagerAttributes::AddAction(DataNode *node,
    const char *actionGroupName, ViewerRPC::ViewerRPCType action)
{
    // Look to see if the action group is already in the node.
    DataNode *actionNode = 0;
    DataNode **groups = node->GetChildren();
    std::string AGName(actionGroupName);
    for(int i = 0; i < node->GetNumChildren(); ++i)
    {
        DataNode *nameNode = groups[i]->GetNode("name");
        // If the action group is already in the node, add the new group's
        // actions to it if they are not in it already.
        if(nameNode && nameNode->AsString() == AGName)
        {
            actionNode = groups[i]->GetNode("actions");
            if(actionNode)
                break;
        }
    }

    if(actionNode == 0)
    {
        // No action group with the specified name was found. Make one
        // and insert it into the node.
        ActionGroupDescription newGroup(actionGroupName);
        newGroup.AddAction(action);
        newGroup.CreateNode(node, true, false);
    }
    else
    {
        // If we're adding an action to an existing action group,
        // replace the group's action vector.
        stringVector existingActions(actionNode->AsStringVector());
        existingActions.push_back(ViewerRPC::ViewerRPCType_ToString(action));
        actionNode->SetStringVector(existingActions);
    }
}


// ****************************************************************************
// Method: ViewerWindowManagerAttributes::AddActionGroup
//
// Purpose: 
//   Adds a new action group to the list of action groups in the DataNode
//   that we know about.
//
// Arguments:
//   node : The node to which the action group will be added.
//   ag   : The action group description containing the list of actions that
//          make up the group.
//
// Programmer: Brad Whitlock
// Creation:   Fri Mar 21 13:20:17 PST 2003
//
// Modifications:
//   
// ****************************************************************************

void
ViewerWindowManagerAttributes::AddActionGroup(DataNode *node,
    ActionGroupDescription &ag)
{
    // Look to see if the action group is already in the node.
    DataNode **groups = node->GetChildren();
    for(int i = 0; i < node->GetNumChildren(); ++i)
    {
        DataNode *nameNode = groups[i]->GetNode("name");

        // If the action group is already in the node, add the new group's
        // actions to it if they are not in it already.
        if(nameNode && nameNode->AsString() == ag.GetName())
        {
            DataNode *actionNode = groups[i]->GetNode("actions");
            if(actionNode)
            {
                stringVector existingActions(actionNode->AsStringVector());
                const stringVector &newActions = ag.GetActions();
                bool modifiedActions = false;

                // Add any actions in newActions to existingActions that
                // are not already in existingActions.
                for(size_t j = 0; j < newActions.size(); ++j)
                {
                    bool actionFound = false;
                    for(size_t k = 0; k < existingActions.size(); ++k)
                    {
                        if(existingActions[k] == newActions[j])
                        {
                            actionFound = true;
                            break;
                        }
                    }

                    if(!actionFound)
                    {
                        existingActions.push_back(newActions[j]);
                        modifiedActions = true;
                    }
                }

                // If we added an action, replace the action vector.
                if(modifiedActions)
                    actionNode->SetStringVector(existingActions);

                return;
            }
        }
    }

    // The action group was not in the node. Add it.
    ag.CreateNode(node, true, false);
}

