#ifndef _FRAGMENTATION_MATH_H
#define _FRAGMENTATION_MATH_H
#ifdef FOTA

#include "mbed.h"
#include "mDot.h"
#include "WriteFile.h"

#define FRAG_SESSION_ONGOING    0xffffffff
#ifndef MAX_PARITY
#define MAX_PARITY 300
#endif
class FragmentationMath
{
  public:
    FragmentationMath(mDot* dot, uint16_t frame_count, uint8_t frame_size, WriteFile* fh);
    ~FragmentationMath();
    bool Init();
    int getLostFrameCount();
    void reset(uint16_t fcount);
    void setFrameFound(uint16_t frameCounter);
    bool processParityFrag(uint16_t frameCounter, uint8_t *pFrag);

    int FragmentationPrbs23(int x);
    bool IsPowerOfTwo(unsigned int x);
    int32_t FindMissingFrameIndex(uint16_t x);
    int32_t FindTrueFrameIndex(uint16_t x);
    void GetRowInFlash(int l, uint8_t *rowData);
    int FindFirstOne(uint8_t *boolData, int size);
    void StoreRowInFlash(uint8_t *rowData, int index);
    void XorLineData(uint8_t *dataL1, uint8_t *dataL2, int size);
    void XorLineBit(uint8_t *dataL1, uint8_t *dataL2, int size);
    void XorRowWithMatrix(uint8_t* row, int matrix_row_num);
    void FragmentationGetParityMatrixRow(int N, int M, uint8_t *matrixRow);
    void CondenseRow(uint8_t *row, int row_number, int start);
    void ExpandAndXorRow(uint8_t *row, int row_number);
    bool CheckIfMissing(int row_number, int index);
    void CompleteRow(int row_num);
    void printMatrix();

    uint8_t _frame_size;
    uint16_t _frame_count;
    uint16_t _max_parity;
    uint16_t numFramesMissing;
    uint16_t lastReceiveFrameCnt;

    uint8_t *matrix;
    uint8_t *matrixRow;
    uint8_t *parity_frag;
    uint8_t *missingFrameIndex;
    uint8_t *frag_in_flash;

    bool empty;
    int index_of_first;
    int matrix_row_num;
    int index;

    mDot* _dot;
    WriteFile* _fh;
};
#endif
#endif // _FRAGMENTATION_MATH_H
