//Infinateint.cc
//brian jahns C1999
//cs252
//infinateint class implementation

#include <iostream.h>
#include <ctype.h>
#include "Node.h"
#include "List.h"
#include "Infinateint.h"

//output stream
ostream& operator << (ostream& os, const Infinateint& integer)
{
int data=0;

if (integer.number.listlength()<1) //checks for valid position
{
os<<" ";
return os;
}
for (int i=integer.number.listlength(); i>0;i--)
{
integer.number.find(i, data); 
os << data;
if (i % 3 ==1 && i !=1)
os <<","; 
}
os<<endl;
return os;

//istream helper
static bool nextcharisdigit(istream& is)
{
int next=is.peek();
while((next!=EOF)&&((next==' ')||(next==',')))
{
is.get();
next=is.peek();
}
if(next=='\n')
is.get();
return (isdigit(next));
}

//istream helper
static void skipleadingnewlines(istream& is)
{
int next=is.peek(); 
while((next!=EOF)&&(next<=' '))
{
is.get();
next=is.peek();
}


//input stream
istream& operator >> (istream& is, Infinateint& integer)
{
while(!integer.number.isempty())
integer.number.del(1);
skipleadingnewlines(is);
while(nextcharisdigit(is))
{
char ch;
is >> ch;
integer.number.insert(1, (ch - '0'));
}
return is;
}

//default constructor
Infinateint::Infinateint(){}

//copy constructor
Infinateint::Infinateint(const Infinateint& integer)
{
number=integer.number;
}

//destructor
Infinateint::~Infinateint(){}

//overloaded addition operator
Infinateint Infinateint::operator + (const Infinateint& integer)
{
Infinateint result;
int data=0;
int num=0;
int carry=0;
int sum=0;
for (int i = 1; i <= integer.number.listlength(); i++)
{
number.find(i, num);
integer.number.find(i, data);
sum = num + data + carry;
if (sum > 9)
{
sum-= 10;
carry = 1;
}
else
carry = 0;
result.number.insert(i, sum);
}
if (number.listlength() == integer.number.listlength() && carry == 1)
result.number.insert((integer.number.listlength()+1), carry);
if (number.listlength()> integer.number.listlength())
for (int j = (integer.number.listlength()+1); j <= number.listlength(); 
j++)
{
number.find(j, num);
sum = num + carry;
carry = 0;
result.number.insert(j, sum);
}
if (number.listlength() < integer.number.listlength())
for (int k = (integer.number.listlength()+1); 
k <= integer.number.listlength(); k++)
{
integer.number.find(k, data);
sum = data + carry;
carry = 0;
result.number.insert(k, sum);
}
return result;
}


//overloaded subtration operator
Infinateint Infinateint::operator - (const Infinateint& integer)
{
Infinateint result;
int num=0;
int data=0;
int diff=0;
int neg = 0;
for (int x = 1; x <= integer.number.listlength(); x++){
number.find(x, num);
integer.number.find(x, data);
diff = num - data - neg;
neg = 0;
if (diff < 0){
diff= diff+10;
neg = 1;
}
result.number.insert(x, diff);
}
if (number.listlength() > integer.number.listlength())
for (int y = (integer.number.listlength()+1); y <= (number.listlength()); 
y++)
{
number.find(y, num);
diff = num - neg;
neg = 0;
if (diff < 0){
diff=diff+10;
neg = 1;
}
result.number.insert(y, diff);
}
return result;
}

//overloaded *
Infinateint Infinateint::operator * (const Infinateint& integer)
{
return integer;
}