//---------------------------------------------------------------------------
//  Represent bits states
//---------------------------------------------------------------------------
#ifndef QBITS_H
#define QBITS_H
//---------------------------------------------------------------------------
#include <iostream>
#include <sstream>
#include <stdio.h>
#include <string.h>

using namespace std;

class QResultInfo{
public:
    char header[4];
    char filename[256];
    int bitnumber;
    QResultInfo(void)
    {
        header[0] = 'q';
        header[1] = 'd';
        header[2] = 'a';
        header[3] = 't';
        bitnumber = 0;
        for (int i=0;i<256;i++)
        {
            filename[i] = 0;
        }
    }
};

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

class QBits
{
    friend std::ostream &operator<<(std::ostream &os, const QBits &qb);
    friend std::ostream &operator<<(std::ostream &os, const QBits *qb);

public:
    QBits(void);
    QBits(const int n);
    QBits(char * filename);
    QBits(const QBits &qubits);
    ~QBits();

    void Init(void);
    bool Allocate(int n);
    int    GetNumberOfQBits(void)  const {
        return mNumberOfQbits;
    }
    int    GetNumberOfStates(void) const {
        return mNumberOfStates;
    }
    void   Measure(int index){
        mMeasured[index] = true;
    };
    bool   isMeasured(int index){
        return mMeasured[index];
    };
    int    GetNumberOfMeasured(void);
    string GetMeasuredString(int index);


    double &NthStateR(const int nth) const;
    double &NthStateI(const int nth) const;
    double *GetBitsR(void) {
        return mBitsR;
    }
    double *GetBitsI(void) {
        return mBitsI;
    }
    double GetAbsoluteValue(int index);
    double GetMeasuredValue(int index);

    void PerformMeasurement(void);
    void SaveMeasurementToStream(ostream &os);

    void LoadFromFile(const char *filename);
    void SaveToFile(const char *filename);
    void SaveAsText(const char *filename);
    void SaveToStream(ostream &ss);
    bool IsValid(void){
        return bValid;
    };

private:

    bool bValid;
    int mNumberOfQbits;  //n
    int mNumberOfStates; //2^n
    double *mBitsR;         //Re
    double *mBitsI;         //Im

    double *mBitsM;// Measured Values

    bool *mMeasured; //Measured Flag

};

std::ostream &operator<<(std::ostream &os, const QBits &qb);
std::ostream &operator<<(std::ostream &os, const QBits *qb);
//---------------------------------------------------------------------------
#endif //QBITS_H
