//  -*- c++ -*-

#ifndef XPATH_VALUE_H
#define XPATH_VALUE_H

#include <qstring.h>
#include <qcstring.h>

#include <dom/dom_node.h>
#include <xpath/xpath_node.h>

namespace XPath {

class Exception;
class NodeSet;
class Boolean;
class Number;
class String;

/**
 * An XPath value. In addition to the four types required by the
 * XPath specification, we define a null type and a type for
 * reporting exceptions.
 *
 * See REC-xpath-19991116 1.0 Section 1.
 *
 * @version $Id: xmldemo.h,v 1.3 2002/02/18 00:45:47 rich Exp $
 * @author Richard Moore, rich@kde.org 
 */
class Value : public XPathNode
{
public:
    enum ValueType {
	ValueNull, ValueException,
	ValueNodeSet, ValueBoolean, ValueNumber, ValueString
    };

    Value() : tp(ValueNull) {}
    Value( const Value &res );
    virtual ~Value() {}

    bool isNull() const { return tp == ValueNull; }
    bool isException() const { return tp == ValueException; }
    bool isNodeSet() const { return tp == ValueNodeSet; }
    bool isBoolean() const { return tp == ValueBoolean; }
    bool isNumber() const { return tp == ValueNumber; }
    bool isString() const { return tp == ValueString; }

    ValueType type() const { return tp; }

    Exception toException();
    NodeSet toNodeSet();
    Boolean toBoolean();
    Number toNumber();
    String toString();

    virtual QString qstring() const;
    QCString toCString() const { return qstring().local8Bit(); }

protected:
    Value( ValueType t ) : tp(t) {}

private:
    ValueType tp;
};

/**
 * An error value returned by the XPath engine.
 */
class Exception : public Value
{
public:
    Exception();
    Exception( const Exception &ex );
    Exception( const QString &msg );
    virtual ~Exception();

    virtual QString qstring() const;
    QString message() const { return msg; }

private:
    QString msg;
};

/**
 * An XPath node-set value.
 * See REC-xpath-19991116 1.0 Section 1.
 */
class NodeSet : public Value
{
public:
    NodeSet();
    NodeSet( const NodeSet &ns );
    virtual ~NodeSet();

    ulong count() const { return val.length(); }
    DOM::NodeList toNodeList() const { return val; }

private:
    DOM::NodeList val;
};

/**
 * An XPath String value.
 * See REC-xpath-19991116 1.0 Section 1.
 */
class String : public Value
{
public:
    String() : Value(ValueString) {}
    String( const String &s ) : Value(ValueString), val(s.val) {}
    String( const QString &s ) : Value(ValueString), val(s) {}
    String( const char *s ) : Value(ValueString), val(s) {}
    virtual ~String() {}

    QString toQString() const { return val; }

    virtual QString qstring() const;

private:
    QString val;
};

/**
 * An XPath Boolean value.
 * See REC-xpath-19991116 1.0 Section 1.
 */
class Boolean : public Value
{
public:
    Boolean();
    Boolean( const Boolean &b );
    virtual ~Boolean();

    bool toBool() const { return val; }

    virtual QString qstring() const;

private:
    bool val;
};

/**
 * An XPath Number value.
 * See REC-xpath-19991116 1.0 Section 1.
 */
class Number : public Value
{
public:
    Number() : Value(ValueNumber), val(0.0L) {}
    Number( const Number &n ) : Value(ValueNumber), val(n.val) {}

    Number( int i ) : Value(ValueNumber), val(i) {}
    Number( uint i ) : Value(ValueNumber), val(i) {}
    Number( long l ) : Value(ValueNumber), val(l) {}
    Number( ulong l ) : Value(ValueNumber), val(l) {}
    Number( double d ) : Value(ValueNumber), val(d) {}

    virtual ~Number();

    double toDouble() const { return val; }
    int toInt() const { return (int) val; }

    virtual QString qstring() const;

private:
    double val;
};

}; // namespace XPath

#endif // XPATH_VALUE_H

// Local Variables:
// c-basic-offset: 4
// End:
