#ifndef MEDIA_CAST_FRAMER_FRAME_ID_MAP_H_
#define MEDIA_CAST_FRAMER_FRAME_ID_MAP_H_
#include <map>
#include <set>
#include "base/memory/linked_ptr.h"
#include "base/memory/scoped_ptr.h"
#include "media/cast/cast_config.h"
#include "media/cast/rtcp/rtcp_defines.h"
#include "media/cast/rtp_receiver/rtp_receiver_defines.h"
namespace media {
namespace cast {
class FrameInfo {
 public:
  FrameInfo(uint32 frame_id,
            uint32 referenced_frame_id,
            uint16 max_packet_id,
            bool key_frame);
  ~FrameInfo();
  PacketType InsertPacket(uint16 packet_id);
  bool Complete() const;
  void GetMissingPackets(bool newest_frame, PacketIdSet* missing_packets) const;
  bool is_key_frame() const { return is_key_frame_; }
  uint32 frame_id() const { return frame_id_; }
  uint32 referenced_frame_id() const { return referenced_frame_id_; }
 private:
  const bool is_key_frame_;
  const uint32 frame_id_;
  const uint32 referenced_frame_id_;
  uint16 max_received_packet_id_;
  PacketIdSet missing_packets_;
  DISALLOW_COPY_AND_ASSIGN(FrameInfo);
};
typedef std::map<uint32, linked_ptr<FrameInfo> > FrameMap;
class FrameIdMap {
 public:
  FrameIdMap();
  ~FrameIdMap();
  PacketType InsertPacket(const RtpCastHeader& rtp_header);
  bool Empty() const;
  bool FrameExists(uint32 frame_id) const;
  uint32 NewestFrameId() const;
  void RemoveOldFrames(uint32 frame_id);
  void Clear();
  
  bool NextContinuousFrame(uint32* frame_id) const;
  uint32 LastContinuousFrame() const;
  bool NextAudioFrameAllowingMissingFrames(uint32* frame_id) const;
  bool NextVideoFrameAllowingSkippingFrames(uint32* frame_id) const;
  int NumberOfCompleteFrames() const;
  void GetMissingPackets(uint32 frame_id,
                         bool last_frame,
                         PacketIdSet* missing_packets) const;
 private:
  bool ContinuousFrame(FrameInfo* frame) const;
  bool DecodableVideoFrame(FrameInfo* frame) const;
  FrameMap frame_map_;
  bool waiting_for_key_;
  uint32 last_released_frame_;
  uint32 newest_frame_id_;
  DISALLOW_COPY_AND_ASSIGN(FrameIdMap);
};
}  
}  
#endif