// This file is part of the FXT library.
// Copyright (C) 2010 Joerg Arndt
// License: GNU General Public License version 3 or later,
// see the file COPYING.txt in the main directory.

#include "graph/digraph-paths.h"
#include "graph/digraph.h"

#include "aux0/swap.h"
#include "aux0/factorial.h"
#include "comb/num2perm.h"  // perm2num(), num2perm()
#include "perm/perminvert.h"

#include "sort/minmaxmed23.h"
#include "sort/sort.h"

//#include "comb/perm-trotter2.h"

#include "fxttypes.h"
#include "jjassert.h"


static inline void j_swap(ulong *x, ulong *i, ulong c)
{
#if 0  // star transpositions:
    ulong i0 = 0,  i1 = c;
    ulong x0 = x[i0],  x1=x[i1];
    swap2(x[i0], x[i1]);
    swap2(i[x0], i[x1]);
#else // adjacent transpositions:
//    swap2(x, i);
    ulong x0 = x[c],  x1=x[c-1];
    ulong i0 = i[x0], i1=i[x1];
    swap2(x[i0], x[i1]);
    swap2(i[x0], i[x1]);
#endif
}
// -------------------------

digraph *
make_perm_gray_digraph(ulong n)
// Initialization for directed graph:
// Gray code graph permutations of n elements with adjacent changes.
{
    ulong ng = factorial(n);

    ulong ne = ng * (n-1);  // number of edges
    ulong *ep, *e;
    digraph * dgp = new digraph(ng, ne, ep, e);

//    perm_trotter2 P(n);  P.first();
//    const ulong *x = P.data();

    ulong xx[32];  // aux: permutations
    ulong yy[32];  // aux: inverse permutations
    ulong p = 0;
    for (ulong k=0; k<ng; ++k)  // for all nodes
    {
        ep[k] = p;

        num2perm_ffact(k, xx, n);

//        for (ulong j=0;  j<n;  ++j)  xx[j] = x[j];  // copy permutation
//        P.next();

        make_inverse(xx, yy, n);
        for (ulong j=1;  j<n;  ++j)
        {
//            swap2(xx[j], xx[j-1]);  // adjacent transposition
            j_swap(xx, yy, j);

            ulong vc = perm2num_ffact(xx, n);
            e[p++] = vc;

//            swap2(xx[j], xx[j-1]);  // undo transposition
            j_swap(xx, yy, j);
        }
    }
    ep[ng] = p;

    return  dgp;
}
// -------------------------

