#ifndef __MSG_QUEUE__H__
#define __MSG_QUEUE__H__

#include <pthread.h>

enum MsgQueueReturns
  {
    QUEUE_OK=0,
    QUEUE_FULL=-1,
    QUEUE_EMPTY=-2,
    QUEUE_POS_PAST_END=-4,
    QUEUE_PEEK_FAIL=QUEUE_POS_PAST_END
  };

/*
  pop, push, and the like copy the argument rather than use it directly.  
  Copying is slower, but probably not as slow as mallocs.  If the class 
  didn't perform the copy, the user would have had to anyway to get the
  data from the DMA bufffer.
*/
template <typename T>
struct MsgQueue {
  int size;
  T ** queue;
  
  int front;
  int back;
  //int peek_p;
  
  pthread_cond_t * cond;  //used for waking thread blocked on pop
  pthread_mutex_t * cond_lock; 

  pthread_mutex_t * lock; //used for protecting front/back

  MsgQueue(int s);
  ~MsgQueue();
  
  T * pop();
  
  int push(T *);


  int length();

  //struct frame * msg_view_pos(struct MsgQueue * fq, int pos);
  //struct frame * msg_peek(struct MsgQueue * fq);
  //void msg_reset_peek(struct MsgQueue * fq);
  

  int is_full();
  int is_empty();
  void print();

private:
 int local_is_empty();
 int local_is_full();
 int local_length();

};



#endif
