/*
    Copyright (C) 2011 Adam Wardyński, Tomasz Śniatowski, Paweł Kędzia,
    Adam Radziszewski, Bartosz Broda
    Part of the WCCL project

    This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3 of the License, or (at your option)
any later version.

    This program is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. 

    See the LICENSE and COPYING files for more details.
*/

#include <libwccl/ops/match/conditions/longest.h>
#include <libwccl/values/matchvector.h>
#include <sstream>
#include <libpwrutils/foreach.h>

namespace Wccl {
namespace Matching {

Longest::Longest(const boost::shared_ptr<std::vector<boost::shared_ptr<ConjConditions> > >& variants)
	: _variants(variants)
{
	BOOST_ASSERT(_variants);
	BOOST_ASSERT(!_variants->empty());
}

MatchResult Longest::apply(const ActionExecContext& context) const
{
	int orig_pos = context.sentence_context().get_position();
	int longest_pos = orig_pos;
	MatchResult longest;

	foreach(const boost::shared_ptr<ConjConditions>& variant, *_variants) {
		MatchResult res = variant->apply(context);
		int cur_pos = context.sentence_context().get_position();
		if (res.matched() && longest_pos < cur_pos) {
			longest_pos = cur_pos;
			longest = res;
		}
		context.sentence_context().set_position(orig_pos);
	}

	context.sentence_context().set_position(longest_pos);
	return longest;
}

std::string Longest::to_string(const Corpus2::Tagset& tagset) const
{
	std::ostringstream ostream;
	ostream << name() << "(";
	for (size_t i = 0; i < _variants->size(); ++i) {
		if (i != 0) {
			ostream << ", ";
		}
		ostream << "variant" << _variants->at(i)->to_string(tagset);
	}
	ostream << ")";
	return ostream.str();
}

std::ostream& Longest::write_to(std::ostream& ostream) const
{
	ostream << name() << "(";
	for (size_t i = 0; i < _variants->size(); ++i) {
		if (i != 0) {
			ostream << ", ";
		}
		ostream << "variant" << *(_variants->at(i));
	}
	return ostream << ")";
}

} /* end ns Matching */
} /* end ns Wccl */