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

#ifndef CoverH
#define CoverH
//---------------------------------------------------------------------------

class CoverOpts {
	friend class Cover;
	friend class LagBaBCover;
	private:
		unsigned int lagrange_total_iter;
		unsigned int lagrange_iter;
		unsigned int lagrange_iter_dual;
		unsigned int lagrange_heur_iter;
		unsigned int dominance;
		float lagrange_init_coef;
		float lagrange_min_coef;
		float lagrange_init_coef_dual;
		float lagrange_min_coef_dual;
		bool lagrange_simple_dual;
		bool run_lag;
		bool use_contribAdd;
		bool use_servit;
		char *matrixFile;

	public:
		void SetLagTotalIter( const unsigned int i ) { lagrange_total_iter = i; };
		void SetLagIter( const unsigned int i ) { lagrange_iter = i; };
		void SetLagHeurIter ( const unsigned int i ) { lagrange_heur_iter = i; };
		void SetLagInitCoef ( const float i ) { lagrange_init_coef = i; };

		void SetLagDualIter( const unsigned int i ) { lagrange_iter_dual = i; };
		void SetLagDualInitCoef ( const float i ) { lagrange_init_coef_dual = i; };
		void SetLagDualMinCoef ( const float i ) { lagrange_min_coef_dual = i; };

		void SetLagMinCoef ( const float i ) { lagrange_min_coef = i; };
		void SetLagSimpleDual ( const unsigned int i ) { if(i>0) lagrange_simple_dual=true; else lagrange_simple_dual=false; };
		void SetLagSimpleDual ( const bool i ) { lagrange_simple_dual=i; };
		void SetMatrixFile ( char* c ) { matrixFile=c; };
		void SetRunLag(const bool i) { run_lag=i; };
		void SetDominance(const unsigned int i) { dominance=i; };
		void SetContribAdd(bool ca) { use_contribAdd = ca;};
		void SetServit(bool se) { use_servit = se;};

		CoverOpts(void);
		~CoverOpts(void) {};
};

class Cover {
    private:
        PLA *source;                 // source PLA. Must not be modified
        PLA *implpool;              // implicant pool. Here Cover processes the pool

    public:
        Cover( PLA *_source, PLA *_implpool );
        ~Cover(void) {};

        void GenerateOM(void);			// Generates OM values in the implicant pool (only from void "~" values)
		void RemoveAbsorbedByCover(void);					// removes absorbed terms by comparing their covers
		void GenerateCoverVector( Term &t );
		void GenerateCoverVectors(void);
		
		PLA *Run(CoverOpts* options);			// Runs the CP. Returns new PLA as a solution (
		PLA *Run(void);							// Runs the CP. Returns new PLA as a solution
		void Sparse_output( PLA *pla );		// Removes unnecessary 1's from the output matrix
};
#endif
