#if !defined HAVE_PERM_STAR_SWAPS_H__
#define      HAVE_PERM_STAR_SWAPS_H__

#include "aux0/swap.h"
#include "comb/comb-print.h"
#include "fxttypes.h"

class perm_star_swaps
// Permutations in star-transposition order (a Gray code).
// Compute swaps only.
// Algorithm of Gideon Ehrlich, as given by Knuth
{
public:
    ulong n_;    // number of elements
    ulong swp_;  // index of element that was swapped (with index 0)
    ulong *b_;   // auxiliary array
    ulong *c_;   // auxiliary array

public:
    perm_star_swaps(ulong n)
    {
        n_ = n;
        b_ = new ulong[n_];
        c_ = new ulong[n_+1];
        first();
    }

    ~perm_star_swaps()
    {
        delete [] b_;
        delete [] c_;
    }

    void first()
    {
//        swp_ = n_ - 1;
        swp_ = 0;
        for (ulong k=0; k<n_; ++k)  b_[k] = k;
        for (ulong k=0; k<=n_; ++k)  c_[k] = 0;
    }

    bool next()
    {
        ulong k = 1;
        if ( c_[k] == k )
        {
            do
            {
                c_[k] = 0;
                ++k;
            }
            while ( c_[k] >= k );
        }

        if ( k == n_ )   return false;

        ++c_[k];
        swp_ = b_[k];

        ulong j = 1;
        --k;
        while ( j < k )  // < 0.18 iterations per call
        {
            swap2(b_[j], b_[k]);
            ++j;
            --k;
        }
        return  true;
    }

    ulong get_swap()  const  { return swp_; }
    void get_swap(ulong &s1, ulong &s2)  const  { s1=0; s2=swp_; }
};
// -------------------------



#endif  // !defined HAVE_PERM_STAR_SWAPS_H__
