//## begin module%1.4%.codegen_version preserve=yes
//   Read the documentation to learn more about C++ code generator
//   versioning.
//## end module%1.4%.codegen_version

//## begin module%3D86D3BE02DA.cm preserve=no
//	  %X% %Q% %Z% %W%
//## end module%3D86D3BE02DA.cm

//## begin module%3D86D3BE02DA.cp preserve=no
//## end module%3D86D3BE02DA.cp

//## Module: Communicator%3D86D3BE02DA; Pseudo Package specification
//## Source file: C:\Program Files\Rational\Rose\C++\source\Communicator.h

#ifndef Communicator_h
#define Communicator_h 1

//## begin module%3D86D3BE02DA.additionalIncludes preserve=no
//## end module%3D86D3BE02DA.additionalIncludes

//## begin module%3D86D3BE02DA.includes preserve=yes
#include "Compass.h"
//## end module%3D86D3BE02DA.includes

// Behavior
#include "Behavior.h"
// Timer
#include "Timer.h"
// Radio
#include "Radio.h"
//## begin module%3D86D3BE02DA.additionalDeclarations preserve=yes
//## end module%3D86D3BE02DA.additionalDeclarations


//## begin Communicator%3D86D3BE02DA.preface preserve=yes
//## end Communicator%3D86D3BE02DA.preface

//## Class: Communicator%3D86D3BE02DA
//	/**
//	This class implements the local communication behavior
//	of the robot. It is only needed when using local
//	communication. First the robot is justified so that it
//	faces the other robot at a close distance. Then it is
//	tried to exchange data with the other robot. If successful their
//	cluster points will be exchanged and the older or denser of the two
//	cluster points is chosen as common cluster point.
//	A new cluster point is set by resetting the robot
//	position. (0,0) is always used as cluster point position
//	as it is easier to push cubes to that position. Thus if
//	a new cluster point is chosen the current robot position
//	is adapted.
//	@author Jia L. Du
//	 */
//## Category: <Top Level>
//## Persistence: Transient
//## Cardinality/Multiplicity: n



class Communicator : public Behavior  //## Inherits: <unnamed>%3D9ACA380316
{
  //## begin Communicator%3D86D3BE02DA.initialDeclarations preserve=yes
  //## end Communicator%3D86D3BE02DA.initialDeclarations

  public:
    //## Constructors (generated)
      Communicator();


    //## Other Operations (specified)
      //## Operation: activate%3D9291FF02C6
      //	/**
      //	Activates this behavior
      //	@return A result code indicating why this behavior
      //	terminated. Communicator.DONE or Communicator.NOT_ONE_
      //	RESPONSE or Communicator.ROBOT_LEFT
      //	 */
      int activate ();

      //## Operation: getHaveClusterPoint%3D9D37BE03AC
      //	/**
      //	@return true if the robot does already have a cluster
      //	point
      //	 */
      bool getHaveClusterPoint ();

      //## Operation: setClusterPoint%3D9EC02E0262
      //	/**
      //	Used to tell the communicator to set the robot's cluster
      //	point to the passed position. This is only done if
      //	Communicator::getHaveClusterPoint() returns false, i.e.
      //	if no cluster point was chosen yet. Otherwise the
      //	communicator ignores this command and decides himself
      //	which cluster point to use
      //	@param x x position of the new cluster point
      //	@param y y position of the new cluster point
      //	@return true if new cluster point accepted and set
      //	*/
      bool setClusterPoint (double x, double y);

      //## Attribute: DONE%3D9ABF3E02B2
      //	/**
      //	Used as result code for Communicator::activate()
      //	*/
      //## begin Communicator::DONE%3D9ABF3E02B2.attr preserve=no  public: static int {UC} 0
      static const int DONE;
      //## end Communicator::DONE%3D9ABF3E02B2.attr

      //## Attribute: NOT_ONE_RESPONSE%3D9ABF600244
      //	/**
      //	Used as result code for Communicator::activate()
      //	*/
      //## begin Communicator::NOT_ONE_RESPONSE%3D9ABF600244.attr preserve=no  public: static int {UC} 1
      static const int NOT_ONE_RESPONSE;
      //## end Communicator::NOT_ONE_RESPONSE%3D9ABF600244.attr

      //## Attribute: ROBOT_LEFT%3D9ABF610014
      //	/**
      //	Used as result code for Communicator::activate()
      //	*/
      //## begin Communicator::ROBOT_LEFT%3D9ABF610014.attr preserve=no  public: static int {UC} 2
      static const int ROBOT_LEFT;
      //## end Communicator::ROBOT_LEFT%3D9ABF610014.attr

    // Additional Public Declarations
      //## begin Communicator%3D86D3BE02DA.public preserve=yes
      //## end Communicator%3D86D3BE02DA.public

  protected:
    // Additional Protected Declarations
      //## begin Communicator%3D86D3BE02DA.protected preserve=yes
      //## end Communicator%3D86D3BE02DA.protected

  private:

