/**
* @file		componenthelper.h
* @brief	sp script parser.
* @author	Cesar Mauri Loba (cesar at crea-si dot com)
* 
* -------------------------------------------------------------------------
*
* Copyright:   (C) 2011 Cesar Mauri Loba - CREA Software Systems
*
*  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/>.
*/
#ifndef COMPONENTHELPER_H
#define COMPONENTHELPER_H

#include "spcore/component.h"
#include "sphost/libimpexp_sphost.h"

#include <exception>
#include <stdexcept>
#include <istream>

#ifdef _MSC_VER
#pragma warning(push)
// non dll-interface class 'A' used as base for dll-interface class 'B'
#pragma warning(disable: 4275)
#endif // _MSC_VER

namespace sphost {

//
// Classes to signal errors during script parsing
//

// Full parser error
class SPIMPEXP_CLASS_HOST parser_error : public std::runtime_error 
{
public:
	parser_error (const std::string& what_arg) : std::runtime_error (what_arg) {}
};

// Partial error. Used when not enough information is known to fully complete the error message
class SPIMPEXP_CLASS_HOST parser_partial_error : public std::runtime_error 
{
public:
	parser_partial_error (const std::string& what_arg) : std::runtime_error (what_arg) {}
};

/**
	This class is intended only to ease the task of working with components and so
	it is only intended to be used by the host application not the modules. Therefore,
	we export directly in the dynamic library.
*/
class SPIMPEXP_CLASS_HOST ComponentHelper {
public:
	/**
	// Parses and input stream and returns a component which contains 
	// the components request to construct and connect. The path argument
	// is used for import directives.
	// 
	// 
	// See README.txt file on scripts directory for syntax details.
	// 		
	// \return the created component
	// 
	// If any error is found throws an parser_error exception
	*/
	static 
	SmartPtr<spcore::IComponent> SimpleParser (std::istream& is, const std::string& dir);

	/**
	// Parses a file using the previous call 
	// 		
	// \return the created component
	// 
	// If any error is found throws an parser_error exception
	*/
	static 
	SmartPtr<spcore::IComponent> SimpleParserFile (const char*);
	
	/**
		Recursively find a component by name. 
		
		\param component: parent component where to search
		\param name: parent component where to search
		\param levels: maximum nesting deep. 0 means unlimited.
		\return pointer to the component or NULL if not found
	*/
	static
	spcore::IComponent* FindComponentByName (spcore::IComponent& component, const char* name, int deep);
};

} // namespace spcore

#ifdef _MSC_VER
#pragma warning(pop)
#endif

#endif
