#include <string>
#include <ostream>
#include <iostream>
#include <fstream>

class Cbr
{

public:
struct a_case {
    long case_nr;
    long nr_of_objects;
    long largest_object;
    double avg_object;
    double avg_intensity;
    double change_intensity;
    double weight_nr_of_objects;
    double weight_largest_object;
    double weight_avg_object;
    double weight_avg_intensity;
    double weight_change_intensity;
    int alarm_situation; // 0 if not alarm, 1 if alarm
    std::string textual;
};

/**
*   Method that supervises the retrieve stage of cbr.
*
*   @param thenewcase The new case presented to the system.
*/
void Retrieve(struct a_case thenewcase);
/**
*   Method that reads all cases from Database file and puts them in an array.
*
*   
*/
void ReadCasesFromDB();
/**
*   Methods that decides what to do when an alarm is raised, or when an alarm is not raised.
*
*   @param alarm A value to specify if an alarm is to be raised or not.
*/
void RaiseAlarm(int alarm);
/**
*   Method that compares the resemblence between the new case and the retrieved case, without taking weights into account.
*
*   @param firstcase The first case that is to be compared.
*   @param secondcase The second case that is to be compared.
*/
double CompareCasesReuse(struct a_case firstcase, struct a_case secondcase);
/**
*   Method that compares the resemblence between the new case and all cases in the case database, taking weights into account.
*   This method finds the three best cases that resembles the new case best.
*
*   @param thenewcase The case that is to be compared with the cases in the case base.
*   @param best The best matching case.
*   @param second The second best matching case.
*   @param third The third best matching case.
*/
void CompareCasesRetrieve(struct a_case thenewcase, int* best, int* second, int* third);
/**
*   Method to add a new case to the case array.
*
*   @param thenewcase The new case which is to be added to the database.
*/
void AddNewCase(struct a_case thenewcase);
/**
*   Method that updates the database file, i.e. writes the database file with the new data.
*
*/
void UpdateDataBase();
/**
*   Method that controls the revise stage of cbr.
*
*   @param thenewcase The new case presented to the system.
*   @param oldcaseindex The position of the best matching case in the case array.
*   @param second The position of the second best matching case in the case array.
*   @param third The position of the third best matching case in the case array.
*   @param args A veriable that is used to determine when revise is sucessfull.
*   @param args A veriable that is used to determine if revise is sucessfull.'
*   @retrun The args value.
*/
int Cbr::Revise(struct a_case thenewcase, int oldcaseindex, int second, int third, int args, int* found);
/**
*   Method that controls the reuse stage of cbr.
*
*   @param thenewcase The new case presented to the system.
*   @param oldcaseindex The position of the best matching case in the case array.
*   @param second The position of the second best matching case in the case array.
*   @param third The position of the third best matching case in the case array.
*/
void Cbr::Reuse(struct a_case thenewcase, int oldcaseindex, int second, int third);
/**
*   Method that update the weights for the retrieved case according to some parameters.
*
*
*   @param args A variable which tells the method if cbr was succesfull or not.
*   @param thenewcase The new case presented to the system.
*   @param oldcaseindex The position of the retrieved case in the case array.
*/
void UpdateWeight(int args, struct a_case thenewcase, int oldcaseindex);
/**
*   Method that controls the retain stage of cbr.   
*
*   @param args A variable which tells the method if cbr was succesfull or not.
*   @param thenewcase The new case presented to the system.
*   @param oldcaseindex The position of the best matching case in the case array.
*   @param second The position of the second best matching case in the case array.
*   @param third The position of the third best matching case in the case array.
*/
void Cbr::Retain(int args, struct a_case thenewcase, int oldcaseindex, int second, int third);

};