// ..
//  Copyright (c) 1996-1998 University Freiburg, Computer Science Departement
// 
//  Project:  HsfLight - Heuristic Search Framework Light
//             
//  See file README for information on using and copying this software.
// 
//  Module:   /home/edelkamp/cdot/alg/hsfLight/include/moves.h
//  Author:   Stefan Edelkamp
//  eMail:    edelkamp@informatik.uni-freiburg.de 
//  WWW:      http://www.informatik.uni-freiburg.de/edelkamp/~hsfLight
// ..

#ifndef MOVES_H
#define MOVES_H

//#include <iostream.h>

// Moves are used to describe transition sequences or strings. 
// Especially, the connection of duplicate and its shortcut(s)
// is provided.

class Moves {
private:
  int len;                    // the length of the move
  int* a;                     // the array of single operators
  Moves* shortcut;            // shortcut provided for a given sequence
  Moves* pred;                // pred in double ended list structure
  Moves* succ;                // succ in double ended list structure

public:
  Moves::Moves();
  Moves::Moves(int _len);
  Moves(int _len, int* _a);
  Moves(int l, int c);
  Moves(const Moves& m);
  ~Moves();
  Moves& operator=(const Moves& m);
  operator>(const Moves& m);

  add(Moves* m, int sigma);
  interval(int begin, int end, int* _a);

  get_length() {return len;}
  set_length(int l) {len = l;}
  val(int i) {return a[i];}
  set_val(int i, int j) { a[i]=j; }
  set_shortcut(Moves* m) { shortcut = m; } //shortcut = new Moves(*m); }
  clear_shortcut() { shortcut = 0; } //shortcut = new Moves(*m); }
  Moves* get_shortcut() { return shortcut; }
  Moves* get_pred() { return pred; }
  Moves* get_succ() { return succ; }
  set_pred(Moves* p) { pred= p; } 
  set_succ(Moves* s) { succ= s; }

  print() const;
  //friend ostream& operator<<(ostream& os, const Moves& m) { m.print(); }
};

// Submoves are intervals of a referred move, 
// s.t. the representation for a submove needs only O(1) space !

class Submove {

private:
  int f;               // start of the interval (first index)
  int l;               // end of the interval (last index)
  Moves* s;            // only for output

public:
  Submove(); 
  Submove(Moves* m);
  Submove(const Submove& m);
  Submove(int first, int last, Moves* m);

  set_Moves(Moves* m) { s = m; }
  Moves* get_Moves()  {return s; }
  int get_first()  { return f; }
  int get_last()   { return l; }
  set_first(int first)   { f = first; }
  set_last(int last)    { l = last; }
  int get_length() { return l - f + 1; }

  Moves* extract_Moves();
  int IsEmpty() const;
  Empty();
  print() const;
  
  //friend ostream& operator<<(ostream& os, const Submove& m)  { m.print(); }

};

#endif //
