//     HTQC - a high-throughput sequencing quality control toolkit
//
//     This program is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
//
//     This program is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
//
//     You should have received a copy of the GNU General Public License
//     along with this program.  If not, see <http://www.gnu.org/licenses/>.


#ifndef HTQC_BASEQUALCOUNTER_H
#define HTQC_BASEQUALCOUNTER_H

#include "htqc/Common.h"

namespace htqc
{

class BaseCounter
{
public:

    BaseCounter(): a(0), t(0), g(0), c(0), n(0), mask(0) { }
    long a;
    long t;
    long g;
    long c;
    long n;
    long mask;

    BaseCounter& operator+=(const BaseCounter& other);
};

class TileQualCounter
{
public:

    TileQualCounter()
    : num_reads_10(0)
    , num_reads_10_20(0)
    , num_reads_20_30(0)
    , num_reads_30(0) { }

    inline void record(int qual)
    {
        if (qual < 10) num_reads_10++;
        else if (qual < 20) num_reads_10_20++;
        else if (qual < 30) num_reads_20_30++;
        else num_reads_30++;
    }
    long num_reads_10;
    long num_reads_10_20;
    long num_reads_20_30;
    long num_reads_30;
    TileQualCounter& operator+=(const TileQualCounter& other);
};

typedef struct
{
    int dec_low;
    int quat_low;
    int median;
    int quat_high;
    int dec_high;
    float mean;
} BaseQualBoxChart;

class BaseQualCounter
{
public:

    BaseQualCounter(htio2::QualityEncode encode);

    inline void record(int qual)
    {
        int key = qual - from;
        if (key > key_max || key < 0)
        {
            char err_msg[2048];
            std::sprintf(err_msg, "invalid quality: %d (key %d), valid range %d - %d", qual, key, from, to);
            throw std::runtime_error(std::string(err_msg));
        }
        counter[key]++;
    }

    inline long get_num(int qual) const
    {
        int key = qual - from;
        return counter[key];
    }

    void create_chart(BaseQualBoxChart& chart) const;

    BaseQualCounter& operator+=(const BaseQualCounter& other);

protected:
    std::vector<long> counter;

    int key_max;
    int16_t from;
    int16_t to;
};

}

#endif // HTQC_BASEQUALCOUNTER_H
