#ifndef LIBWCCL_OPS_FUNCTIONS_BOOL_PREDICATES_ANN_H
#define LIBWCCL_OPS_FUNCTIONS_BOOL_PREDICATES_ANN_H

#include <libwccl/ops/functions/bool/predicate.h>

namespace Wccl {

/**
 * An annotation-checking match condition: checks whether the computed
 * range corresponds to an annotation within a given channel. In case
 * of a disjoint annotation, it is sufficient (and olny possible) to correspond
 * to one of the disjoint fragments.
 */
class Ann : public Predicate
{
public:
	Ann(
		const boost::shared_ptr<Function<Match> >& check_from,
		const boost::shared_ptr<Function<Match> >& check_to,
		const std::string& annotation_name)
		: check_from_(check_from),
		  check_to_(check_to),
		  chan_name_(annotation_name)
	{
		BOOST_ASSERT(check_from);
		BOOST_ASSERT(check_to);
		BOOST_ASSERT(!annotation_name.empty());
	}

	Ann(
		const boost::shared_ptr<Function<Match> >& check_from_to,
		const std::string& annotation_name)
		: check_from_(check_from_to),
		  check_to_(check_from_to),
		  chan_name_(annotation_name)
	{
		BOOST_ASSERT(check_from_);
		BOOST_ASSERT(check_to_);
		BOOST_ASSERT(!annotation_name.empty());
	}


	/**
	 * @returns Name of the function
	 */
	std::string raw_name() const {
		return "ann";
	}

	/**
	 * @returns String representation of the predicate
	 */
	std::string to_string(const Corpus2::Tagset& tagset) const;

protected:
	/**
	 * Outputs the string value of the returned value
	 * @returns True
	 */
	BaseRetValPtr apply_internal(const FunExecContext& context) const;

	/**
	 * Writes string representation of the AnnSub to
	 * an output stream.
	 * @returns Stream written to.
	 * @note May be incomplete and/or containt internal info.
	 */
	std::ostream& write_to(std::ostream& ostream) const;

private:
	const boost::shared_ptr< const Function<Match> > check_from_;
	const boost::shared_ptr< const Function<Match> > check_to_;
	const std::string chan_name_;
};

} /* end ns Wccl */

#endif // LIBWCCL_OPS_FUNCTIONS_BOOL_PREDICATES_ANN_H