/*
    libmaus2
    Copyright (C) 2018 German Tischler-Höhle

    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
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include <libmaus2/lcs/NPLSelf.hpp>
#include <libmaus2/lcs/AlignmentPrint.hpp>

// check whether any self alignment is present in a trace
static void checkNoSelf(
	libmaus2::lcs::Aligner const & np,
	std::size_t const ab,
	std::size_t const bb
)
{
	auto const & TC = np.getTraceContainer();

	auto ta = TC.ta;
	auto te = TC.te;
	std::size_t pa = ab;
	std::size_t pb = bb;

	while ( ta != te )
	{
		auto const op = *(ta++);

		switch ( op )
		{
			case libmaus2::lcs::AlignmentTraceContainer::STEP_MATCH:
				assert ( pa != pb );
				pa += 1;
				pb += 1;
				break;
			case libmaus2::lcs::AlignmentTraceContainer::STEP_MISMATCH:
				break;
			case libmaus2::lcs::AlignmentTraceContainer::STEP_INS:
				pb += 1;
				break;
			case libmaus2::lcs::AlignmentTraceContainer::STEP_DEL:
				pa += 1;
				break;
			default:
				break;
		}
	}
}

int main()
{
	try
	{
		{
			std::string const a = "AAGAAAGAAGAAG";

			libmaus2::lcs::NPLSelf np;

			std::size_t const ab = 0;
			std::size_t const bb = 1;

			np.np(
				a.begin()+ab,a.end(),
				a.begin()+bb,a.end()
			);

			checkNoSelf(np,ab,bb);

			std::cerr << np.getAlignmentStatistics() << std::endl;

			auto const SL = np.getStringLengthUsed();

			libmaus2::lcs::AlignmentPrint::printAlignmentLines(
				std::cerr,
				a.begin()+ab,
				SL.first,
				a.begin()+bb,
				SL.second,
				80,
				np.ta,
				np.te,
				[](auto const c) {return c;},
				ab,
				bb
			);
		 }
	}
	catch(std::exception const & ex)
	{
		std::cerr << ex.what() << std::endl;
		return EXIT_FAILURE;
	}
}
