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

//
// Enum conversion methods for MovieAttributes::MovieTypeEnum
//

static const char *MovieTypeEnum_strings[] = {
"Simple", "UsingTemplate"};

std::string
MovieAttributes::MovieTypeEnum_ToString(MovieAttributes::MovieTypeEnum t)
{
    int index = int(t);
    if(index < 0 || index >= 2) index = 0;
    return MovieTypeEnum_strings[index];
}

std::string
MovieAttributes::MovieTypeEnum_ToString(int t)
{
    int index = (t < 0 || t >= 2) ? 0 : t;
    return MovieTypeEnum_strings[index];
}

bool
MovieAttributes::MovieTypeEnum_FromString(const std::string &s, MovieAttributes::MovieTypeEnum &val)
{
    val = MovieAttributes::Simple;
    for(int i = 0; i < 2; ++i)
    {
        if(s == MovieTypeEnum_strings[i])
        {
            val = (MovieTypeEnum)i;
            return true;
        }
    }
    return false;
}

//
// Enum conversion methods for MovieAttributes::GenerationMethodEnum
//

static const char *GenerationMethodEnum_strings[] = {
"NowCurrentInstance", "NowNewInstance", "Later"
};

std::string
MovieAttributes::GenerationMethodEnum_ToString(MovieAttributes::GenerationMethodEnum t)
{
    int index = int(t);
    if(index < 0 || index >= 3) index = 0;
    return GenerationMethodEnum_strings[index];
}

std::string
MovieAttributes::GenerationMethodEnum_ToString(int t)
{
    int index = (t < 0 || t >= 3) ? 0 : t;
    return GenerationMethodEnum_strings[index];
}

bool
MovieAttributes::GenerationMethodEnum_FromString(const std::string &s, MovieAttributes::GenerationMethodEnum &val)
{
    val = MovieAttributes::NowCurrentInstance;
    for(int i = 0; i < 3; ++i)
    {
        if(s == GenerationMethodEnum_strings[i])
        {
            val = (GenerationMethodEnum)i;
            return true;
        }
    }
    return false;
}

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

void MovieAttributes::Init()
{
    generationMethod = NowCurrentInstance;
    movieType = Simple;
    outputDirectory = ".";
    outputName = "movie";
    sendEmailNotification = false;
    useScreenCapture = false;
    fps = 10;
    startIndex = 0;
    endIndex = 1000000000;
    stride = 1;

    MovieAttributes::SelectAll();
}

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

void MovieAttributes::Copy(const MovieAttributes &obj)
{
    generationMethod = obj.generationMethod;
    movieType = obj.movieType;
    outputDirectory = obj.outputDirectory;
    outputName = obj.outputName;
    fileFormats = obj.fileFormats;
    useCurrentSize = obj.useCurrentSize;
    widths = obj.widths;
    heights = obj.heights;
    scales = obj.scales;
    stereoFlags = obj.stereoFlags;
    templateFile = obj.templateFile;
    sendEmailNotification = obj.sendEmailNotification;
    useScreenCapture = obj.useScreenCapture;
    emailAddress = obj.emailAddress;
    fps = obj.fps;
    startIndex = obj.startIndex;
    endIndex = obj.endIndex;
    stride = obj.stride;

    MovieAttributes::SelectAll();
}

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


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

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

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

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

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

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

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

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

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

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

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

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

    MovieAttributes::Copy(obj);

    return *this;
}

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

bool
MovieAttributes::operator == (const MovieAttributes &obj) const
{
    // Create the return value
    return ((generationMethod == obj.generationMethod) &&
            (movieType == obj.movieType) &&
            (outputDirectory == obj.outputDirectory) &&
            (outputName == obj.outputName) &&
            (fileFormats == obj.fileFormats) &&
            (useCurrentSize == obj.useCurrentSize) &&
            (widths == obj.widths) &&
            (heights == obj.heights) &&
            (scales == obj.scales) &&
            (stereoFlags == obj.stereoFlags) &&
            (templateFile == obj.templateFile) &&
            (sendEmailNotification == obj.sendEmailNotification) &&
            (useScreenCapture == obj.useScreenCapture) &&
            (emailAddress == obj.emailAddress) &&
            (fps == obj.fps) &&
            (startIndex == obj.startIndex) &&
            (endIndex == obj.endIndex) &&
            (stride == obj.stride));
}

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

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

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

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

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

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

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

    return true;
}

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

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

    return retval;
}

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

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

    return retval;
}

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

