/*
 * Copyright (C) 2007, 2008  Miriam Ruiz <little_miry@yahoo.es>
 *
 * 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 2 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, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "taghandler.h"

#ifdef UNIT_TEST
#include "CuTest.h"
#endif

#include <iostream>

FilterTagHandler::FilterTagHandler() : current_position(0), current_flag(1)
{
}

FilterTagHandler::~FilterTagHandler()
{
}

const FilterTagHandler::Element *FilterTagHandler::GetTag(const std::string name)
{
	for (std::vector<Element>::const_iterator i = elements.begin();
			i != elements.end(); ++i)
	{ if (i->name == name) return &(*i); }
	return NULL;
}

void FilterTagHandler::AddTag(const std::string name)
{
	for (std::vector<Element>::const_iterator i = elements.begin();
			i != elements.end(); ++i)
	{ if (i->name == name) return; }

	Element tag(name, current_position, current_flag);
	current_flag = current_flag << 1;
	if (!current_flag)
	{ current_position++; current_flag=1; }
	elements.push_back(tag);
}

bool FilterTagHandler::TagExists(const std::string name)
{
	for (std::vector<Element>::const_iterator i = elements.begin();
			i != elements.end(); ++i)
	{ if (i->name == name) return true; }
	return false;
}

void FilterTagHandler::PrintAll(std::ostream &out) const
{
	for (std::vector<Element>::const_iterator i = elements.begin();
			i != elements.end(); ++i)
	{
		out << i->name << " (" << i->position << ":" << i->flag << ")" << std::endl;
	}
}

void FilterTagHandler::Print(std::ostream &out, Result *result) const
{
	for (std::vector<Element>::const_iterator i = elements.begin();
			i != elements.end(); ++i)
	{
		if (result->CheckAny(i->position, i->flag))
			out << i->name << " ";
	}
	out << std::endl;
}

#ifdef UNIT_TEST
TEST_FUNCTION TestCuFilterTagHandler(CuTest* tc)
{
	FilterTagHandler tags;
	for (unsigned int i=0; i<70; i++)
	{
		tags.AddTag("A");
		tags.AddTag("B");
		tags.AddTag("C");
		tags.AddTag("D");
		tags.AddTag("E");
		tags.AddTag("F");
		tags.AddTag("G");
		tags.AddTag("H");
		tags.AddTag("I");
		tags.AddTag("J");
		tags.AddTag("K");
		tags.AddTag("L");
		tags.AddTag("LL");
		tags.AddTag("M");
		tags.AddTag("N");
		tags.AddTag("O");
		tags.AddTag("P");
		tags.AddTag("Q");
		tags.AddTag("R");
		tags.AddTag("S");
		tags.AddTag("T");
		tags.AddTag("U");
		tags.AddTag("V");
		tags.AddTag("W");
		tags.AddTag("X");
		tags.AddTag("Y");
		tags.AddTag("Z");
		tags.AddTag("0");
		tags.AddTag("1");
		tags.AddTag("2");
		tags.AddTag("3");
		tags.AddTag("4");
		tags.AddTag("5");
		tags.AddTag("6");
		tags.AddTag("7");
		tags.AddTag("8");
		tags.AddTag("9");
		tags.AddTag("10");
	}

	FilterTagHandler::Result t1, t2, t3, t4;

	tags.SetTag(&t1, "A"); tags.SetTag(&t1, "7"); tags.SetTag(&t1, "MIRY");
	tags.SetTag(&t2, "A"); tags.SetTag(&t2, "7"); tags.SetTag(&t2, "MIRY");
	tags.SetTag(&t3, "A"); tags.SetTag(&t3, "8"); tags.SetTag(&t3, "MIRY");
	tags.SetTag(&t4, "B"); tags.SetTag(&t4, "C");

	CuAssertTrue(tc, t1.CompareAny(t2) == true );
	CuAssertTrue(tc, t1.CompareAny(t3) == true );
	CuAssertTrue(tc, t1.CompareAny(t4) != true );
	CuAssertTrue(tc, t1.CompareAll(t2) == true );
	CuAssertTrue(tc, t1.CompareAll(t3) != true );
	CuAssertTrue(tc, t1.CompareAll(t4) != true );
}
#endif
