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

#ifndef AuraCoverH
#define AuraCoverH

//structure, where is kept linkt to set of columns included to solution
struct header_of_solution_UCP {
  long Cost;
  struct CLink *SetC;//Link to set of columns
};

//structure to keep domains of covering matrix for Aura 
struct Domain {
  struct CLink *SetC;
  int cheapestColumn;
  int numberOfRow;
  int countOfCols;
  struct Domain *Next;
  struct Domain *Previous;
};

struct cube {
  
  struct Domain *link_To_Domain;
  int counfOfDomain;
  int countOfCheapestCols;
  struct cube *Next;
};

struct header_Of_Cubes {
  
  struct cube *link_To_Cube;
  int countOfCubes;
  
};

//structure, where is kept linkt to set of rows included to MSIR

struct header_Of_Set_MSIR {
   struct set_Of_Rows_MSIR *RowsLink;
   int MSIR;
};

//structure where are kept row links an column links
struct CLink {
   struct CLink *Previous;
   struct CLink *Next;
   int ID;
   int Offset; //Offset to jump from one item to next
   int Cost;
   int NumberOf1;
   };

//Structure where is kept the matrix
struct CoveringMatrix {
  struct CLink *RowLink;  //Link to rows of matrix
  struct CLink *ColLink;  //Link to columns of matrix
  long Cost;
  int Dirty;
  int countOfCols;        //countOfCols je pocet sloupcu
  int countOfRows;		 //countOfRows je pocet radku + 1, (1 pro uchovani cen sloucu)
  int MSIR;			//pridano pro tvoreni doplnkove matice MSIR k matici, kde radky MSIR chybi
  int countOfOnes;
  char * *Array;    //Matice
  int lbound;
};

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

class AuraCover {
	private:

   long uBound;		// = 0 (if it is static)
   long MaxCost;
   int MaxRunTime;
   long NumCalls;
   float StartTime,StopTime;
   int maxRaiser;
   int parameterN;
   bool stopCover;
   int callUpperBound;

	float GetMyCPUTime();
	void print_Matrix ( struct CoveringMatrix *CM );
	void Release (struct CoveringMatrix * CM);
	void Release ( struct header_of_solution_UCP *SolUCP );
	struct header_of_solution_UCP *create_New_Empty_Solution ( void );
	void AppendSolution (struct header_of_solution_UCP *Source,struct header_of_solution_UCP *Target );
	void Replace_Solution (struct header_of_solution_UCP *Source,struct header_of_solution_UCP *Target );
	void AddToSolution ( struct header_of_solution_UCP *SolutionUCP,struct CLink *Column );
	void remove_Col_From_Matrix ( struct CoveringMatrix *CM, struct CLink *colToRemove );
	void remove_Col_From_Matrix ( struct CoveringMatrix *CM, int ID );
	void remove_Row_From_Matrix ( struct CoveringMatrix *CM, struct CLink *rowToRemove );
	void RemoveColWithRows ( struct CLink * Column, struct CoveringMatrix *CM );
	struct CoveringMatrix* Duplicate ( struct CoveringMatrix *CM);
	void create_Matrix ( struct CoveringMatrix *Cm,int *Costs );
	void FindNumberOf1 ( struct CoveringMatrix *CM );
	void R_Dominance ( struct CoveringMatrix *CM,struct header_of_solution_UCP *SolutionUCP );
	void S_Dominance ( struct CoveringMatrix *CM);
	int SolveDominance ( struct CoveringMatrix *CM,struct header_of_solution_UCP *SolutionUCP );
	struct cube * create_Empty_Cube ( void );
	struct header_Of_Cubes * create_Empty_Header_Cube ( void );
	struct Domain * InitDomain (  int numberOfRow );
	void remove_Col_From_Domain (struct Domain *domain, int required_Col_ID );
	void add_Col_To_Domain ( struct Domain *domain, struct CLink *Column ); 
	void find_Cols_Covering_Row (  struct CoveringMatrix *CM, struct CLink *SelectedRow, struct Domain *SelectedRowDomain );
	void Release ( struct cube *cube_of_Matrix );
	void Release (struct header_Of_Cubes *header);
	void Release ( struct Domain* Aux_Domain);
	void Release ( struct CLink* Pomocny_SetC);
	void add_Row_To_Matrix (struct CoveringMatrix *CM, struct CLink *RowLink);
	struct Domain * copy_Domain (struct Domain *source_Domain);
	void add_Domain_To_Cube ( struct cube *cube_of_Matrix,struct Domain* source_Domain);
	void add_Cube_To_Header ( struct header_Of_Cubes *header, struct cube *cube_of_Matrix);
	void find_Cube_Of_Matrix ( struct CoveringMatrix *CM, struct cube *cube_of_Matrix);
	struct Domain * make_Domain_Intersection ( struct CLink *Domain_Row1, struct CLink *Domain_Row2);
	struct Domain  * make_Difference_Domain ( struct CLink *Domain_Row2, struct CLink *Domain_Row1);
	int evaluate_Row (struct CoveringMatrix *CM,struct CLink *PomocnyRadek);
	struct CoveringMatrix * create_Matrix_Of_Rows_MSIR ( struct CoveringMatrix *original_Matrix,struct CoveringMatrix *original_Matrix_Without_MSIR);
	int FindMSIR ( struct CoveringMatrix *CM,int MSIR );
	float evaluate_Column (struct CoveringMatrix *CM,struct CLink *AuxiliaryCol);
	struct CLink* select_Col_Contrib (struct CoveringMatrix *CM);
	int select_Best_Uncovered_Row ( struct CoveringMatrix *matrix_Without_MSIR ,struct cube *cube_Of_Matrix_MSIR);
	int Add_Set_Of_1intersecting_Rows (struct CoveringMatrix *matrix_Without_MSIR,struct cube *cube_Of_Matrix_MSIR,int Still_To_Raise);
	struct CoveringMatrix * find_Best_Set_Of_Non_Intersecting_Rows (struct CoveringMatrix *matrix_Without_MSIR,struct cube *cube_Of_Matrix_MSIR);
	int found_Solution (struct CoveringMatrix *CM,struct cube *cube_of_Matrix,struct header_of_solution_UCP *SolUCP,int Path);
	struct cube * Split_Domain ( struct CoveringMatrix *Matice_MSIR,struct CoveringMatrix *matrix_Without_MSIR,struct cube *cube_Of_Matrix_MSIR,struct Domain *domain_Of_Selected_Row);
	int Raiser (  struct CoveringMatrix *CM,struct CoveringMatrix *Matice_MSIR,struct CoveringMatrix *matrix_Without_MSIR,struct cube *cube_Of_Matrix_MSIR,int lbound,struct header_of_solution_UCP *SolUCP,int Omezit_Cas);
	int BABAURA2 ( struct CoveringMatrix *CM,struct header_of_solution_UCP *SolUCP,int Omezit_Cas );
	void Set_Max_Raiser (struct CoveringMatrix *Cm);
	struct CoveringMatrix *RebuildMatrix (CovMatrix *CVM);
	
	list<unsigned int> Rebuild_Solution (struct header_of_solution_UCP *SolutionUCP);
	
  list<unsigned int> Solution;///toto jsem pridal, funkce rebuild_solution sem prida cisla sloupcu reseni
  struct CoveringMatrix *CM;//toto jsem pridal, struktura kam se kopiruje vase matice
  struct header_of_solution_UCP *SolutionUCP;//toto jsem pridal, pomocny seznam, potrebny pro beh mych funkci
	public:
	
		AuraCover( CovMatrix *_matrix );
		~AuraCover();

		list<unsigned int> Run();

};

#endif
