//-----------------------------------------------------------------------------
// COPYRIGHT  (c)  1997 
// THE REGENTS OF THE UNIVERSITY OF MICHIGAN
// ALL RIGHTS RESERVED
// 
// PERMISSION IS GRANTED TO USE, COPY, CREATE DERIVATIVE WORKS 
// AND REDISTRIBUTE THIS SOFTWARE AND SUCH DERIVATIVE WORKS FOR 
// ANY PURPOSE, SO LONG AS NO FEE IS CHARGED, AND SO LONG AS 
// THE COPYRIGHT NOTICE ABOVE, THIS GRANT OF PERMISSION, AND 
// THE DISCLAIMER BELOW APPEAR IN ALL COPIES MADE; AND SO LONG 
// AS THE NAME OF THE UNIVERSITY OF MICHIGAN IS NOT USED IN ANY 
// ADVERTISING OR PUBLICITY PERTAINING TO THE USE OR 
// DISTRIBUTION OF THIS SOFTWARE WITHOUT SPECIFIC, WRITTEN 
// PRIOR AUTHORIZATION.
// 
// THIS SOFTWARE IS PROVIDED AS IS, WITHOUT REPRESENTATION 
// FROM THE UNIVERSITY OF MICHIGAN AS TO ITS FITNESS 
// FOR ANY PURPOSE, AND WITHOUT WARRANTY BY THE 
// UNIVERSITY OF MICHIGAN OF ANY KIND, EITHER EXPRESS OR 
// IMPLIED, INCLUDING WITHOUT LIMITATION THE IMPLIED WARRANTIES 
// OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 
// REGENTS OF THE UNIVERSITY OF MICHIGAN SHALL NOT BE LIABLE 
// FOR ANY DAMAGES, INCLUDING SPECIAL, INDIRECT, INCIDENTAL, OR 
// CONSEQUENTIAL DAMAGES, WITH RESPECT TO ANY CLAIM ARISING OUT 
// HAS BEEN OR IS HEREAFTER ADVISED OF THE POSSIBILITY OF SUCH 
// DAMAGES.
//-----------------------------------------------------------------------------

//-----------------------------------------------------------------------------
// File: argument.hh
//
// Purpose: container class to hold parser arguments
//
// Remarks: 
//
// History: 03/15/97 - MAR - created.
//
// Copyright (c) 1997 Michael A. Riepe
//
// RCS Version:
//     $Id: argument.hh,v 1.1.1.1 2002/05/01 14:23:27 mguthaus Exp $
//-----------------------------------------------------------------------------

#ifndef __ARGUMENT__
#define __ARGUMENT__

#include <vector>
#include <map>
#include <list>
using namespace std;
#include <stream.h>
#include "functors.hh"

class Argument;
class RecursiveArgument;
class IntegerArgument;
class DoubleArgument;
class StringArgument;
class FunctionArgument;
class ParameterArgument;
class NodeAssignmentArgument;

typedef vector<Argument *> ArgumentVec;
typedef vector<RecursiveArgument *> RecursiveArgumentVec;
typedef vector<IntegerArgument *> IntegerArgumentVec;
typedef vector<DoubleArgument *> DoubleArgumentVec;
typedef vector<StringArgument *> StringArgumentVec;
typedef vector<FunctionArgument *> FunctionArgumentVec;
typedef vector<ParameterArgument *> ParameterArgumentVec;
typedef vector<NodeAssignmentArgument *> NodeAssignmentArgumentVec;

//-----------------------------------------------------------------------------
// Class: Argument
//
// Purpose: abstract parent class for different kinds of arguments.  
//-----------------------------------------------------------------------------

class Argument {
public:

    //-------------------------------------------------------------------------
    // enumerated type for derived class identification
    //-------------------------------------------------------------------------
    
    typedef int arg_type;
    
    enum {
        _ARGUMENT_,
        _RECURSIVE_,
        _INTEGER_,
        _DOUBLE_,
        _STRING_,
        _FUNCTION_,
        _PARAMETER_,
        _NODEASSIGNMENT_
    };

    //-------------------------------------------------------------------------
    // Constructor/destructor.
    //-------------------------------------------------------------------------

    Argument();
    virtual ~Argument();

    virtual void dump(ostream &os);
    virtual arg_type which() { return _ARGUMENT_; }
    virtual int is_a(arg_type other) { return (other==_ARGUMENT_); }

protected:

private:

};


//-----------------------------------------------------------------------------
// Class: RecursiveArgument
//
// Purpose: 
//-----------------------------------------------------------------------------

class RecursiveArgument : public Argument {
public:

    //-------------------------------------------------------------------------
    // Constructor/destructor.
    //-------------------------------------------------------------------------