    //## Other Operations (specified)
      //## Operation: justify%3D9967D5010E
      //	/**
      //	Tries to justify this robot so that it faces the robot
      //	it tries to communicate with at a close distance
      //	@return true if justification was successful
      //	 */
      bool justify ();


      //## Operation: exchangeData%3D99680B00D2
      //	/**
      //	Tries to exchange data with the robot that we met by sending out
      //	messages to all nearby robots and waiting for incoming
      //	messages. If exactly one incoming message is received
      //	we know that it is probably from the robot facing us.
      //  The cluster point age or density and the cluster point location
      //  are exchanged. Based on the exchanged data the older or the denser
      //  of the two cluster points is chosen as cluster point for this robot
      //	@return true if the exchange was completed successfully
      //	 */
      bool exchangeData ();

    // Additional Private Declarations
      //## begin Communicator%3D86D3BE02DA.private preserve=yes
      //	/**
      //	Converts an int into an array of BYTEs. The passed array must
      //  have enough space for an int, i.e. at least 4 bytes
      //	@param valueToConvert the int value that is to be converted into an array of BYTEs
      //  @param arrayToContainValue a pointer to the array that is to contain the converted int
      //	 */
      void int2BYTEArray(int valueToConvert, BYTE* arrayToContainValue);

      //	/**
      //	Converts an array of ints into an array of BYTEs. The passed array of BYTEs must
      //  have enough space for the number of ints that are to be converted, i.e. at least
      //  4 bytes for each int
      //  @param numberOfValues the number of int values to be converted
      //	@param values the int values that are to be converted into an array of BYTEs
      //  @param arrayToContainValues a pointer to the array that is to contain the converted ints
      //	 */
      void intArray2BYTEArray(int numberOfValues, int* values, BYTE* arrayToContainValues);

      //	/**
      //	Converts an array of BYTEs into an int. The passed array must
      //  have enough have at least 4 bytes
      //	@param arrayContainingValue the array that is to be converted into an int
      //  @param value a reference to the int that is to contain the int value from the converted array
      //	 */
      void BYTEArray2Int(BYTE* arrayContainingValue, int& value);

      //	/**
      //	Converts an array of BYTEs into an array of ints. The passed array must
      //  have enough have at least 4 bytes for each int that is to be converted
      //  @param numberOfValues the number of int values to be converted
      //	@param arrayContainingValues the array that is to be converted into a ints
      //  @param values a pointer to the array of ints that is to contain the int values from the converted BYTE array
      //	 */
      void BYTEArray2IntArray(int numberOfValues, BYTE* arrayContainingValues, int values[]);

      //	/**
      //	Empties the message queue of the radio by reading all messages
      //  in the queue. The messages are not retained!
      //	 */
      void emptyMessageQueue(void);

      //## end Communicator%3D86D3BE02DA.private

  private: //## implementation
    // Data Members for Class Attributes

      //## Attribute: haveClusterPoint%3D9D1C0B00B4
      //	/**
      //	Stores if the robot does already have a cluster point
      //	*/
      //## begin Communicator::haveClusterPoint%3D9D1C0B00B4.attr preserve=no  private: bool {U} false
      bool haveClusterPoint;
      //## end Communicator::haveClusterPoint%3D9D1C0B00B4.attr

      //## Attribute: waitingPeriod%3D9968AF0000
      //	/**
      //	Determines how long the robot waits for incoming
      //	responses when exchanging data with other robots
      //	@see Communicator::exchangeData()
      //	 */
      //## begin Communicator::waitingPeriod%3D9968AF0000.attr preserve=no  private: int {U} 450
      int waitingPeriod;
      //## end Communicator::waitingPeriod%3D9968AF0000.attr

    // Data Members for Associations

      //## Association: <unnamed>%3D86D48200D2
      //## Role: Communicator::<radio>%3D86D48603DE
      //	/**
      //	The Communicator uses the Radio to communicate
      //	*/
      //## begin Communicator::<radio>%3D86D48603DE.role preserve=no  public: Radio { -> RHN}
      Radio *radio;
      //## end Communicator::<radio>%3D86D48603DE.role

      //## Association: <unnamed>%3D86D5EB0190
      //## Role: Communicator::<timer>%3D86D5EB0348
      //	/**
      //	The Communicator has a Timer to determine cluster point
      //	ages and to wait for incoming messages
      //	*/
      //## begin Communicator::<timer>%3D86D5EB0348.role preserve=no  public: Timer { -> RHN}
      Timer timer;
      //## end Communicator::<timer>%3D86D5EB0348.role

    // Additional Implementation Declarations
      //## begin Communicator%3D86D3BE02DA.implementation preserve=yes
      //	/**
      //	The Communicator needs the Compass to correctly exchange
      //  its position with the other robot
      //	*/
      Compass *compass;
      //## end Communicator%3D86D3BE02DA.implementation

};

//## begin Communicator%3D86D3BE02DA.postscript preserve=yes
//## end Communicator%3D86D3BE02DA.postscript

// Class Communicator

//## begin module%3D86D3BE02DA.epilog preserve=yes
//## end module%3D86D3BE02DA.epilog


#endif
