/*******************************************************************/
/*                                                                 */
/*  MODULE   generate                                              */
/*  PROGRAM  SFST                                                  */
/*  AUTHOR   Helmut Schmid, IMS, University of Stuttgart           */
/*                                                                 */
/*  PURPOSE  prints automata                                       */
/*                                                                 */
/*******************************************************************/

#include "fst.h"

using std::vector;

namespace SFST {

/********************  Gen  ***************************************/

class Gen {
public:
  Node *node;
  Index previous;
  Label label;

  Gen(Node *n, Label l = Label::epsilon, Index p = undef)
      : node(n), previous(p), label(l) {}

  void print(vector<Gen> &paths, FILE *file, Alphabet &alphabet,
             OutputType ot) {
    if (previous != undef) {
      paths[previous].print(paths, file, alphabet, ot);
      if (ot == Joint)
        fputs(alphabet.write_label(label).c_str(), file);
      else if (ot == UpperOnly) {
        if (label.upper_char() != Label::epsilon)
          fputs(alphabet.write_char(label.upper_char()).c_str(), file);
      } else if (ot == LowerOnly) {
        if (label.lower_char() != Label::epsilon)
          fputs(alphabet.write_char(label.lower_char()).c_str(), file);
      }
    }
  }
};

/*******************************************************************/
/*                                                                 */
/*  Transducer::generate                                           */
/*                                                                 */
/*******************************************************************/

void Transducer::generate(FILE *file, int max, OutputType ot)

{
  vector<Gen> paths;
  paths.push_back(Gen(root_node()));

  int n = 0;
  for (size_t i = 0; i < paths.size(); i++) {
    // fprintf(stderr,">>> %lu\n", i);
    Gen &gen = paths[i];
    Node *node = gen.node;
    if (node->is_final()) {
      if (ot == Both) {
        gen.print(paths, file, alphabet, UpperOnly);
        fputc('\t', file);
        gen.print(paths, file, alphabet, LowerOnly);
      } else
        gen.print(paths, file, alphabet, ot);
      fputc('\n', file);
      if (++n == max)
        return;
    }

    for (ArcsIter p(node->arcs()); p; p++) {
      Arc *arc = p;
      paths.push_back(Gen(arc->target_node(), arc->label(), (Index)i));
    }
  }
}
} // namespace SFST
