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

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

class motzkin_path_lex
// Motzkin paths in lexicographic order, CAT algorithm.
{
public:
    ulong *a_;
    ulong n_;

public:
    motzkin_path_lex(ulong n)
    // Must have n>=1.
    {
        n_ = n;
        a_ = new ulong[n+2];
        a_[0] = 0;
        ++a_;  // nota bene
        a_[n_] = 0;

        first();
    }

    ~motzkin_path_lex()
    {
        --a_;
        delete [] a_;
    }

    void first()
    {
        for (ulong j=0; j<n_; ++j)  a_[j] = 0;
    }

    ulong next()
    {
#if 1  // "easy case" optimization:
        ulong j = n_ - 1;
        if ( a_[j] == 0 )  // easy case
        {
            a_[j] = 1;
            return j;
        }

        a_[j] = 0;
        --j;
        ulong m = 2;
#else
        ulong j = n_ - 1;
        ulong m = 1;
#endif

        while ( a_[j] == m )
        {
            a_[j] = 0;
            ++m;
            --j;
        }

        while ( a_[j] > a_[j-1] )
        {
            a_[j] = 0;
            --j;
        }

        if ( j==0 )   return 0;  // current is last

        const ulong i = j;
        ulong v = a_[j] + 1;
        do
        {
            a_[j] = v;
            --v;
            ++j;
        }
        while ( v );

        return i;
    }

    const ulong * data()  const  { return a_; }

    void print(const char *bla, bool dfz=false)
    {
        print_vec(bla, a_, n_+1, dfz);
    }
};
// -------------------------


#endif  // !defined HAVE_MOTZKIN_PATH_LEX_H__