void
MovieAttributes::SelectAll()
{
    Select(ID_generationMethod,      (void *)&generationMethod);
    Select(ID_movieType,             (void *)&movieType);
    Select(ID_outputDirectory,       (void *)&outputDirectory);
    Select(ID_outputName,            (void *)&outputName);
    Select(ID_fileFormats,           (void *)&fileFormats);
    Select(ID_useCurrentSize,        (void *)&useCurrentSize);
    Select(ID_widths,                (void *)&widths);
    Select(ID_heights,               (void *)&heights);
    Select(ID_scales,                (void *)&scales);
    Select(ID_stereoFlags,           (void *)&stereoFlags);
    Select(ID_templateFile,          (void *)&templateFile);
    Select(ID_sendEmailNotification, (void *)&sendEmailNotification);
    Select(ID_useScreenCapture,      (void *)&useScreenCapture);
    Select(ID_emailAddress,          (void *)&emailAddress);
    Select(ID_fps,                   (void *)&fps);
    Select(ID_startIndex,            (void *)&startIndex);
    Select(ID_endIndex,              (void *)&endIndex);
    Select(ID_stride,                (void *)&stride);
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

    return (addToParent || forceAdd);
}

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

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

    DataNode *node;
    
    //
    // Make sure the formats stored in the data node are valid
    // before we attempt to use the data from them.
    //
    ValidateFormats(searchNode);

    if((node = searchNode->GetNode("generationMethod")) != 0)
    {
        // Allow enums to be int or string in the config file
        if(node->GetNodeType() == INT_NODE)
        {
            int ival = node->AsInt();
            if(ival >= 0 && ival < 3)
                SetGenerationMethod(GenerationMethodEnum(ival));
        }
        else if(node->GetNodeType() == STRING_NODE)
        {
            GenerationMethodEnum value;
            if(GenerationMethodEnum_FromString(node->AsString(), value))
                SetGenerationMethod(value);
        }
    }
    if((node = searchNode->GetNode("movieType")) != 0)
    {
        // Allow enums to be int or string in the config file
        if(node->GetNodeType() == INT_NODE)
        {
            int ival = node->AsInt();
            if(ival >= 0 && ival < 2)
                SetMovieType(MovieTypeEnum(ival));
        }
        else if(node->GetNodeType() == STRING_NODE)
        {
            MovieTypeEnum value;
            if(MovieTypeEnum_FromString(node->AsString(), value))
                SetMovieType(value);
        }
    }
    if((node = searchNode->GetNode("outputDirectory")) != 0)
        SetOutputDirectory(node->AsString());
    if((node = searchNode->GetNode("outputName")) != 0)
        SetOutputName(node->AsString());
    if((node = searchNode->GetNode("fileFormats")) != 0)
        SetFileFormats(node->AsStringVector());
    if((node = searchNode->GetNode("useCurrentSize")) != 0)
        SetUseCurrentSize(node->AsUnsignedCharVector());
    if((node = searchNode->GetNode("widths")) != 0)
        SetWidths(node->AsIntVector());
    if((node = searchNode->GetNode("heights")) != 0)
        SetHeights(node->AsIntVector());
    if((node = searchNode->GetNode("scales")) != 0)
        SetScales(node->AsDoubleVector());
    if((node = searchNode->GetNode("stereoFlags")) != 0)
        SetStereoFlags(node->AsIntVector());
    if((node = searchNode->GetNode("templateFile")) != 0)
        SetTemplateFile(node->AsString());
    if((node = searchNode->GetNode("sendEmailNotification")) != 0)
        SetSendEmailNotification(node->AsBool());
    if((node = searchNode->GetNode("useScreenCapture")) != 0)
        SetUseScreenCapture(node->AsBool());
    if((node = searchNode->GetNode("emailAddress")) != 0)
        SetEmailAddress(node->AsString());
    if((node = searchNode->GetNode("fps")) != 0)
        SetFps(node->AsInt());
    if((node = searchNode->GetNode("startIndex")) != 0)
        SetStartIndex(node->AsInt());
    if((node = searchNode->GetNode("endIndex")) != 0)
        SetEndIndex(node->AsInt());
    if((node = searchNode->GetNode("stride")) != 0)
        SetStride(node->AsInt());
}

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

