/* LICENSE:
  =========================================================================
    CMPack'04 Source Code Release for OPEN-R SDK 1.1.5-r2 for ERS7
    Copyright (C) 2004 Multirobot Lab [Project Head: Manuela Veloso]
    School of Computer Science, Carnegie Mellon University
    All rights reserved.
  ========================================================================= */

#ifndef INCLUDED_MainObject_h
#define INCLUDED_MainObject_h

#include <OPENR/ObjcommMessages.h>
#include <OPENR/ObjcommTypes.h>
#include <OPENR/OObject.h>
#include <OPENR/OObserverVector.h>
#include <OPENR/OSubject.h>

class SPOutVisionEncoder;
class BehaviorSystem;

#include "../Vision/Vision.h" /* for rle definition */

#include "def.h"
#include "../headers/Sensors.h"
#include "../headers/AperiosSharedMem.h"
#include "../headers/AperiosMessageStructures.h"
#include "../headers/DogTypes.h"
#include "../Vision/VisionInterface.h"
#include "../Motion/MotionInterface.h"
#include "../Motion/WalkParam.h"
#include "../Behaviors/Behaviors.h"
#include "../headers/SharedMem.h"
#include "../headers/WaveLAN.h"
#include "../headers/EasyNet.h"
#include "../CommMgr/CommMgrInterface.h"
#include "RobotMain.h"
#include "TeamMsgMgr.h"

using namespace VisionInterface;
using namespace Motion;

extern double MaxDX;
extern double MaxDY;
extern double MaxDA;

extern char* model;

// *******************************************************
// DO NOT add more variables to MainObject if they
// don't depend on Aperios specific items.  This class
// is intended for things that are Aperios specific only.
// *******************************************************

class MainObject : public OObject {
public:
  OSubject*          subject[numOfSubject];
  OObserverVector*   observer[numOfObserver];
 
  MainObject();
  ~MainObject() {}

  static MainObject &GetObject();

  //
  //  OPEN-R Method
  //
  virtual OStatus DoInit   (const OSystemEvent&);
  virtual OStatus DoStart  (const OSystemEvent&);
  virtual OStatus DoStop   (const OSystemEvent&);
  virtual OStatus DoDestroy(const OSystemEvent&);

  //
  // Inter Object Communication Method 
  //
  void ReadyGeneric      (const OReadyEvent &event);

  void GotSensorFrame    (const ONotifyEvent &event);
  void GotImage          (const ONotifyEvent &event);
  void ProcessImageRegion(RCRegion *data_region);
  void GotVelParam       (const ONotifyEvent &event); 
  void GotMemRegion      (const ONotifyEvent &event);
  void GameMgrInput      (const ONotifyEvent &event);
  void GotMessage        (const ONotifyEvent &event);
  void NetStatus         (const ONotifyEvent &event);

  void sendOutputBuffer();
  void sendMotionCommand(MotionCommand &command);
  void sendWalkParams(WalkParam &params);
  void queueRoleMessage(int receiver, int type, double activation,
		       int token, double other_act);
  void queueStatusMessage(StatusMsgEntry *my_data);
  void SendStatusAndRoleMsgs(int team_id);

  void requestRegions();
  void setCameraParam();
  char* robotModel();

  void NetReceiveInput(byte *data, int Bytes);

private:
  RobotMain *main;

  // data
  bool gotHeadPos;
  bool takeSnapshot;
  bool have_played;
  ulong okay_to_send_time;

  // streams
  PacketStream *GSensorStream;
  PacketStream *FootSensorStream;
  PacketStream *DutyCycleStream;

  // We need 1-place buffers for status and role assignment
  // messages (we discard existing messages);
  StatusMsgEntry status_queue;
  RoleTokenEntry role_queue;
  bool need_to_send_status;
  bool need_to_send_role;

  // output data (other people create)
  bool requestedRegion[MemoryId::NUM_MEMORY_IDS];
  SMMSharedMemRegion outputMemRgn;
  SMMSharedMemRegion inputMemRgn;
  SMMSharedMemRegion motionLocUpdateMemRgn;
  SMMSharedMemRegion logControlMemRgn;

  // we create
  bool needToSendOutBuffer;
  SMMSharedMemRegion outMemRgn;
};

#endif // INCLUDED_MainObject_h

