//-----------------------------------------------------------------------------
// 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: appMode.hh
//
// Purpose: Mode
//
// Remarks: 
//
// History: 03/15/96 - JPMS - created.
//
// Copyright (c) 1996 Joao P. Marques Silva.
//
// RCS Version:
//     $Id: appMode.hh,v 1.1.1.1 2002/05/01 14:23:27 mguthaus Exp $
//-----------------------------------------------------------------------------

#ifndef __APPMODE__
#define __APPMODE__

#include <vector>
#include <list>
#include <map>
using namespace std;
#include <string.h>

//-----------------------------------------------------------------------------
// Defines common to the interface of the SAT algorithm and the clause
// database.
//-----------------------------------------------------------------------------

enum AppModes {
    _HELP_ = 0,                                          // Prints help message
    _DEBUG_,                                        // Print debugging messages
    _VERBOSE_                    // Print verbose info regarding search process
    };

enum { APP_OPTION_NUMBER = (_VERBOSE_+1) };

//-----------------------------------------------------------------------------
// Class: ModeVal
//
// Purpose: Base class for Mode values.  The appMode class (below) holds
//          values of types derived from this class.  This class has no
//          functionality of its own, it is simply an abstract base class.
//          Derived classes are meant to define mode values of specific
//          types, referred to as type <T>.  The hold an item of type <T> and
//          are required to define two operators:
//             <T> operator* () - returns the stored item of type <T>
//             int operator== (<T>> - compares the stored item to the argument
//-----------------------------------------------------------------------------

class ModeVal {
public:

    //-------------------------------------------------------------------------
    // enumerated type for derived class identification
    //-------------------------------------------------------------------------

    typedef int mode_type;
    enum {
        _MODEVAL_ = 0,
        _MODEINT_,
        _MODEFLOAT_,
        _MODESTR_
    };

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

    ModeVal() {}
    virtual ~ModeVal() {}

    // virtual type information
    virtual mode_type which() { return _MODEVAL_; }
    virtual int is_a(mode_type other) { return (other==_MODEVAL_); }
};

//-----------------------------------------------------------------------------
// Class: ModeInt
//
// Purpose: defines a ModeVal type that stores an int
//-----------------------------------------------------------------------------

class ModeInt : public ModeVal {
public:

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

    ModeInt(const int data) : _data(data) {}
    virtual ~ModeInt() {}

    // virtual type information
    virtual mode_type which() { return _MODEINT_; }
    virtual int is_a(mode_type other) { return (other==_MODEINT_); }

    const int data() { return _data; }

protected:

private:
    int _data;
};

//-----------------------------------------------------------------------------
// Class: ModeFloat
//
// Purpose: defines a ModeVal type that stores an int
//-----------------------------------------------------------------------------

class ModeFloat : public ModeVal {
public:

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

    ModeFloat(const double data) : _data(data) {}
    virtual ~ModeFloat() {}

    // virtual type information
    virtual mode_type which() { return _MODEFLOAT_; }
    virtual int is_a(mode_type other) { return (other==_MODEFLOAT_); }

    const double data() { return _data; }

protected:

private:
    double _data;
};

//-----------------------------------------------------------------------------
// Class: ModeStr
//
// Purpose: defines a ModeVal type that stores a string
//
// Note: the constructor copies the input string, it does not have to be
//       permanent storage.
//-----------------------------------------------------------------------------

class ModeStr : public ModeVal {
public:

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

    ModeStr(const char *data) { _data = strdup(data); }
    virtual ~ModeStr() {}

    // virtual type information
    virtual mode_type which() { return _MODESTR_; }
    virtual int is_a(mode_type other) { return (other==_MODESTR_); }

    const char *data() { return _data; }

protected:

private:
    char *_data;
};

//-----------------------------------------------------------------------------
// Class: appMode
//
// Purpose: Specified operating modes for the SAT algorithm.
//-----------------------------------------------------------------------------

class appMode {
public:

    //-------------------------------------------------------------------------
    // Constructor/destructor.
    //-------------------------------------------------------------------------
    
    appMode();
    virtual ~appMode();

    //-------------------------------------------------------------------------
    // Interface contract.
    //-------------------------------------------------------------------------

    virtual void setup();
    
    ModeVal *new_int_mode(const int val) {
        ModeInt *m = new ModeInt(val);
        _defined_modes.push_back(m);
        return m;
    }
    ModeVal *new_float_mode(const double val) {
        ModeFloat *m = new ModeFloat(val);
        _defined_modes.push_back(m);
        return m;
    }
    ModeVal *new_str_mode(const char *val) {
        ModeStr *m = new ModeStr(val);
        _defined_modes.push_back(m);
        return m;
    }

    // Note: will have to cast the return value to the proper type
    // (e.g. (ModeInt*) before most uses.
    ModeVal* &operator[] (const int idx) { return _mode[idx]; }

    const int int_mode(const int idx);
    const double float_mode(const int idx);
    const char *str_mode(const int idx);

protected:

    virtual void init_mode();

    vector<ModeVal*> _mode;
    list<ModeVal*>  _defined_modes;

};

#endif // __APPMODE__

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