void
MovieAttributes::SetGenerationMethod(MovieAttributes::GenerationMethodEnum generationMethod_)
{
    generationMethod = generationMethod_;
    Select(ID_generationMethod, (void *)&generationMethod);
}

void
MovieAttributes::SetMovieType(MovieAttributes::MovieTypeEnum movieType_)
{
    movieType = movieType_;
    Select(ID_movieType, (void *)&movieType);
}

void
MovieAttributes::SetOutputDirectory(const std::string &outputDirectory_)
{
    outputDirectory = outputDirectory_;
    Select(ID_outputDirectory, (void *)&outputDirectory);
}

void
MovieAttributes::SetOutputName(const std::string &outputName_)
{
    outputName = outputName_;
    Select(ID_outputName, (void *)&outputName);
}

void
MovieAttributes::SetFileFormats(const stringVector &fileFormats_)
{
    fileFormats = fileFormats_;
    Select(ID_fileFormats, (void *)&fileFormats);
}

void
MovieAttributes::SetUseCurrentSize(const unsignedCharVector &useCurrentSize_)
{
    useCurrentSize = useCurrentSize_;
    Select(ID_useCurrentSize, (void *)&useCurrentSize);
}

void
MovieAttributes::SetWidths(const intVector &widths_)
{
    widths = widths_;
    Select(ID_widths, (void *)&widths);
}

void
MovieAttributes::SetHeights(const intVector &heights_)
{
    heights = heights_;
    Select(ID_heights, (void *)&heights);
}

void
MovieAttributes::SetScales(const doubleVector &scales_)
{
    scales = scales_;
    Select(ID_scales, (void *)&scales);
}

void
MovieAttributes::SetStereoFlags(const intVector &stereoFlags_)
{
    stereoFlags = stereoFlags_;
    Select(ID_stereoFlags, (void *)&stereoFlags);
}

void
MovieAttributes::SetTemplateFile(const std::string &templateFile_)
{
    templateFile = templateFile_;
    Select(ID_templateFile, (void *)&templateFile);
}

void
MovieAttributes::SetSendEmailNotification(bool sendEmailNotification_)
{
    sendEmailNotification = sendEmailNotification_;
    Select(ID_sendEmailNotification, (void *)&sendEmailNotification);
}

void
MovieAttributes::SetUseScreenCapture(bool useScreenCapture_)
{
    useScreenCapture = useScreenCapture_;
    Select(ID_useScreenCapture, (void *)&useScreenCapture);
}

void
MovieAttributes::SetEmailAddress(const std::string &emailAddress_)
{
    emailAddress = emailAddress_;
    Select(ID_emailAddress, (void *)&emailAddress);
}

void
MovieAttributes::SetFps(int fps_)
{
    fps = fps_;
    Select(ID_fps, (void *)&fps);
}

void
MovieAttributes::SetStartIndex(int startIndex_)
{
    startIndex = startIndex_;
    Select(ID_startIndex, (void *)&startIndex);
}

void
MovieAttributes::SetEndIndex(int endIndex_)
{
    endIndex = endIndex_;
    Select(ID_endIndex, (void *)&endIndex);
}

void
MovieAttributes::SetStride(int stride_)
{
    stride = stride_;
    Select(ID_stride, (void *)&stride);
}

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

MovieAttributes::GenerationMethodEnum
MovieAttributes::GetGenerationMethod() const
{
    return GenerationMethodEnum(generationMethod);
}

