/*********************************************************************
 * This file is part of the PRAPI library.
 *
 * Copyright (C) 2001 Topi Mäenpää and Jaakko Viertola
 * All rights reserved.
 *
 * This program is free software. You can redistribute and/or modify
 * it under the terms of the free software licence found in the
 * accompanying file "COPYING". The licence terms must always be
 * redistributed with this source file. The above copyright notice
 * must be reproduced in all modified and unmodified copies of this
 * source file.
 *
 * $Revision: 1.8 $
 *********************************************************************/

#include "Quantizer.h"
#include <xml/XMLParser.h>

using namespace std;
using namespace util;
using namespace util::xml;

namespace prapi
{
	void EqualAreaQuantizer::setLevels(int l)
	{
		_lstCutvalues.clear();
		Quantizer::setLevels(l);
	}

	int EqualAreaQuantizer::getBinIndex(double value) throw (QuantizationException&)
	{
		int start=0,end=_lstCutvalues.getLength();
		while(start<end)
			{
				int half = (start+end)>>1;
				if (_lstCutvalues[half] > value)
					end = half;
				else
					start = half+1;
			}
		return start;
	}

	ostream& operator<< (ostream& sout, const EqualAreaQuantizer& quantizer)
	{
		sout << "<equalareaquantizer levels='"<< quantizer.getLevels() <<"'>"<<endl;
		sout << "<cutvalues>" << quantizer.getCutvalues() <<"</cutvalues>"<<endl;
		sout << "</equalareaquantizer>"<<endl;

		return sout;
	}
	
	istream& operator>> (istream& sin, EqualAreaQuantizer& quantizer)
	{
		sin >> ws;
		XMLParser parser;
		SmartPtr<Node> node(parser.getNextNode(sin));
		const Node* child = node->getChildNode("equalareaquantizer.attribute[levels]");
		if (!child)
			throw util::io::IOException("operator>> (istream&, EqualAreaQuantizer): "
																	"The input stream does not contain a valid equalareaquantizer object.");
		quantizer._iLevels = String::parse<int>(((Attr*)child)->value);
		sin >> ws;
		node = parser.getNextNode(sin);
		if (node->getNodeType() != Node::ELEMENT_NODE || node->getName() != "cutvalues")
			throw util::io::IOException("operator>> (istream&, EqualAreaQuantizer): Expecting <cutvalues>, read " +
																	node->getName() + ".");
		sin >> quantizer._lstCutvalues;
		sin >> ws;
		node = parser.getNextNode(sin);
		if (node->getNodeType() != Node::ELEMENT_NODE || ((Element*)node.get())->tagType != Element::TAG_CLOSING ||
				node->getName() != "cutvalues")
			throw util::io::IOException("operator>> (istream&, EqualAreaQuantizer): Expecting </cutvalues>.");
		sin >> ws;
		node = parser.getNextNode(sin);
		if (node->getNodeType() != Node::ELEMENT_NODE || ((Element*)node.get())->tagType != Element::TAG_CLOSING ||
				node->getName() != "equalareaquantizer")
			throw util::io::IOException("operator>> (istream&, EqualAreaQuantizer): Expecting </equalareaquantizer>.");
		return sin;
	}
}
