

#ifndef VALIB_FILTER_GRAPH_H
#define VALIB_FILTER_GRAPH_H

#include "filter.h"

static const int graph_nodes = 32;
 
static const int node_start = graph_nodes;
static const int node_end   = graph_nodes + 1;
static const int node_err   = -1;

class FilterGraph : public Filter
{
private:
  bool ofdd; 

  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  

  NullFilter start;
  NullFilter end;

  int next[graph_nodes + 2];
  int prev[graph_nodes + 2];
  Filter *filter[graph_nodes + 2];
  enum { ns_ok, ns_dirty, ns_flush, ns_rebuild } node_state[graph_nodes + 2];

  
  

  bool build_chain(int node);
  bool add_node(int node, Speakers spk);

  
  

  bool process_internal(bool rebuild);

protected:
  
  

  inline int chain_next(int node) const { return next[node]; }
  inline int chain_prev(int node) const { return prev[node]; }

  void drop_chain();
  void set_dirty(int node);
  void invalidate_chain();
  void rebuild_node(int node);

  
  

  virtual const char *get_name(int node) const
  {
    
    return 0;
  }

  virtual Filter *init_filter(int node, Speakers spk)
  {
    
    return 0;
  }

  virtual int get_next(int node, Speakers spk) const
  {
    
    
    
    
    
    
    
    
    
    
    
    
    

    return node_end;
  }

public:
  FilterGraph(int _format_mask);
  virtual ~FilterGraph();

  
  
  
  
  
  
  

  int chain_text(char *buf, size_t buf_size) const;

  
  

  virtual void reset();

  virtual bool is_ofdd() const;
  virtual bool query_input(Speakers spk) const;
  virtual bool set_input(Speakers spk);
  virtual Speakers get_input() const;

  virtual bool process(const Chunk *chunk);
  virtual Speakers get_output() const;
  virtual bool is_empty() const;
  virtual bool get_chunk(Chunk *chunk);
};


class FilterChain : public FilterGraph
{
protected:
  Filter *chain[graph_nodes];
  char   *desc[graph_nodes];
  int     chain_size;

  
  

  const char *get_name(int _node) const;
  Filter *init_filter(int _node, Speakers _spk);
  int get_next(int _node, Speakers _spk) const;

public:
  FilterChain(int _format_mask = -1);
  virtual ~FilterChain();

  
  

  bool add_front(Filter *_filter, const char *_desc);
  bool add_back(Filter *_filter, const char *_desc);

  void drop();
};

#endif