MovieAttributes::MovieTypeEnum
MovieAttributes::GetMovieType() const
{
    return MovieTypeEnum(movieType);
}

const std::string &
MovieAttributes::GetOutputDirectory() const
{
    return outputDirectory;
}

std::string &
MovieAttributes::GetOutputDirectory()
{
    return outputDirectory;
}

const std::string &
MovieAttributes::GetOutputName() const
{
    return outputName;
}

std::string &
MovieAttributes::GetOutputName()
{
    return outputName;
}

const stringVector &
MovieAttributes::GetFileFormats() const
{
    return fileFormats;
}

stringVector &
MovieAttributes::GetFileFormats()
{
    return fileFormats;
}

const unsignedCharVector &
MovieAttributes::GetUseCurrentSize() const
{
    return useCurrentSize;
}

unsignedCharVector &
MovieAttributes::GetUseCurrentSize()
{
    return useCurrentSize;
}

const intVector &
MovieAttributes::GetWidths() const
{
    return widths;
}

intVector &
MovieAttributes::GetWidths()
{
    return widths;
}

const intVector &
MovieAttributes::GetHeights() const
{
    return heights;
}

intVector &
MovieAttributes::GetHeights()
{
    return heights;
}

const doubleVector &
MovieAttributes::GetScales() const
{
    return scales;
}

doubleVector &
MovieAttributes::GetScales()
{
    return scales;
}

const intVector &
MovieAttributes::GetStereoFlags() const
{
    return stereoFlags;
}

intVector &
MovieAttributes::GetStereoFlags()
{
    return stereoFlags;
}

const std::string &
MovieAttributes::GetTemplateFile() const
{
    return templateFile;
}

std::string &
MovieAttributes::GetTemplateFile()
{
    return templateFile;
}

bool
MovieAttributes::GetSendEmailNotification() const
{
    return sendEmailNotification;
}

bool
MovieAttributes::GetUseScreenCapture() const
{
    return useScreenCapture;
}

const std::string &
MovieAttributes::GetEmailAddress() const
{
    return emailAddress;
}

std::string &
MovieAttributes::GetEmailAddress()
{
    return emailAddress;
}

int
MovieAttributes::GetFps() const
{
    return fps;
}

int
MovieAttributes::GetStartIndex() const
{
    return startIndex;
}

int
MovieAttributes::GetEndIndex() const
{
    return endIndex;
}

int
MovieAttributes::GetStride() const
{
    return stride;
}

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

void
MovieAttributes::SelectOutputDirectory()
{
    Select(ID_outputDirectory, (void *)&outputDirectory);
}

void
MovieAttributes::SelectOutputName()
{
    Select(ID_outputName, (void *)&outputName);
}

void
MovieAttributes::SelectFileFormats()
{
    Select(ID_fileFormats, (void *)&fileFormats);
}

void
MovieAttributes::SelectUseCurrentSize()
{
    Select(ID_useCurrentSize, (void *)&useCurrentSize);
}

void
MovieAttributes::SelectWidths()
{
    Select(ID_widths, (void *)&widths);
}

void
MovieAttributes::SelectHeights()
{
    Select(ID_heights, (void *)&heights);
}

void
MovieAttributes::SelectScales()
{
    Select(ID_scales, (void *)&scales);
}

void
MovieAttributes::SelectStereoFlags()
{
    Select(ID_stereoFlags, (void *)&stereoFlags);
}

void
MovieAttributes::SelectTemplateFile()
{
    Select(ID_templateFile, (void *)&templateFile);
}

void
MovieAttributes::SelectEmailAddress()
{
    Select(ID_emailAddress, (void *)&emailAddress);
}

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

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

