/**
 * Defines some simple speech behaviors for the Eyebot
 */

#ifndef SPEECH_BEHAVIORS_H
#define SPEECH_BEHAVIORS_H


#include "behavior/behavior.hh"
#include "input/eyebot_sensors.hh"
#include "behavior/stdc_linktypes.hh"
#include "semantic/dictionary.hh"




namespace Soccer03 {

using namespace EyeMind;

#if 0
const int W_SOUND_LENGTH  = 3;
const int W_LETTER_LENGTH = 16;


typedef struct
{
	int tone;
	int duration;
} sound_t;

/**
 * A structure for "words".
 * Holds two pieces of information, the sound and the letters.
 *
 * sound - holds the tone and duration to be played on a Speaker.
 *
 * letter - a character array
 */
typedef struct
{
	sound_t sound[W_SOUND_LENGTH];
	char letter[W_LETTER_LENGTH];
} word_t;


/**
 * Link for transferring "words" see speech_behaviors.hh for enumerated word list
 */

class WordLink : public SignalLink
{
private:
	word_t word;
	word_t next_word;

public:
	WordLink() : SignalLink()
	{
		memset(&word,0,sizeof(word_t));
		memset(&next_word,0,sizeof(word_t));
		generic = false;
	}

	virtual bool Update()
	{
		word = next_word;
		updated = false;
		SignalLink::Update();
		return true;
	}

	virtual void W(const word_t& w)
	{
		next_word = w;
		updated = true;
	}

	word_t& W(){ return word; }
};


//// Again...
#define LOW_TONE 2000
#define MID_TONE 3000
#define HIGH_TONE 4000

#define SHORT_TONE 50
#define LONG_TONE  100

#define PHRASE_LENGTH 2


/**
 * The dictionary
 */
//// This is too anonymous, how do you want to access these?
//enum
//  {
//    W_HI,
//    W_BYE,
//    W_OK,
//    W_OUCH,
//    W_HELP,
//    W_GOOD,
//	W_GO,
//	W_STOP
//  };


#endif

/**
 * A Behavior for speaking over the radio.
 */

class SpeakRadio : public Behavior
{
private:
	RadioComm& radio;

protected:
	virtual int Execute();

public:
	SpeakRadio() : Behavior(), radio(RadioComm::I())
	{}
};

SpeakRadio& operator>>(CharArrayLink& l, SpeakRadio& o);
CharArrayLink& operator<<(SpeakRadio& n, CharArrayLink& i);



/**
 * A Behavior for saying character strings
 */
const int DEFAULT_SPOKEN_STRING_LENGTH=16;

class SayString : public Behavior
{
friend CharArrayLink& operator>>(SayString& n, CharArrayLink& o);
friend SayString& operator<<(CharArrayLink& o, SayString& n);
private:
	char string[DEFAULT_SPOKEN_STRING_LENGTH];
	Dictionary& dictionary;

protected:
	virtual int Execute();

public:
	SayString();
	~SayString();
};

CharArrayLink& operator>>(SayString& n, CharArrayLink& o);
SayString& operator<<(CharArrayLink& o, SayString& n);
SayString& operator>>(IntLink& l, SayString& o);
IntLink& operator<<(SayString& n, IntLink& i);


/**
 * A Behavior for saying character strings
 */
class SayConstString : public Behavior
{
friend CharArrayLink& operator>>(SayConstString& n, CharArrayLink& o);
friend SayConstString& operator<<(CharArrayLink& o, SayConstString& n);
private:
	char string[DEFAULT_SPOKEN_STRING_LENGTH];

protected:
	virtual int Execute();

public:
	SayConstString();
	SayConstString(const char* s);
	~SayConstString();
};

CharArrayLink& operator>>(SayString& n, CharArrayLink& o);
SayString& operator<<(CharArrayLink& o, SayString& n);


/**
 * A Behavior for finding words in a Dictionary.
 * @arg Input: StringLink
 * @arg Output: IntLink
 */
class InterpretString : public Behavior
{
private:
	int index;
	Dictionary dictionary;

protected:
	virtual int Execute();
	void Feed(SignalLink &l);

public:
	InterpretString();
};

InterpretString& operator>>(CharArrayLink& l, InterpretString& o);
InterpretString& operator<<(IntLink& l, InterpretString& i);
IntLink& operator>>(InterpretString& n, IntLink& o);
CharArrayLink& operator<<(InterpretString& n, CharArrayLink& i);



/**
 * A Behavior for interpreting commands from tv remote
 * @arg Input: StringLink
 * @arg Output: IntLink
 */
class InterpretIRtv : public Behavior
{
private:
	int index;
	Index reference;

protected:
	virtual int Execute();
	void Feed(SignalLink &l);

public:
	InterpretIRtv();
};

InterpretIRtv& operator>>(IntLink& l, InterpretIRtv& o);
InterpretIRtv& operator<<(IntLink& l, InterpretIRtv& i);
IntLink& operator>>(InterpretIRtv& n, IntLink& o);
IntLink& operator<<(InterpretIRtv& n, IntLink& i);

}; // namespace Soccer03

#endif
