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

#ifndef CubeH
#define CubeH

//#include <climits>



class Cube {
  protected:
	int dim;            // dimension. -1 means that it is not computed yet. Just for internal purposes.
    string IM;           // the term. '0', '1' and '-' are valid values. Deprecated
	//pair<bitvector, bitvector> IM_data;		// (00) = 0, (10) = 1, (01) = dc
	bitvector IM_data;
    unsigned int index;  // index of the term
	bool unwanted;		// this one is to be deleted by Purge();

		// for BOOM
	vector<bitvector> SO_CoverVector;	// vector of source function terms, which are covered by it, for each output separately
	bitvector CoverVector;	// vector of source function terms, which are covered by it

public:
    Cube(void);
    Cube( const unsigned int iv );
    //~Cube(void);

	int tmp;					// for public use. Must not be modified by the kernel!

	bool operator== ( const string &s ) const { return this->IM == s; };
	bool operator== ( const Cube &t ) const;

	void clear(void);				// clears all data
	void init( const unsigned int iv );	// assigns all dc values

		// these should be used with care! For PLA and SoPLA only.	
	void setIndex( const unsigned int val ) { index = val; };
	unsigned int getIndex(void) const { return index; };		// !Needs not be correctly computed! Do use PLA.getIndex() instead

		// setters and getters
	void setLit_0( const unsigned int pos );				// sets one bit in IM to 1
	void setLit_1( const unsigned int pos );				// sets one bit in IM to 0
	void setLit_dc( const unsigned int pos );				// sets one bit in IM to dc
	void setLit( const unsigned int pos, const Literal val );
	void setLit( const unsigned int pos, const char val );      // sets one value in the IM
	bool isLit_0( const unsigned int pos ) const;			// is the given IM bit 0?
	bool isLit_1( const unsigned int pos ) const;			// is the given IM bit 1?
	bool isLit_dc( const unsigned int pos ) const;			// is the given IM bit dc?
	Literal getLit2( const unsigned int pos ) const;	// new version. Will replace getLit
	vector<Literal> getCube2(void) const;				// new version. Will replace getCube
	void assign( Literal val );						// assigns a value to all vector items
	void assign( unsigned int size, Literal val );


	// deprecated
    string getCube(void) const { return IM; };
    void setCube( const string val );      // sets IM
    void setCube( const vector<Literal> val );      // sets IM
    char getLit( const unsigned int pos ) const { return IM[pos]; };

    unsigned int getDim(void);
	void setUnwanted(void) { unwanted = true; };
	bool isUnwanted(void) const { return unwanted; };
	unsigned int size(void) const { return IM_data.size(); };		// returns # of term variables
	unsigned int inputs(void) const { return IM_data.size(); };		// returns # of term variables

	void getCoverVector( const bitvector _CoverVector ) { CoverVector = _CoverVector; };
	bitvector *getCoverVector(void) { return &CoverVector; };
	void setSO_CoverVector( const vector<bitvector> _SO_CoverVector ) { SO_CoverVector = _SO_CoverVector; };
	bitvector *getSO_CoverVector( const unsigned int ov ) { return &SO_CoverVector[ov]; };
	vector<bitvector> *getSO_CoverVector() { return &SO_CoverVector; };

    bool intersects( const string &s ) const;				// does it intersect a cube given by a string? 
	bool intersects( const Cube &t ) const;				// does it intersect a cube? 
    bool contains( const string &s ) const;		// does it contain s?
	bool contains( const Cube &t ) const;		// does it contain t?
	Cube intersection( const string &s ) const;				// returns an intersection of two terms. The intersection must exist
	//Cube intersection(  const Cube &t ) const;				// returns an intersection of two terms. The intersection must exist
	int intersectSize( const string &s ) const;
	//int intersectSize( const Cube &t ) const;

	bool And( const string &s ) const;
	bool And( Cube &t );

};

typedef list<Cube> CubeList;

//---------------------------------------------------------------------------
#endif
