#ifndef _SGRAPH_HH
#define _SGRAPH_HH

#include <stdio.h>

#include <list>
#include <vector>
#include <bitset>

#include "const.hh"
#include "thesymbols.hh"


using namespace std;

class MNode;


struct Arc
{
  int dst;
  Role role;
  int anc;
 
  Arc(int d, Role r, int a) : dst(d), role(r), anc(a) {};
 };


struct NodeProp
{
  bitset<MAXTYPES> required;
  bitset<MAXTYPES> forbidden;

  bool operator==(const NodeProp& p)
  { return required==p.required && forbidden==p.forbidden; }

  void clear()
  { required.reset(), forbidden.reset(); }

};


struct SNode
{
  
  MNode* mnode;

  NodeProp prop;

  bitset<MAXNODES> LV;
  bitset<MAXNODES> LH;
  bitset<MAXNODES> LD;
  bool in_LH;

  vector<Arc> heads;
  vector<Arc> deps;

  void clear()      { prop.clear(), LV.reset(), LD.reset(), LH.reset(), heads.clear(), deps.clear(); }
  bool saturated()  { return prop.required.none(); }
};



class SGraph
{
public:

  SNode nodes[MAXNODES];
  int n; // number of nodes

  enum Output { HEADS=1, DEPS=2, SETS=4, CONSTRAINTS=8 };

  SGraph() : n(0) {}

  void clear() { n=0; }
 
  int add_base_snode(MNode* mn);
  int clone(int ancind, NodeProp newprop);
  void update_left(int headind, int depind);
  void update_right(int headind, int depind);

  bool visible(int left, int right);
  bool saturated(int node);

  //--------------------------------------------------------------------

  void read(FILE* f);
  void write(FILE* f, list<int> nodelist, unsigned int info);

  int sprint_node(char* buf, int n, unsigned int info);
  int print_node(FILE* f, int n, unsigned int info);
  int sprint_node_debug(char* buf, const char* pref, int n);
  int print_node_debug(FILE* f, const char* pref, int n);

  void print_arc(FILE* f, int left, int right, Role role, int dir); // 0 - left, 1 - right

};


inline bool SGraph::visible(int left, int right)
{
  return nodes[right].LV[left];
}

inline bool SGraph::saturated(int node)
{
  return nodes[node].saturated();
}

#endif
