#ifndef Q_ROUTING_QROUTING_POLICY_H
#define Q_ROUTING_QROUTING_POLICY_H

class QRoutingPolicy : public Policy {
public:
	QRoutingPolicy( Network * network );
	virtual ~QRoutingPolicy();

	virtual void Init();
	virtual void Reset();
	virtual void NetworkChange();

	virtual bool OneStep( Router & router , Packet ** packet ) const;
};

class QRoutingExtraData : public RouterExtraData 
{
public:
	QRoutingExtraData( Router * parent );
	virtual ~QRoutingExtraData();

	void	 Clear();
	void	 SetRoutersNum( int routers_num );
	int		 GetRoutersNum();
	void	 AddRouter( Router * router );
	Router * GetNextHop( Router * packet_destination , Router * packet_last_router );
	void	 Update( Router * destination ,
					 Router * neighbor ,
					 double new_expected_time );
	double GetExpectedTime( Router * destination , Router * neighbor ) const;
	double GetExpectedTime( Router * destination ) const;

private:
	class Entry { 
		public:
			Entry() { destination = neighbor = 0; expected_time = PACKET_DUMP_PRICE; }
			Router * destination; 
			Router * neighbor;
			double expected_time;
	};
	
	unsigned int entries_num; // one per network router * neighbor
	unsigned int routers_num;
	Entry * routers_list;
	Router * parent;
	
	Entry * GetRouterEntry( Router * destination , unsigned int neighbor_index ) const;
	Entry * GetRouterEntry( Router * destination , Router * neighbor ) const;

	// neighbours list
	typedef Router * RouterPointer;
	RouterPointer * neighbor_list;
	int neighbor_num;
};

#endif //Q_ROUTING_QROUTING_POLICY_H