/*
 * Copyright (C) 2008-2012 Delft University of Technology - All rights reserved.
 *
 * Author: Reijer Idema
 */

/**
 * @file MatPowerInterface.h
 * MatPower case file interface class header.
 */
#ifndef PowerSystem_MatPowerInterface_h
#define PowerSystem_MatPowerInterface_h

#include <string>			// HASA string
#include <fstream>			// HASA ifstream
#include "Interface.h"		// ISA Interface
#include "../PowerSystem.def"

POWERSYSTEM_NAMESPACE_BEGIN

/**
 * MatPower case file interface class.
 * Implements a power system data interface to MatPower case files.
 */
class MatPowerInterface : public Interface
{
public:
	// LIFECYCLE
	MatPowerInterface(void);

	// ACCESS
	/**
	 * Opens a MatPower case file.
	 * @param rSourceName name of the MatPower case file.
	 * @return \c true on success, \c false on failure.
	 */
	bool Open(const std::string& rSourceName);

	/**
	 * Closes the MatPower case file.
	 * Does nothing if no file is open.
	 */
	void Close(void);

	/**
	 * Read power system data from the case file.
	 * @param rPowerSystem power system object to store the data in.
	 * @return 0 on success, otherwise a negative integer error code.
	 */
	bool Read(PowerSystem& rPowerSystem);


private:
	// STATIC CONSTANTS
	static const ErrorType msNoError = 0;				///< No errors.
	static const ErrorType msFileNotOpenError = -1;		///< Trying to read without a file being open.
	static const ErrorType msGetLineError = -2;			///< Error getting a line from the input stream.
	static const ErrorType msUnknownBlockError = -10;	///< Error while processing an unknown block.
	static const ErrorType msFunctionBlockError = -11;	///< Error in function block.
	static const ErrorType msBaseMVABlockError = -12;	///< Error in baseMVA block.
	static const ErrorType msBusBlockError = -13;		///< Error in bus block.
	static const ErrorType msGenBlockError = -14;		///< Error in gen block.
	static const ErrorType msBranchBlockError = -15;	///< Error in branch block.
	static const ErrorType msAreasBlockError = -16;		///< Error in areas block.
	static const ErrorType msGenCostBlockError = -17;	///< Error in gencost block.

	/**
	 * Reads the bus block from the case file.
	 * @param[in] rFileStream open file stream positioned at the start of the bus block.
	 * @param[in,out] rLineNumber number of the current line in the file.
	 * @param[in,out] rPowerSystem power system object to store the case file data in.
	 * @return number of busses read, -1 on error.
	 */
	int ReadBusBlock(std::istream& rFileStream, int& rLineNumber, PowerSystem& rPowerSystem);

	/**
	 * Reads the generator block from the case file.
	 * @param[in] rFileStream open file stream positioned at the start of the bus block.
	 * @param[in,out] rLineNumber number of the current line in the file.
	 * @param[in,out] rPowerSystem power system object to store the case file data in.
	 * @return number of generators read, -1 on error.
	 */
	int ReadGenBlock(std::istream& rFileStream, int& rLineNumber, PowerSystem& rPowerSystem);

	/**
	 * Reads the branch block from the case file.
	 * @param[in] rFileStream open file stream positioned at the start of the bus block.
	 * @param[in,out] rLineNumber number of the current line in the file.
	 * @param[in,out] rPowerSystem power system object to store the case file data in.
	 * @return number of branches read, -1 on error.
	 */
	int ReadBranchBlock(std::istream& rFileStream, int& rLineNumber, PowerSystem& rPowerSystem);

	/**
	 * Reads an unknown block from the case file.
	 * Reads the block until the start of a new block. Does not use the read data.
	 * @param[in] rFileStream open file stream positioned at the start of the bus block.
	 * @param[in,out] rLineNumber number of the current line in the file.
	 * @return 0 on success, -1 on error.
	 */
	int ReadUnknownBlock(std::istream& rFileStream, int& rLineNumber);

	/**
	 * Removes comments from a string.
	 * If a comment is found, the identifier and all characters after it are removed.
	 * @param str string to process.
	 * @param com string that identifies the start of a comment.
	 */
	void RemoveComment(std::string& str, const std::string& com) const;

	/**
	 * Trims leading and trailing white spaces and tabs from a string.
	 * @param str string to process.
	 */
	void Trim(std::string& str) const;

	/**
	 * Handle MatPower interface error.
	 * @param err error code to handle.
	 * @return \c true if the error code does not signify an actual error, \c false if it does.
	 */
	bool HandleError(ErrorType err) const;

	std::string mFilename;		///< File name of the MatPower case file.
	std::ifstream mFileStream;	///< File stream used to read the case file.
};

POWERSYSTEM_NAMESPACE_END

#endif // PowerSystem_MatPowerInterface_h
