/*
 * Interpreter.h - class definition for l-system interpreter.
 *
 * Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
 *                     University of Berne, Switzerland
 * All rights reserved.
 *
 * This software may be freely copied, modified, and redistributed
 * provided that this copyright notice is preserved on all copies.
 *
 * You may not distribute this software, in whole or in part, as part of
 * any commercial product without the express consent of the authors.
 *
 * There is no warranty or other guarantee of fitness of this software
 * for any purpose.  It is provided solely "as is".
 *
 */

#ifndef Interpreter_H
# define Interpreter_H

#include "Value.h"
#include "Polygon.h"
#include "DeviceDriver.h"
#include "Module.h"
#include "Turtle.h"
#include "Hull.h"
#include "Options.h"

//___________________________________________________________ Interpreter

class Interpreter;
typedef void (Interpreter::*FP)(void);
class TurtleStack;

class Interpreter
{
public: 
  Interpreter(DeviceDriver*, Options*);
  ~Interpreter();

  void interpret(ModuleList*);

  static Value* getTx();
  static Value* getTy();
  static Value* getTz();

private:
  void forward();
  void width();
  void go();
  void pitch();
  void pitch_negativ();
  void roll();
  void roll_negativ();
  void turn();
  void turn_negativ();
  void rotate_vertical();
  void reverse();
  void push();
  void pop();
  void startPolygon();
  void saveVertex();
  void endPolygon();
  void tropism();
  void weight();
  void color();
  void beginMacro();
  void endMacro();
  void executeMacro();
  void libraryObject();
  void sphere();
  void triangle();
  void polygon();
  void activateHull();
  void deactivateHull();
  void cutBranchWhenHit();
  void cutBranch();
  void texture();

  void flush();
  void createConeBetweenSpheres(const Vector&, real, const Vector&, real);
  void computeTropism();

public:
  struct InterpreterFunctions {
    char* name;
    FP function;
    long  index;
  };

private:
  static InterpreterFunctions FuncTable[];
  static FP* functable;
  static Value turtleX; // position of turtle, for use in analytic
  static Value turtleY; // tropism functions
  static Value turtleZ;

  Expression* tropismX; // analytic tropism functions
  Expression* tropismY;
  Expression* tropismZ;
  Expression* tropismWeight;
  int tropismFunction; // analytic tropism functions set?
  int weightFunction;  // analytic weight functions set?

  DeviceDriver* d;
  Turtle* t;
  HullSymtab* h;
  Options* options;

  ModuleList* ml;
  Module* m;           // current module
  long currentModule;  // position of current module in the list

  PolygonList* polyStack;
  TurtleStack* turtleStack;
  Turtle* saveTurtle;

  int definingMacro;  // defining a macro?
  int reflected;      // did we hit a hull primitive in the last move?
  int deleteBranchWhenHit;
};


inline Value* Interpreter::getTx() {
  return &turtleX;
}

inline Value* Interpreter::getTy() {
  return &turtleY;
}

inline Value* Interpreter::getTz() {
  return &turtleZ;
}

#endif // Interpreter_H





