// ========================================================= //
//                                                           //
//   File      : calculator.h                                //
//   Purpose   : perform SAI calculation                     //
//                                                           //
//   Coded by Ralf Westram (coder@reallysoft.de) in Dec 19   //
//   http://www.arb-home.de/                                 //
//                                                           //
// ========================================================= //

#ifndef CALCULATOR_H
#define CALCULATOR_H

#ifndef SAIOP_H
#include "saiop.h"
#endif
#ifndef ARBDB_H
#include <arbdb.h>
#endif

enum SaiAliScope {
    SAS_SELECTED, // apply to selected alignment
    SAS_ALL,      // apply to all existing alignments
    SAS_COMMON,   // all alignments common for all input SAI
    SAS_TARGET,   // existing target alignments
    // (avoid changing order! int is saved to config)
};

class SaiCalculator : virtual Noncopyable {
    GBDATA              *gb_main;
    const CharPtrArray&  inputSaiNames;
    const SaiOperator&   op;
    const char          *outSaiName;
    SaiAliScope          scope;
    ARB_ERROR            error;

    void run();
    void calc4ali(const char *ali, GBDATA *gb_target_sai);
    bool allSaiHaveDataInAlignment(const char *ali);

public:
    SaiCalculator(GBDATA *gb_main_, const CharPtrArray& inputSaiNames_, const SaiOperator& op_, const char *outSaiName_, SaiAliScope scope_) :
        gb_main(gb_main_),
        inputSaiNames(inputSaiNames_),
        op(op_),
        outSaiName(outSaiName_),
        scope(scope_)
    {
        GB_transaction ta(gb_main);
        run();
        error = ta.close(error);
    }

    bool hasError() const {
        if (error) return true;
        error.expect_no_error();
        return false;
    }
    ARB_ERROR getError() const {
        return error;
    }
};


#else
#error calculator.h included twice
#endif // CALCULATOR_H