    RecursiveArgument();
    RecursiveArgument(ArgumentVec *args);
    virtual ~RecursiveArgument();

    virtual void dump(ostream &os);
    virtual arg_type which() { return _RECURSIVE_; }
    virtual int is_a(arg_type other) { return (other==_RECURSIVE_); }

    inline void add_argument (Argument *new_arg) { _arguments->push_back(new_arg); }
        
    inline ArgumentVec &arguments() {return *_arguments;}

protected:

private:
    ArgumentVec *_arguments;

};

//-----------------------------------------------------------------------------
// Class: IntegerArgument
//
// Purpose: 
//-----------------------------------------------------------------------------

class IntegerArgument : public Argument {
public:

    //-------------------------------------------------------------------------
    // Constructor/destructor.
    //-------------------------------------------------------------------------

    IntegerArgument(int data);
    virtual ~IntegerArgument();

    virtual void dump(ostream &os);
    virtual arg_type which() { return _INTEGER_; }
    virtual int is_a(arg_type other) { return (other==_INTEGER_); }

    inline int data() { return _data; };

protected:

private:
    int _data;
};

//-----------------------------------------------------------------------------
// Class: DoubleArgument
//
// Purpose: 
//-----------------------------------------------------------------------------

class DoubleArgument : public Argument {
public:

    //-------------------------------------------------------------------------
    // Constructor/destructor.
    //-------------------------------------------------------------------------

    DoubleArgument(double data);
    virtual ~DoubleArgument();

    virtual void dump(ostream &os);
    virtual arg_type which() { return _DOUBLE_; }
    virtual int is_a(arg_type other) { return (other==_DOUBLE_); }

    inline double data() { return _data; };

protected:

private:
    double _data;
};

//-----------------------------------------------------------------------------
// Class: StringArgument
//
// Purpose: class to hold string arguments, derived from argument parent class
//-----------------------------------------------------------------------------

class StringArgument : public Argument {
public:
    
    //-------------------------------------------------------------------------
    // Constructor/destructor.
    //-------------------------------------------------------------------------

    StringArgument(char *data);
    virtual ~StringArgument();

    virtual void dump(ostream &os);
    virtual arg_type which() { return _STRING_; }
    virtual int is_a(arg_type other) { return (other==_STRING_); }

    inline char *data() { return _data; }

protected:

private:
    char *_data;
};


//-----------------------------------------------------------------------------
// Class: FunctionAgrument
//
// Purpose: 
//-----------------------------------------------------------------------------

class FunctionArgument : public RecursiveArgument {
public:

    //-------------------------------------------------------------------------
    // Constructor/destructor.
    //-------------------------------------------------------------------------

    FunctionArgument(char* name);
    FunctionArgument(char* name, ArgumentVec *args);
    virtual ~FunctionArgument();

    virtual void dump(ostream &os);
    virtual arg_type which() { return _FUNCTION_; }
    virtual int is_a(arg_type other) { return (other==_FUNCTION_); }

    inline char *name() { return _name; }

protected:

private:
    char *_name;
};


//-----------------------------------------------------------------------------
// Class: ParameterArgument
//
// Purpose: 
//-----------------------------------------------------------------------------

class ParameterArgument : public RecursiveArgument {
public:

    //-------------------------------------------------------------------------
    // Constructor/destructor.
    //-------------------------------------------------------------------------

    ParameterArgument(char *lhs);
    ParameterArgument(char *lhs, ArgumentVec *args);
    virtual ~ParameterArgument();

    virtual void dump(ostream &os);
    virtual arg_type which() { return _PARAMETER_; }
    virtual int is_a(arg_type other) { return (other==_PARAMETER_); }

    inline char *lhs() { return _lhs; }

protected:

private:
    char *_lhs;
};


//-----------------------------------------------------------------------------
// Class: NodeAssignmentArgument
//
// Purpose: 
//-----------------------------------------------------------------------------

class NodeAssignmentArgument : public RecursiveArgument {
public:

    //-------------------------------------------------------------------------
    // Constructor/destructor.
    //-------------------------------------------------------------------------

    NodeAssignmentArgument(Argument *lhs);
    NodeAssignmentArgument(Argument *lhs, ArgumentVec *args);
    virtual ~NodeAssignmentArgument();

    virtual void dump(ostream &os);
    virtual arg_type which() { return _NODEASSIGNMENT_; }
    virtual int is_a(arg_type other) { return (other==_NODEASSIGNMENT_); }

    inline FunctionArgument *lhs() { return _lhs; }

protected:

private:
    FunctionArgument *_lhs;
};

#endif // __ARGUMENT__

/*****************************************************************************/
