/*********************************************************************
 * This file is part of the PRAPI library.
 *
 * Copyright (C) 2001 Topi Mäenpää
 * 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.13 $
 *********************************************************************/

#include "Sample.h"
#include <String.h>
#include <stdio.h>

using namespace util;
using namespace std;
using namespace util::io;

namespace prapi
{
	ImageSampleIdentifier& ImageSampleIdentifier::operator= (const ImageSampleIdentifier& other)
	{
		_strName = other._strName;
		_iX = other._iX;
		_iY = other._iY;
		_iWidth = other._iWidth;
		_iHeight = other._iHeight;
		return *this;
	}

	void ImageSampleIdentifier::setIdentifier(const string& str)
	{
		List<string> tokens(5);
		String::tokenize(str," \t",tokens);
		tokens.setLength(5);
		_strName = tokens[0];
		_iX = String::parseInt(tokens[1]);
		_iY = String::parseInt(tokens[2]);
		_iWidth = String::parseInt(tokens[3]);
		_iHeight = String::parseInt(tokens[4]);
	}

	string ImageSampleIdentifier::getIdentifier(void)
	{
		char *bfr = new char[50];
		sprintf(bfr," %d %d %d %d",_iX,_iY,_iWidth,_iHeight);
		string result(_strName);
		result += bfr;
		delete bfr;
		return result;
	}

	ostream& operator<< (ostream& sout, const ImageSampleIdentifier& obj)
	{
		sout << "<imagesampleidentifier name='" << String::addXMLEntities(obj._strName) <<
			"' x='" << obj._iX <<
			"' y='" << obj._iY <<
			"' width='" << obj._iWidth <<
			"' height='" << obj._iHeight << "'/>";
		return sout;
	}

#define getInt(variable,name) \
	child = node->getChildNode(string("imagesampleidentifier.") + name); \
	if (child && child->getNodeType() == Node::ATTRIBUTE_NODE) \
		variable = String::parseInt(((Attr*)child)->value); \
	else \
	  throw IOException("operator>> (istream&, ImageSampleIdentifier&):" \
													"Cannot read the required attribute '" + string(name) + "'.");
	
	istream& operator>> (istream& sin, ImageSampleIdentifier& obj)
	{
		using namespace xml;
		XMLParser parser;
		sin >> ws;
		if (sin && sin.peek() != '<')
			return oldRead(sin,obj);
		
		auto_ptr<Node> node(parser.readFragment(sin));
		if (!node.get())
			throw IOException("operator>> (istream&, ImageSampleIdentifier&): Input stream does not contain an ImageSampleIdentifier.");
		const Node* child;
		getInt(obj._iX,"x");
		getInt(obj._iY,"y");
		getInt(obj._iWidth,"width");
		getInt(obj._iHeight,"height");

		child = node->getChildNode("imagesampleidentifier.name");
		if (child && child->getNodeType() == Node::ATTRIBUTE_NODE)
			obj._strName = ((Attr*)child)->value;
		else
			throw IOException("operator>> (istream&, ImageSampleIdentifier&):" \
														"Cannot read the required attribute 'name'.");
		return sin;
	}

#undef getInt
	
	istream& oldRead(istream& sin, ImageSampleIdentifier& obj)
	{
		throw IOException("operator>> (istream&, ImageSampleIdentifier&): Sorry, the support for the old format has been removed.");
	}
	
}
