#ifndef XPathPredicate_h
#define XPathPredicate_h
#include "core/xml/XPathExpressionNode.h"
#include "core/xml/XPathValue.h"
namespace WebCore {
    namespace XPath {
        class Number FINAL : public Expression {
        public:
            explicit Number(double);
        private:
            virtual Value evaluate() const OVERRIDE;
            virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
            Value m_value;
        };
        class StringExpression FINAL : public Expression {
        public:
            explicit StringExpression(const String&);
        private:
            virtual Value evaluate() const OVERRIDE;
            virtual Value::Type resultType() const OVERRIDE { return Value::StringValue; }
            Value m_value;
        };
        class Negative FINAL : public Expression {
        private:
            virtual Value evaluate() const OVERRIDE;
            virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
        };
        class NumericOp FINAL : public Expression {
        public:
            enum Opcode {
                OP_Add, OP_Sub, OP_Mul, OP_Div, OP_Mod
            };
            NumericOp(Opcode, PassOwnPtr<Expression> lhs, PassOwnPtr<Expression> rhs);
        private:
            virtual Value evaluate() const OVERRIDE;
            virtual Value::Type resultType() const OVERRIDE { return Value::NumberValue; }
            Opcode m_opcode;
        };
        class EqTestOp FINAL : public Expression {
        public:
            enum Opcode { OP_EQ, OP_NE, OP_GT, OP_LT, OP_GE, OP_LE };
            EqTestOp(Opcode, PassOwnPtr<Expression> lhs, PassOwnPtr<Expression> rhs);
            virtual Value evaluate() const OVERRIDE;
        private:
            virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
            bool compare(const Value&, const Value&) const;
            Opcode m_opcode;
        };
        class LogicalOp FINAL : public Expression {
        public:
            enum Opcode { OP_And, OP_Or };
            LogicalOp(Opcode, PassOwnPtr<Expression> lhs, PassOwnPtr<Expression> rhs);
        private:
            virtual Value::Type resultType() const OVERRIDE { return Value::BooleanValue; }
            bool shortCircuitOn() const;
            virtual Value evaluate() const OVERRIDE;
            Opcode m_opcode;
        };
        class Union FINAL : public Expression {
        private:
            virtual Value evaluate() const OVERRIDE;
            virtual Value::Type resultType() const OVERRIDE { return Value::NodeSetValue; }
        };
        class Predicate {
            WTF_MAKE_NONCOPYABLE(Predicate); WTF_MAKE_FAST_ALLOCATED;
        public:
            explicit Predicate(PassOwnPtr<Expression>);
            ~Predicate();
            bool evaluate() const;
            bool isContextPositionSensitive() const { return m_expr->isContextPositionSensitive() || m_expr->resultType() == Value::NumberValue; }
            bool isContextSizeSensitive() const { return m_expr->isContextSizeSensitive(); }
        private:
            OwnPtr<Expression> m_expr;
        };
    }
}
#endif