/**
 * @file c_application.h
 *
 * @brief C application for ns-2 (header).
 *
 * Copyright 2007-2008, Freie Universitaet Berlin. All rights reserved.
 * Please refer to the COPYING file for detailed licensing information.
 *
 * @author Georg Wittenburg
 *
 * $Id: c_application.h 2686 2008-06-26 10:30:01Z wittenbu $
 */

#ifndef SERVICE_PLACEMENT_APPLICATION_H
#define SERVICE_PLACEMENT_APPLICATION_H

#include <stdlib.h>
#include <iostream>

#include "app.h"
#include "god.h"
#include "ip.h"
#include "packet.h"
#include "rng.h"
#include "timer-handler.h"



// Architecture-dependant definitions for C code.

/**
 * @brief Define architecture for all the source that is included later on.
 */
#define ARCH_NS2

/**
 * @brief Type of time.
 */
typedef double			C_time_t;

/**
 * @brief Type of node addresses.
 */
typedef nsaddr_t		C_addr_t;

/**
 * @brief Broadcast address.
 */
#define C_BROADCAST_ADDR	((C_addr_t) IP_BROADCAST)



// Own namespace to prevent name collisions with ns-2 identifiers.
namespace C {

	// Include C types and defines.
	#include "../../types.h"
	#include "../../icmp-light/icmp-light_types.h"
	#include "../../rudp-light/rudp-light_types.h"
	#include "../../slp-light/slp-light_types.h"
	#include "../../service/service_types.h"
	#include "../../placement/placement_types.h"
	#include "../../graphs/graphs_types.h"

	class CApplicationTimer;

	/**
	 * @brief C application as ns-2 object.
	 *
	 * An instances of CApplication are the ns-2 simulation objects for the
	 * service placement code running on different nodes.
	 */
	class CApplication : public Application {
	public:
		CApplication();
		~CApplication();

		// Calls from ns-2.
		virtual void send(int nbytes);
		virtual void recv(int nbytes);
		virtual void recv(Packet* pkt, Handler*);
		virtual void process_data(int size, AppData* data);
		virtual void resume();

		/**
		 * @brief Call from CApplicationTimer.
		 */
		void expire();

		// Include global C variables.
		#include "../../vars.h"
		#include "../../icmp-light/icmp-light_vars.h"
		#include "../../rudp-light/rudp-light_vars.h"
		#include "../../slp-light/slp-light_vars.h"
		#include "../../service/service_vars.h"
		#include "../../placement/placement_vars.h"
		#include "../../graphs/graphs_vars.h"

		// Include C code interface definitions.
		#include "../../interface.h"

		/**
		 * @brief Pointer to the application instance that is currently
		 * being simulated.
		 *
		 * Whenever control is transfered from the ns-2 simulation to a
		 * CApplication object, it sets this variable to the currently
		 * active instance, i.e. itself or "this". This static
		 * reference is necessary for the C code to be able to interact
		 * with the object it logically belongs to.
		 */
		static CApplication* instance_;

	protected:
		// These are entry points specific to ns-2.
		virtual int command(int argc, const char*const* argv);
		virtual void start();
		virtual void stop();

	private:
		/**
		 * @brief Support extra line breaks to group output by time.
		 */
		static double timeOfLastCallToVprintf_;

		/**
		 * @brief Support delayed execution in the application.
		 */
		CApplicationTimer* timer_;

		/**
		 * @brief Random number generator.
		 */
		RNG* rng_;

		/**
		 * @brief Current state of application.
		 */
		int state_;

		/**
		 * @brief Time at which the next callback is to be activated.
		 */
		double timeOfNextCallback_;

		/**
		 * @brief Statistics counter for transmitted unicast packets.
		 */
		int transmittedUnicastPackets_;

		/**
		 * @brief Statistics counter for received unicast packets.
		 */
		int receivedUnicastPackets_;

		/**
		 * @brief Statistics counter for transmitted broadcast packets.
		 */
		int transmittedBroadcastPackets_;

		/**
		 * @brief Statistics counter for received broadcast packets.
		 */
		int receivedBroadcastPackets_;

		/**
		 * @brief Statistics counter for transmitted bytes.
		 */
		int transmittedBytes_;

		/**
		 * @brief Statistics counter for received bytes.
		 */
		int receivedBytes_;
	};

	/**
	 * Simple timer class to support delayed execution in the application.
	 **/

	class CApplicationTimer : public TimerHandler {
	public:
		CApplicationTimer(CApplication* app);
		virtual void expire(Event* e);

	protected:
		/**
		 * @brief
		 */
		CApplication* app_;
	};

}	// namespace C



#endif	// SERVICE_PLACEMENT_APPLICATION_H
