#ifndef NODO_H
#define NODO_H

#include <string>

using namespace std;

enum { CTE, VARX, SUM, SUB, MUL, DIV, POW, LOG, SIN, COS };

class Nodo {
      public:
        virtual int    T(void)= 0;
        virtual double E(void)= 0;
        virtual string P(bool par)= 0;
        virtual Nodo*  C(void)=0;
        virtual Nodo*  S(void)=0;
        virtual Nodo*  D(void)= 0;
};


class Cte : public Nodo {
      private:
         double  val;
      public:
        virtual int    T(void);
        virtual double E(void);
        virtual string P(bool par);
        virtual Nodo*  C(void);
        virtual Nodo*  S(void);
        virtual Nodo*  D(void);
        Cte(double v);
};

class VarX : public Nodo {
      private:
         double *var;
      public:
        virtual int    T(void);
        virtual double E(void);
        virtual string P(bool par);
        virtual Nodo*  C(void);
        virtual Nodo*  S(void);
        virtual Nodo*  D(void);
        VarX(double* v);
};


class Bin : public Nodo {
      public:
        Nodo *izq;
        Nodo *der;

      public:
        Bin (Nodo* i, Nodo* d) { izq= i; der=d; };
        virtual ~Bin(void);  
        virtual int    T(void) = 0;
        virtual double E(void) = 0;
        virtual string P(bool par) = 0;
        virtual Nodo*  C(void) =0;
        virtual Nodo*  S(void) = 0;
        virtual Nodo*  D(void) = 0;
};

class Sum : public Bin {
      public:
        virtual int    T(void);
        virtual double E(void);
        virtual string P(bool par);
        virtual Nodo*  C(void);
        virtual Nodo*  S(void);
        virtual Nodo*  D(void);
        Sum(Nodo* i, Nodo* d) : Bin( i, d ) {};
};

class Sub : public Bin {
      public:
        virtual int    T(void);
        virtual double E(void);
        virtual string P(bool par);
        virtual Nodo*  C(void);
        virtual Nodo*  S(void);
        virtual Nodo*  D(void);
        Sub(Nodo* i, Nodo* d) : Bin( i, d ) {};
};

class Mul : public Bin {
      public:
        virtual int    T(void);
        virtual double E(void);
        virtual string P(bool par);
        virtual Nodo*  C(void);
        virtual Nodo*  S(void);
        virtual Nodo*  D(void);
        Mul(Nodo* i, Nodo* d) : Bin( i, d ) {};
};

class Div : public Bin {
      public:
        virtual int    T(void);
        virtual double E(void);
        virtual string P(bool par);
        virtual Nodo*  C(void);
        virtual Nodo*  S(void);
        virtual Nodo*  D(void);
        Div(Nodo* i, Nodo* d) : Bin( i, d ) {};
};

class Pow : public Bin {
      public:
        virtual int    T(void);
        virtual double E(void);
        virtual string P(bool par);
        virtual Nodo*  C(void);
        virtual Nodo*  S(void);
        virtual Nodo*  D(void);
        Pow(Nodo* i, Nodo* d) : Bin( i, d ) {};
};

class Fun : public Nodo {
      public:
        Nodo* arg;

      public:
        Fun(Nodo* a) { arg= a; }
        virtual ~Fun(void) { delete arg; }
  
        virtual int    T(void) = 0;
        virtual double E(void) = 0;
        virtual string P(bool par) = 0;
        virtual Nodo*  C(void) = 0;
        virtual Nodo*  S(void) = 0;
        virtual Nodo*  D(void) = 0;
};

class Log : public Fun {
      public:
        Log(Nodo* a) : Fun(a) {};
        virtual int    T(void);
        virtual double E(void);
        virtual string P(bool par);
        virtual Nodo*  C(void);
        virtual Nodo*  S(void);
        virtual Nodo*  D(void);
};

#endif