std::string
MovieAttributes::GetFieldName(int index) const
{
    switch (index)
    {
    case ID_generationMethod:      return "generationMethod";
    case ID_movieType:             return "movieType";
    case ID_outputDirectory:       return "outputDirectory";
    case ID_outputName:            return "outputName";
    case ID_fileFormats:           return "fileFormats";
    case ID_useCurrentSize:        return "useCurrentSize";
    case ID_widths:                return "widths";
    case ID_heights:               return "heights";
    case ID_scales:                return "scales";
    case ID_stereoFlags:           return "stereoFlags";
    case ID_templateFile:          return "templateFile";
    case ID_sendEmailNotification: return "sendEmailNotification";
    case ID_useScreenCapture:      return "useScreenCapture";
    case ID_emailAddress:          return "emailAddress";
    case ID_fps:                   return "fps";
    case ID_startIndex:            return "startIndex";
    case ID_endIndex:              return "endIndex";
    case ID_stride:                return "stride";
    default:  return "invalid index";
    }
}

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

AttributeGroup::FieldType
MovieAttributes::GetFieldType(int index) const
{
    switch (index)
    {
    case ID_generationMethod:      return FieldType_enum;
    case ID_movieType:             return FieldType_enum;
    case ID_outputDirectory:       return FieldType_string;
    case ID_outputName:            return FieldType_string;
    case ID_fileFormats:           return FieldType_stringVector;
    case ID_useCurrentSize:        return FieldType_ucharVector;
    case ID_widths:                return FieldType_intVector;
    case ID_heights:               return FieldType_intVector;
    case ID_scales:                return FieldType_doubleVector;
    case ID_stereoFlags:           return FieldType_intVector;
    case ID_templateFile:          return FieldType_string;
    case ID_sendEmailNotification: return FieldType_bool;
    case ID_useScreenCapture:      return FieldType_bool;
    case ID_emailAddress:          return FieldType_string;
    case ID_fps:                   return FieldType_int;
    case ID_startIndex:            return FieldType_int;
    case ID_endIndex:              return FieldType_int;
    case ID_stride:                return FieldType_int;
    default:  return FieldType_unknown;
    }
}

// ****************************************************************************
// Method: MovieAttributes::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
MovieAttributes::GetFieldTypeName(int index) const
{
    switch (index)
    {
    case ID_generationMethod:      return "enum";
    case ID_movieType:             return "enum";
    case ID_outputDirectory:       return "string";
    case ID_outputName:            return "string";
    case ID_fileFormats:           return "stringVector";
    case ID_useCurrentSize:        return "ucharVector";
    case ID_widths:                return "intVector";
    case ID_heights:               return "intVector";
    case ID_scales:                return "doubleVector";
    case ID_stereoFlags:           return "intVector";
    case ID_templateFile:          return "string";
    case ID_sendEmailNotification: return "bool";
    case ID_useScreenCapture:      return "bool";
    case ID_emailAddress:          return "string";
    case ID_fps:                   return "int";
    case ID_startIndex:            return "int";
    case ID_endIndex:              return "int";
    case ID_stride:                return "int";
    default:  return "invalid index";
    }
}

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

bool
MovieAttributes::FieldsEqual(int index_, const AttributeGroup *rhs) const
{
    const MovieAttributes &obj = *((const MovieAttributes*)rhs);
    bool retval = false;
    switch (index_)
    {
    case ID_generationMethod:
        {  // new scope
        retval = (generationMethod == obj.generationMethod);
        }
        break;
    case ID_movieType:
        {  // new scope
        retval = (movieType == obj.movieType);
        }
        break;
    case ID_outputDirectory:
        {  // new scope
        retval = (outputDirectory == obj.outputDirectory);
        }
        break;
    case ID_outputName:
        {  // new scope
        retval = (outputName == obj.outputName);
        }
        break;
    case ID_fileFormats:
        {  // new scope
        retval = (fileFormats == obj.fileFormats);
        }
        break;
    case ID_useCurrentSize:
        {  // new scope
        retval = (useCurrentSize == obj.useCurrentSize);
        }
        break;
    case ID_widths:
        {  // new scope
        retval = (widths == obj.widths);
        }
        break;
    case ID_heights:
        {  // new scope
        retval = (heights == obj.heights);
        }
        break;
    case ID_scales:
        {  // new scope
        retval = (scales == obj.scales);
        }
        break;
    case ID_stereoFlags:
        {  // new scope
        retval = (stereoFlags == obj.stereoFlags);
        }
        break;
    case ID_templateFile:
        {  // new scope
        retval = (templateFile == obj.templateFile);
        }
        break;
    case ID_sendEmailNotification:
        {  // new scope
        retval = (sendEmailNotification == obj.sendEmailNotification);
        }
        break;
    case ID_useScreenCapture:
        {  // new scope
        retval = (useScreenCapture == obj.useScreenCapture);
        }
        break;
    case ID_emailAddress:
        {  // new scope
        retval = (emailAddress == obj.emailAddress);
        }
        break;
    case ID_fps:
        {  // new scope
        retval = (fps == obj.fps);
        }
        break;
    case ID_startIndex:
        {  // new scope
        retval = (startIndex == obj.startIndex);
        }
        break;
    case ID_endIndex:
        {  // new scope
        retval = (endIndex == obj.endIndex);
        }
        break;
    case ID_stride:
        {  // new scope
        retval = (stride == obj.stride);
        }
        break;
    default: retval = false;
    }

    return retval;
}

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

