// polinomio.cpp - Implementación de la clase CPolinomio
//
#include <iostream>                                                                    
#include "polinomio.h"
using namespace std;

/////////////////////////////////////////////////////////////////
// Constructor
CPolinomio::CPolinomio()
{
  polinomio.reserve(10); // reservar memoria para 10 términos
}

// Asigna un término al polinomio colocándolo en orden ascendente
// del exponente.
void CPolinomio::AsignarTermino(CTermino termino)
{
  if (termino.ObtenerCoeficiente() == 0) return;
  float c, coef = termino.ObtenerCoeficiente();
  int exp = termino.ObtenerExponente();

  // Insertar un nuevo término en orden ascendente del exponente.
  int i = polinomio.size() - 1;
  while (i >= 0 &&  exp < polinomio[i].ObtenerExponente())
    i--;
  if (i >= 0 && exp == polinomio[i].ObtenerExponente())
  {
    c = coef + polinomio[i].ObtenerCoeficiente();
    // Término existente. Sumar los coeficientes.
    if (c)
      polinomio[i].AsignarCoeficiente(c);
    else
      polinomio.erase(polinomio.begin()+i);
  }
  else
    // Insertar un nuevo término
    polinomio.insert(polinomio.begin()+(i+1), termino);
}

// Sumar dos polinomios
void CPolinomio::Sumar(CPolinomio& polA, CPolinomio& polB)
{
  unsigned ipa = 0, ipb = 0;
  int na = polA.ObtenerNroTerminos(), nb = polB.ObtenerNroTerminos();
  float coefA, coefB;
  int expA, expB;
  // Sumar polA con polB
  while (ipa < na && ipb < nb)
  {
    coefA = polA.polinomio[ipa].ObtenerCoeficiente();
    coefB = polB.polinomio[ipb].ObtenerCoeficiente();
    expA = polA.polinomio[ipa].ObtenerExponente();
    expB = polB.polinomio[ipb].ObtenerExponente();
    if (expA == expB)
    {
      if (coefA + coefB != 0)
        AsignarTermino(CTermino(coefA + coefB, expA));
      ipa++, ipb++;
    }
    else if (expA < expB)
    {
      AsignarTermino(CTermino(coefA, expA));
      ipa++;
    }
    else
    {
      AsignarTermino(CTermino(coefB, expB));
      ipb++;
    }
  }

  // Términos restantes de polA o de polB
  while (ipa < na)
  {
    coefA = polA.polinomio[ipa].ObtenerCoeficiente();
    expA = polA.polinomio[ipa].ObtenerExponente();
    AsignarTermino(CTermino(coefA, expA));
    ipa++;
  }
  while (ipb < nb)
  {
    coefB = polB.polinomio[ipb].ObtenerCoeficiente();
    expB = polB.polinomio[ipb].ObtenerExponente();
    AsignarTermino(CTermino(coefB, expB));
    ipb++;
  }
}

// Visualizar los términos de un polinomio
void CPolinomio::VisualizarPol()
{
  size_t i = ObtenerNroTerminos();
  
  while (i--)
    polinomio[i].VisualizarTermino();
}
/////////////////////////////////////////////////////////////////

