/* triangolo.h */

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include "menu.h"


class punto {
  double x,y;  // Attributi del punto, coordinate
public:
  // Costruttore di default: assegna due numeri random da -5.0 a 5.0 son due decimali
  punto () { x = (random () % 1000) / 100.0 - 5.0;  y = (random () % 1000) / 100.0 - 5.0;};
  // Costruttore: inizializza con due double
  punto (double X, double Y) { x=X; y=Y; };
  // Costruttore per copia: per quello che fa, puteva bastare quello fornito dal sistema
  punto (const punto &p) { x = p.x; y = p.y; };
  // Visualizza le coordinate del punto
  void show () { printf ("X %.2f Y %.2f\n", x, y);};
  // Operatore -: usando Pitagora, calcola la distanza tra i due punti
  double operator - (const punto &g) { double a=x - g.x; double b=y -g.y; return sqrt (a*a+b*b); };
  // Operatore +=: calcola la somma dei due punti (intesi come vettori) e la lascia nel punto
  punto &operator += (const punto &g) { y+=g.y; x+=g.x; return *this;};
  // Operatore *=: moltiplica le coordinate per un numero, lasciando il risultato nel punto
  punto &operator *= (double s) { y*=s; x*=s; return *this;};
};
 
class triangolo {
  punto a,b,c;  // I tre vertici del triangolo
public :
  // Costruttore con tre punti come parametro, chiama l'inizializzatore degli attributi
  triangolo (const punto &A, const punto &B, const punto &C) : a (A), b (B), c (C) {};
  // Metodo 'show' che stampa i vertici del triangolo, richiamando lo 'show' dei punti
  void show () { printf ("A - "); a.show ();  printf ("B - "); b.show (); printf ("C - "); c.show ();};
  // Metodo 'perimetro' che calcola il perimetro, sommando la dimensione dei tre lati
  double perimetro () { return (a-b) + (b-c) + (c-a) ; };
  // Operatore +=: somma il punto ai tre vertici, con l'operator += di 'punto'
  triangolo &operator += (const punto &g) { a+=g; b+=g; c+=g; return *this;};
  // Operatore *=: scala il triangolo scalndo tutti e tre i vertici, tramite il loro operatore *=
  triangolo &operator *= (double s) { a*=s; b*=s; c*=s; return *this;};
};

/* Menu: come al solito solo costruttore e 'action' */
class MenuShow : public menu {
protected:
  virtual void action (void *par) { ((triangolo*)par) -> show (); }; // Invoca semplicemente la 'show' del triangolo
public:
  MenuShow (menu **base,char *n) : menu ((menu**)base,n) {};
};

class MenuPerimetro : public menu {
protected:
  // Calcola il perimetro, usando il metodo di 'triangolo'
  virtual void action (void *par) { printf ("Perimetro %.2f\n", ((triangolo*)par) -> perimetro ()); }; 
public:
  MenuPerimetro (menu **base,char *n) : menu ((menu**)base,n) {};
};

class MenuScala : public menu {
protected:
  virtual void action (void *par);
public:
  MenuScala (menu **base,char *n) : menu ((menu**)base,n) {};
};

void MenuScala::action (void *par) 
{ 
  char str [10];                   // Posto per il numero scelto dall'utente
  double s;                        // Numero scritto dall'utente
    printf ("Fattore di scala: "); // Prompt
    fgets (str,9,stdin);           // Legge la risposta dell'utente
    s = strtod (str,0);            // Converte in double
    *((triangolo*)par) *= s;       // Esegue l'operazione
}

class MenuTrasla : public menu {
protected:
  virtual void action (void *par);
public:
  MenuTrasla (menu **base,char *n) : menu ((menu**)base,n) {};
};

void MenuTrasla::action (void *par) 
{ 
  char str [10];                         // Posto per il numero scelto dall'utente
  double x,y;                            // Numero scritto dall'utente
    printf ("X Traslazione: ");          // Prompt
    fgets (str,9,stdin);                 // Legge la risposta dell'utente
    x = strtod (str,(char**)0);          // Converte in double
    printf ("Y Traslazione: ");          // Prompt
    fgets (str,9,stdin);                 // Legge la risposta dell'utente
    y = strtod (str,(char**)0);          // Converte in double
    *((triangolo*)par) += punto (x,y);   // Esegue l'operazione
}


/* Funzione principale */
int main ()
{
  srandom (time (NULL));	         /* Inizializza il generatore di numeri casuali */
punto a,b,c;                             // Crea tre punti 'a caso'
triangolo t (a , b, c);                  // Ci costruisce un triangolo
menu *m = 0;                             // Il menu' principale
  // Le voci del menu'
  new menuexit (&m,"Termina");
  new MenuShow (&m,"Visualizza Triangolo");
  new MenuPerimetro (&m,"Calcola Perimetro");
  new MenuScala (&m,"Scala il triangolo");
  new MenuTrasla (&m,"Trasla il triangolo");

  // Loop di esecuzione del meni'
  while (1)
  {
    m->doaction (m->print (1),&t);  // Stampa il menu' ed esegue direttamente il numero trovato
  }
}