#ifndef LIBWCCL_OPS_ISINSIDE_H
#define LIBWCCL_OPS_ISINSIDE_H

#include <libwccl/ops/predicate.h>
#include <libwccl/ops/formatters.h>
#include <libwccl/values/position.h>

namespace Wccl {

/**
 * Predicate that checks if a position is within sentence boundaries
 */
class IsInside : public Predicate {
public:
	typedef boost::shared_ptr<Function<Position> > PosFunctionPtr;

	IsInside(const PosFunctionPtr& pos_expr)
		: pos_expr_(pos_expr)
	{
		BOOST_ASSERT(pos_expr_);
	}

	virtual std::string to_string(const Corpus2::Tagset& tagset) const {
		return UnaryFunctionFormatter::to_string(tagset, *this, *pos_expr_);
	}

	virtual std::string to_raw_string() const {
		return UnaryFunctionFormatter::to_raw_string(*this, *pos_expr_);
	}

	virtual const std::string raw_operator_name() const {
		return "inside";
	}

protected:
	const PosFunctionPtr pos_expr_;

	/**
	 * Takes values of position from argument, and checks if it is inside sentence
	 * boundaries.
	 * @returns True value if position is within sentence boundaries, False otherwise.
	 */
	virtual BaseRetValPtr apply_internal(const FunExecContext& context) const {
		const boost::shared_ptr<const Position>& pos = pos_expr_->apply(context);
		return Predicate::evaluate(pos->is_inside(context.sentence_context()), context);
	}
};

} /* end ns Wccl */

#endif // LIBWCCL_OPS_ISINSIDE_H