//---------------------------------------------------------------------------
// Swap gate
//---------------------------------------------------------------------------
#include "QC_swap.h"
//---------------------------------------------------------------------------

/**
 *  Constructor
 */
QC_swap::QC_swap(int target1,int target2) : QCalcUnit() {
    TargetBit1 = target1;
    TargetBit2 = target2;
}
//---------------------------------------------------------------------------
/**
 *  Calculation
 */
void QC_swap::calc(int target1, int target2,
                   double BitsR[], double BitsI[], int NumberOfBits) {
    unsigned int states = (1 << (NumberOfBits - 2));
    // Sort Bits to regular order of bit index
    int Bit0 = target1;
    int Bit1 = target2;
    if (Bit0 > Bit1) {
        QCalcUnit::swap(Bit0, Bit1);
    }

    for (unsigned int i = 0; i < states; i++) {
        unsigned int ix1 = insert1(i,   Bit0);
        ix1 = insert0(ix1, Bit1);
        unsigned int ix2 = insert0(i,   Bit0);
        ix2 = insert1(ix2, Bit1);

        QCalcUnit::swap(BitsR[ix1], BitsR[ix2]);
        QCalcUnit::swap(BitsI[ix1], BitsI[ix2]);
    }
}
//---------------------------------------------------------------------------
void QC_swap::Calc(QBits *qBits)
{
    int N = qBits->GetNumberOfQBits();
    double *R = qBits->GetBitsR();
    double *I = qBits->GetBitsI();

    QC_swap::calc(TargetBit1, TargetBit2, R, I, N);
}
//---------------------------------------------------------------------------
#ifdef __USE__MPI
void
QC_swap::calcmpi(int t1, int t2, double R[], double I[], int N) {
    // Sort Bits to regular order of bit index
    int Bit0 = t1;
    int Bit1 = t2;
    if (Bit0 > Bit1) {
        QCalcUnit::swap(Bit0, Bit1);
    }

    double r0 = 0.0;
    double i0 = 0.0;
    double r1 = 0.0;
    double i1 = 0.0;
    unsigned int ix0, ix1;

    printf("Swap Gate has not been implemented yet.\n");
//TODO:
    /*
      for (int i = 0; i < (1 << (N - 2)); i++)
        {
          // Obtain indices of state:
          unsigned int ix1 = insert1(i,   Bit0);
                       ix1 = insert0(ix1, Bit1);
          unsigned int ix2 = insert0(i,   Bit0);
                       ix2 = insert1(ix2, Bit1);

          bool bstore = setup(R, I, ix0, ix1, r0, i0, r1, i1);
          if (bstore) {
            // Calc:
            QCalcUnit::swap(r0, r1);
            QCalcUnit::swap(i0, i1);
            // Store:
            store(R, I, ix0, ix1, r0, i0, r1, i1);
          }
        }
    */
}
#endif
//---------------------------------------------------------------------------
