//---------------------------------------------------------------------------
#ifndef tboolfnctH
  #define tboolfnctH
//---------------------------------------------------------------------------

struct FnctInfo
{
  int liters;
  int ON_terms;
  int OFF_terms;
  int DC_terms;
  int groupterms;
  int selterms;
  int primes; // # of PIs
  int GEs; // GEs * 2 (!!!)
  int gates;
};
//---------------------------------------------------------------------------
struct PartInfo
{
  int inpsum; // sum of inputs into blocks
  int inpusage; // totaly used inputs
  int branchinps; // branching inputs
  int branchings; // # of input junctions
  int maxload; // maximum load
  float avgload;
};
//---------------------------------------------------------------------------
struct DFTInfo
{
  // DFT
  int conesum;
  int maxcone;
};
//---------------------------------------------------------------------------
struct DecompAss;
class TPfnct;
class TermTree;
//---------------------------------------------------------------------------
class TBoolFnct
{
public:
  int terms; // # of terms
  int inpvars; // # of input variables
  int outvars; // # of outputs
  TBoolFnct * parent; // parent function = source
  char * * inames; // names of input variables
  char * * onames; // names of output variables
  int type; // 1: ON,OFF (fr); 0:ON,DC (fd)

  TPfnct * * onset; // onsets
  TPfnct * * offset; // offsets
  TPfnct * * dcset; // dc-sets

  TPfnct * fnct; // list of terms
  TPfnct * last; // last term

  FnctInfo info;
  int firstpass;

  int hits;
  int tries;

  DecompAss * decomp; // decomposition assignment
  int optval;

  int * onterms; // # of onsets vectors
  int * offterms; // # of offsets vectors
  int * dcterms; // # of dc-sets vectors
  int maxonterms; // maximum of onterms[]

  TPfnct * * index; // array of pointers to terms



private:
  int split; // 1 = splitted function exists
  int tmp;
  int * ffbinds; // flip-flop I/O binds

  PartInfo pinfo;
  DFTInfo dinfo;

  void DuplNames();
  void NameOVars();
  void NameIVars();

public:
  TBoolFnct& operator=(TBoolFnct &_fn);
  TBoolFnct( int iv, int ov, int vct, int tp );
  ~TBoolFnct();
  TBoolFnct * LoadFnct( char * filn, struct TGauge gauge );
  TBoolFnct * CreateChildFnct();
  TBoolFnct * DuplFnct();
  TBoolFnct * DumpOnset( TBoolFnct * e_buffer );
  TPfnct * AddEmptyTermToEnd();
  TPfnct * AddTermToBeginning( char * ivr, char * ovr, int tdim );
  TPfnct * AddTermToEnd( char * ivr, char * ovr, int tdim );
  TPfnct * DeleteTerm( TPfnct * ff, TPfnct * pff );
  void DeleteTerm( int t );
  int SaveFnct( char * filn, struct TGauge gauge, bool savevarnames );
  void SaveFnctAsSymbols( char * filn, TGauge gauge, struct Notation not );
  void SaveFnctAsHTML( char * filn, TGauge gauge );
  void SaveFnctAsVHDL( char * filn, TGauge gauge, int limit );
  void SaveFnctAsVHDL2( char * filn, TGauge gauge, int limit );
  void SaveFnctAsVerilog( char * filn, TGauge gauge );
  void SaveFnctAsVerilog2( char * filn, TGauge gauge );
  void SaveFnctAsBLIF( char * filn, TGauge gauge );
  void SaveFnctAsBLIF_POS( char * filn, TGauge gauge );

  void NameVars()
  {
    this->NameIVars(); this->NameOVars();
  };

  void JoinFnct( TBoolFnct * srcf );
  void FillEmptyFnct();
  void GetInfo();
  char * FunctToSymbols( int ovr, Notation not );
  void DeleteInvalidTerms();
  void SplitFnct();
  int GetDim( char * ivr );
  int AdvCountPrimes( int mask, int IC_memory, int IC_type,  TermTree ** imp_test, TermTree ** offtree );
  int CountFnctHamming( char * c );
  void NullFFBinds();

  void IsolateFunction()
  {
    this->DuplNames(); this->parent = 0;
  };

  void DeleteInpVariable( int v );
  void DeleteOutVariable( int v );
  void InsertTerm( int t );
  void InsertInpVariable( int v );
  void InsertOutVariable( int v );
  void SubstOutDCs();
  void DeleteSplit();
  void DeleteNames();
  void GetOptVal( int crit );
  void Reindex();
  char * IsPrime( TPfnct * ff, int IC_memory, int IC_type,  TermTree ** imp_test, TermTree ** offtree );
  void SwapOnOff();
};
//---------------------------------------------------------------------------
TBoolFnct * Minimize( TBoolFnct * srcf );
TBoolFnct * OneFCMinStep( TBoolFnct * srcf, TBoolFnct * allf );
TBoolFnct * OneMinStep( TBoolFnct * srcf, TBoolFnct * allf );
//---------------------------------------------------------------------------
#endif
