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

/**
 * @file Bus.h
 * Power System Bus class header.
 */
#ifndef PowerSystem_Bus_h
#define PowerSystem_Bus_h

#include <string>				// HASA string
#include <iostream>				// USES ostream
#include "PowerSystem.def"

POWERSYSTEM_NAMESPACE_BEGIN

/**
 * Power System Bus class.
 * Implements the power system bus class,
 * describing a load, generator, or slack bus in the power system.
 */
class Bus
{
public:
	friend class PowerSystem;		// Needed for BusContainerType to be able to access mName.
	typedef int BusTypeType;		///< Bus type (load, generator, or slack) identifier type.

	// LIFECYCLE

	Bus(void);

	// OPERATIONS

	/**
	 * Writes the bus data to a string.
	 * @return string with bus data.
	 */
	std::string ToString(void) const;

	// ACCESS

	/**
	 * Gets the bus name.
	 * @return bus name.
	 */
	std::string GetName(void) const;

	/**
	 * Sets the bus name to a given string.
	 * @param rName bus name to set.
	 * @return set bus name.
	 */
	std::string SetName(const std::string& rName);

	/**
	 * Checks if the bus is a load bus.
	 * @return \c true if the bus is a load bus, \c false otherwise.
	 */
	bool IsLoadType(void) const;

	/**
	 * Checks if the bus is a generator bus.
	 * @return \c true if the bus is a generator bus, \c false otherwise.
	 */
	bool IsGeneratorType(void) const;

	/**
	 * Checks if the bus is a slack bus.
	 * @return \c true if the bus is a slack bus, \c false otherwise.
	 */
	bool IsSlackType(void) const;

	/**
	 * Sets the bus to be a load bus.
	 */
	void SetLoadType(void);

	/**
	 * Sets the bus to be a generator bus.
	 */
	void SetGeneratorType(void);

	/**
	 * Sets the bus to be a slack bus.
	 */
	void SetSlackType(void);

	/**
	 * Gets the active power demand (Pd) in MW.
	 * @return active power demand.
	 */
	double GetActivePowerDemand(void) const;

	/**
	 * Sets the active power demand (Pd) in MW.
	 * @param val active power demand to set.
	 * @return set active power demand.
	 */
	double SetActivePowerDemand(double val);

	/**
	 * Gets the reactive power demand (Qd) in MVAr.
	 * @return reactive power demand.
	 */
	double GetReactivePowerDemand(void) const;

	/**
	 * Sets the reactive power demand (Qd) in MVAr.
	 * @param val reactive power demand to set.
	 * @return set reactive power demand.
	 */
	double SetReactivePowerDemand(double val);

	/**
	 * Gets the active power generation (Pg) in MW.
	 * @return active power generation.
	 */
	double GetActivePowerGeneration(void) const;

	/**
	 * Sets the active power generation (Pg) in MW.
	 * @param val active power generation to set.
	 * @return set active power generation.
	 */
	double SetActivePowerGeneration(double val);

	/**
	 * Gets the reactive power generation (Qg) in MVAr.
	 * @return reactive power generation.
	 */
	double GetReactivePowerGeneration(void) const;

	/**
	 * Sets the reactive power generation (Qg) in MVAr.
	 * @param val reactive power generation to set.
	 * @return set reactive power generation.
	 */
	double SetReactivePowerGeneration(double val);

	/**
	 * Gets the shunt conductance (Gs) in MW demanded at V=1 p.u.
	 * @return shunt conductance.
	 */
	double GetShuntConductance(void) const;

	/**
	 * Sets the shunt conductance (Gs) in MW demanded at V=1 p.u.
	 * @param val shunt conductance to set.
	 * @return set shunt conductance.
	 */
	double SetShuntConductance(double val);

	/**
	 * Gets the shunt susceptance (Bs) in MVAr injected at V=1 p.u.
	 * @return shunt susceptance.
	 */
	double GetShuntSusceptance(void) const;

	/**
	 * Sets the shunt susceptance (Bs) in MVAr injected at V=1 p.u.
	 * @param val shunt susceptance to set.
	 * @return set shunt susceptance.
	 */
	double SetShuntSusceptance(double val);

	/**
	 * Gets the voltage angle (Va) in radians.
	 * @return voltage angle.
	 */
	double GetVoltageAngle(void) const;

	/**
	 * Sets the voltage angle (Va) in radians.
	 * @param val voltage angle to set.
	 * @return set voltage angle.
	 */
	double SetVoltageAngle(double val);

	/**
	 * Gets the voltage magnitude (Vm) in p.u.
	 * @return voltage magnitude.
	 */
	double GetVoltageMagnitude(void) const;

	/**
	 * Sets the voltage magnitude (Vm) in p.u.
	 * @param val voltage magnitude to set.
	 * @return set voltage magnitude.
	 */
	double SetVoltageMagnitude(double val);

	/**
	 * Gets the base voltage in kV.
	 * @return base voltage.
	 */
	double GetBaseKiloVoltage(void) const;

	/**
	 * Sets the base voltage in kV.
	 * @param val base voltage to set.
	 * @return set base voltage.
	 */
	double SetBaseKiloVoltage(double val);

private:
	static const int msLoadBusId = 1;		///< Bus type identifier for loads.
	static const int msGeneratorBusId = 2;	///< Bus type identifier for generators.
	static const int msSlackBusId = 3;		///< Bus type identifier for the slack bus.

	std::string mName;						///< Bus name.
	BusTypeType mType;						///< Bus type (load, generator, or slack bus).
	double mActivePowerDemand;				///< Active power demand (Pd) in MW.
	double mReactivePowerDemand;			///< Reactive power demand (Qd) in MVAr.
	double mActivePowerGeneration;			///< Active power generation (Pg) in MW.
	double mReactivePowerGeneration;		///< Reactive power generation (Qg) in MVAr.
	double mShuntConductance;				///< Shunt conductance (Gs) in MW demanded at V=1 p.u.
	double mShuntSusceptance;				///< Shunt susceptance (Bs) in MVAr injected at V=1 p.u.
	double mVoltageAngle;					///< Voltage angle (Va) in radians.
	double mVoltageMagnitude;				///< Voltage magnitude (Vm) in p.u.
	double mBaseKiloVoltage;				///< Base voltage in kV.
};

// NON-MEMBER
/**
 * Writes bus data to an output stream.
 * @param rOutput output stream to write the data to.
 * @param rBus bus to write data from.
 * @return output stream to which the data was written.
 */
std::ostream& operator<<(std::ostream& rOutput, const Bus& rBus);

POWERSYSTEM_NAMESPACE_END

#endif // PowerSystem_Bus_h