// ****************************************************************************
// Method: MovieAttributes::ValidateFormats
//
// Purpose:
//   This method looks at the formats stored in the DataNode and modifies them
//   as required to ensure they are all the same length.
//
// Programmer: Brad Whitlock
// Creation:   Tue Jun 19 09:21:17 PDT 2007
//
// Modifications:
//
// ****************************************************************************

void
MovieAttributes::ValidateFormats(DataNode *searchNode)
{
#define GET_MOVIE_DATA(NN, VN, AF, N) \
    DataNode *NN = searchNode->GetNode(N); \
    if(NN != 0) \
    { \
        VN = NN->AF(); \
        len = (len > VN.size()) ? len : VN.size(); \
    }

#define SET_MOVIE_DATA(NN, VN, SF, N) \
    if(NN == 0) \
        searchNode->AddNode(new DataNode(N, VN)); \
    else \
        NN->SF(VN);

#define ADJUST_LENGTH(VN, V) \
    while(VN.size() < len) \
        VN.push_back(V);

    // Vectors to hold the temporary values.
    stringVector       fileFormatsVec;
    intVector          widthsVec, heightsVec, stereoVec;
    doubleVector       scalesVec;
    unsignedCharVector useCurrentSizeVec;

    // Populate the vectors based on the DataNode values.
    size_t len = 0;
    GET_MOVIE_DATA(ffNode, fileFormatsVec, AsStringVector,  "fileFormats");
    GET_MOVIE_DATA(wNode, widthsVec, AsIntVector, "widths");
    GET_MOVIE_DATA(hNode, heightsVec, AsIntVector, "heights");
    GET_MOVIE_DATA(stereoNode, stereoVec, AsIntVector, "stereoFlags");
    GET_MOVIE_DATA(scaleNode, scalesVec, AsDoubleVector, "scales");
    GET_MOVIE_DATA(csNode, useCurrentSizeVec, AsUnsignedCharVector, "useCurrentSize");

    // Adjust the length of each vector until they all have len items. We put in
    // some default values: use current size, tiff, no stereo.
    ADJUST_LENGTH(fileFormatsVec, "tiff");
    ADJUST_LENGTH(widthsVec, 400);
    ADJUST_LENGTH(heightsVec, 400);
    ADJUST_LENGTH(stereoVec, 0);
    ADJUST_LENGTH(scalesVec, 1.);
    ADJUST_LENGTH(useCurrentSizeVec, 1);

    // Replace the data in the object with the augmented vector values.
    SET_MOVIE_DATA(ffNode, fileFormatsVec, SetStringVector,  "fileFormats");
    SET_MOVIE_DATA(wNode, widthsVec, SetIntVector, "widths");
    SET_MOVIE_DATA(hNode, heightsVec, SetIntVector, "heights");
    SET_MOVIE_DATA(stereoNode, stereoVec, SetIntVector, "stereoFlags");
    SET_MOVIE_DATA(scaleNode, scalesVec, SetDoubleVector, "scales");
    SET_MOVIE_DATA(csNode, useCurrentSizeVec, SetUnsignedCharVector, "useCurrentSize");
}

