/*----------------------------------------------------------------
|	Autor:                                                        |
|	Fecha:                            Versión: 1.0	              |
|-----------------------------------------------------------------|
|	Descripción del Programa:                                     |
|  								                                  |
| ----------------------------------------------------------------*/

// Incluir E/S y Librerías Standard
#include <iostream>
#include <cstdlib>
#include <cmath>
using namespace std;

// Zona de Declaración de Constantes

// Zona de Declaración de Tipos


// Zona de Cabeceras de Procedimientos y Funciones
char menu();
bool ConfirmaSalida();
void intercambia(int &x, int &y);
int MCD(int x, int y);
void leer_fraccion(int &n, int &d);
void escribir_fraccion(int n, int d);
void suma_fracciones(int n1,int d1,int n2,int d2,int &n3,int &d3);
void multiplica_fracciones(int n1,int d1,int n2,int d2,int &n3,int &d3);
void simplifica_fraccion(int n1,int d1,int &n3,int &d3);
// Programa Principal
int main()
{
  // Zona de Declaración de Variables del Programa principal
  char op;
  int n1,n2,n3,d1,d2,d3;
  bool salir;
  
  salir = false;
  while(!salir)
  {
    op = menu();
    switch(op)
    {
        case 'A': cout << "Fraccion 1" << endl;
                  leer_fraccion(n1, d1);
                  cout << "Fraccion 2" << endl;
                  leer_fraccion(n2, d2);
                  suma_fracciones(n1,d1,n2,d2,n3,d3);
                  cout << endl << endl;
                  escribir_fraccion(n1,d1);
                  cout << " + ";
                  escribir_fraccion(n2,d2);
                  cout << " = ";
                  escribir_fraccion(n3,d3);                  
                  cout << endl << endl;
                  break;
        case 'B': cout << "Fraccion 1" << endl;
                  leer_fraccion(n1, d1);
                  cout << "Fraccion 2" << endl;
                  leer_fraccion(n2, d2);
                  suma_fracciones(n1,d1,-n2,d2,n3,d3);
                  cout << endl << endl;
                  escribir_fraccion(n1,d1);
                  cout << " - ";
                  escribir_fraccion(n2,d2);
                  cout << " = ";
                  escribir_fraccion(n3,d3);        
                  cout << endl << endl;
                  break;
        case 'C': cout << "Fraccion 1" << endl;
                  leer_fraccion(n1, d1);
                  cout << "Fraccion 2" << endl;
                  leer_fraccion(n2, d2);
                  multiplica_fracciones(n1,d1,n2,d2,n3,d3);
                  cout << endl << endl;
                  escribir_fraccion(n1,d1);
                  cout << " * ";
                  escribir_fraccion(n2,d2);
                  cout << " = ";
                  escribir_fraccion(n3,d3); 
                  cout << endl << endl;
                  break;
        case 'D': cout << "Fraccion 1" << endl;
                  leer_fraccion(n1, d1);
                  cout << "Fraccion 2" << endl;
                  leer_fraccion(n2, d2);
                  multiplica_fracciones(n1,d1,d2,n2,n3,d3);
                  cout << endl << endl;
                  escribir_fraccion(n1,d1);
                  cout << " / ";
                  escribir_fraccion(n2,d2);
                  cout << " = ";
                  escribir_fraccion(n3,d3); 
                  cout << endl << endl;
                  break;
        case 'E': cout << "Fraccion " << endl;
                  leer_fraccion(n1, d1);
                  simplifica_fraccion(n1,d1,n3,d3);
                  cout << endl << endl;
                  escribir_fraccion(n1,d1);
                  cout << " = ";
                  escribir_fraccion(n3,d3); 
                  cout << endl << endl;
                  break;
        case 'X': salir = ConfirmaSalida();
                  cout << endl << endl;
                  break;
    
    }

    system("Pause"); // Hacer una pausa
    system("cls");   // Borrar la Pantalla
  }
  
  return 0;	   // Valor de retorno al S.O.
}

// Implementación de Procedimientos y Funciones

char menu()
{
  char op;
  
  cout << "        MENU" << endl;
  cout << "        ====" << endl;
  cout << "Elaborado Por : Nombre Apellidos" << endl;
  cout << "E.T.S.I Informatica 1ºA Gestion" << endl;
  cout << "Fecha: 9 de Diciembre de 2.003" << endl;
  cout << endl;
  cout << "  A. Sumar Fracciones." << endl;
  cout << "  B. Restar Fracciones." << endl;
  cout << "  C. Multiplicar Fracciones." << endl;
  cout << "  D. Dividir Fracciones." << endl;
  cout << "  E. Simplificar Fracción." << endl;
  cout << "  X. Salir del Programa" << endl;
  cout << endl;
  cout << "  Introduzca su opcion: " ;
  
  cin >> op;
  op = toupper(op);
  
  while ( ((op<'A') || (op>'E')) && (op!='X') )
  {
    cout << "  Opcion Incorrecta ..." << endl;
    cout << endl;
    cout << "  Introduzca su opcion: " ;
    cin >> op;
    op = toupper(op);  
  }
  
  return op;

}

bool ConfirmaSalida()
{ 
  char car;

  cout << "?Esta seguro de salir (S/N)?";
  cin >> car;
  car = toupper(car);
  
  return (car=='S');
}

void leer_fraccion(int &n, int &d)
{
    cout << "Numerador: ";
    cin >> n;
    cout << "Denominador: ";
    cin >> d;
    
}

void escribir_fraccion(int n, int d)
{
    cout << n << "/" << d;
}

void intercambia(int &x, int &y)
{ int t;

  t = x;
  x = y;
  y = t;
}

int MCD(int x, int y)
{ // El MCD no depende del signo por lo que uso el valor absoluto
  x = abs(x);
  y = abs(y);
  while(x!=y)
  { if (x>y)
    { x = x -y;
    }
    else
    { intercambia(x,y);
    }
  }
  return x;
}

void suma_fracciones(int n1,int d1,int n2,int d2,int &n3,int &d3)
{
    simplifica_fraccion(n1*d2 + n2*d1,d1*d2,n3,d3);
}

void multiplica_fracciones(int n1,int d1,int n2,int d2,int &n3,int &d3)
{
    simplifica_fraccion(n1*n2,d1*d2,n3,d3);
}

void simplifica_fraccion(int n1,int d1,int &n3,int &d3)
{
    int mcd;
    
    // Ajusto los Valores
    mcd = MCD(n1,d1);   
    n3 = abs(n1)/mcd;
    d3 = abs(d1)/mcd;
    
    // Ajusto el Signo
    if (n1*d1<0) // Tienen distinto signo
    {
      n3 = -n3;
    }

}