/*
#  $Id$
# -----------------------------------------------------------------------------
#  The part of 'VideoNEXT MediaClient SDK'
# -----------------------------------------------------------------------------
#  Author: Petrov Maxim, 03/04/2009
#  Edited by:
#  QA by:
#  Copyright: videoNEXT LLC
# -----------------------------------------------------------------------------
*/

#ifndef CACHE_H_
#define CACHE_H_

#include <list>
#include "c_ptr.h"
#include "FrameConsumer.h"

namespace videonext { namespace media {

class Cache
{
public:
    
    enum CACHE_STATUS {OK, OUT_OF_BUFFER, JUMP2TS};
    enum DIRECTION {BACKWARD=-1, FORWARD};
    
    Cache(UsageEnvironment& env, uint32_t maxSize, MemCounter *mc);

    virtual ~Cache();
    
    /**
     * Add frame to tail, optionaly adjust to last valid frame in the list
     */ 
    void add(CPMediaFrame &cpMediaFrame, bool adjust = false);
    
    /**
     * Return first frame
     */
    CPMediaFrame head(CACHE_STATUS *status = NULL);
    
    /**
     * Return last frame
     */
    CPMediaFrame tail(CACHE_STATUS *status = NULL);
    
    /**
     * Advance on buffer
     */
    CPMediaFrame advance(DIRECTION direction = FORWARD, CACHE_STATUS *status = NULL);
 
    /**
     * Mark current second in the buffer
     */    
    void markJump();
    
    /**
     * Jump to timestamp on buffer
     */
    bool jumpToTimestamp(int32_t timestamp, bool playingArchive);
    
    /**
     * Get buffer boundaries
     * @return false if buffer is empty
     */
    bool boundaries(struct timeval *left, struct timeval *right);
    
private:
    /**
     * Search frame by timestamp
     */
    std::list<CPMediaFrame>::iterator search_first(int32_t timestamp);
    std::list<CPMediaFrame>::iterator search_last(int32_t timestamp);
    std::list<CPMediaFrame>::iterator search_first_more_than(int32_t timestamp);
    
private:
    Mutex mutex_; 
    const int32_t maxSize_;    
    std::list<CPMediaFrame> frameList_;
    std::list<CPMediaFrame>::iterator current_; 
    MemCounter *memCounter_;
    
};
}}
#endif /*CACHE_H_*/
