/*
****************************************************************************
*  Kelli Wiseth
*  kelli[at]alameda-tech-lab[dot]com
*  CIS 255AX
*  Program name: Complex.java
*  Program Description: An abstract data type, or class file, that contains
*     methods that add(), subtract(), multiply(), and divide() complex numbers.
*    
*  Assignment #3
*  10 March 2005
****************************************************************************
*/
import java.text.DecimalFormat;  

public class Complex {
   private double realPart;   
   private double imaginaryPart; 
      
   /***********************************************************************
    * Constructors for the class. We have two constructors--a default 
    * constructor() that sets everything to 0.00, and a constructor() that
    * accepts two double values (parameters) to set the values to each of 
    * the real and imaginary parts of the complex number that gets 
    * instantiated.
    ***********************************************************************
   */

   public Complex()                                  //default constructor
   { 
      this( 0.00, 0.00 );
   }

   public Complex(double realNo, double imagineNo) 
   { 
    realPart = realNo;
    imaginaryPart = imagineNo;
   }

   /***********************************************************************
    * Four methods to accomplish the basic operations on any two
    * complex numbers--add(), subtract(), multiply(), and divide().
    ***********************************************************************
   */

   public Complex add(Complex complex)
   {
   double realPartRight = complex.getReal();
   double imagPartRight = complex.getImaginary();
   Complex total = new Complex((realPart + realPartRight), (imaginaryPart + imagPartRight));
   return total;
   }

   public Complex subtract(Complex complex)
   {
   double realPartRight = complex.getReal();
   double imagPartRight = complex.getImaginary();
   Complex difference = new Complex((realPart - realPartRight), (imaginaryPart - imagPartRight));
   return difference;
   }
   
   public Complex multiply(Complex complex)
   {
   double realPartRight = complex.getReal();
   double imagPartRight = complex.getImaginary();
   Complex product = new Complex(((realPart*realPartRight) - (imaginaryPart*imagPartRight)), 
          ((realPart*imagPartRight) + (imaginaryPart*realPartRight)));
   return product;
   }
   /**********************************************************************
    * The divide() method breaks the formula for solving complex number division
    * into its constituents (numerator, denominator) as doubles. Since we must
    * multiply the numerator and denominator by the complex conjugate of the 
    * denominator, the resultant denominator is always a real number, so we can 
    * just deal with it as a double. If it's a zero, we won't do any further
    * division, instead, return a new Complex number set to zeros.
    **********************************************************************
   */
    
   public Complex divide(Complex complex)
   {
   double realPartRight = complex.getReal();
   double imagPartRight = complex.getImaginary();
   double denominator = ((realPartRight*realPartRight) + (imagPartRight*imagPartRight));
   double numeratorLeftPart = ((realPart*realPartRight) + (imaginaryPart*imagPartRight));
   double numeratorRightPart =((imaginaryPart*realPartRight) - (realPart*imagPartRight));
   Complex quotient;
   if (denominator==0)
      quotient = new Complex(0,0);
   else
      quotient = new Complex((numeratorLeftPart/denominator), 
             (numeratorRightPart/denominator));
   return quotient;
   }

   /************************************************************************
    * Accessor ("get methods()" to return the real and imaginary parts of
    * any instance of a complex number. The four methods above--add(), subtract(),
    * multiply(), divide()--use getReal() and getImaginary() to pull out these
    * respective parts of the Complex object being passed in as a parameter to
    * each of these methods. 
    ************************************************************************
   */
   public double getReal() 
   { 
      return realPart; 
   }

   public double getImaginary() 
   { 
      return imaginaryPart; 
   }

   // convert to String with appropriate number of zeros
   public String toString()
   {
    DecimalFormat twoDecimalPlaces = new DecimalFormat("0.0#");
    
    if (imaginaryPart < 0)
        return twoDecimalPlaces.format(Math.abs(getReal())) + " - " + 
              twoDecimalPlaces.format(Math.abs(getImaginary())) + "i";
    else
        return twoDecimalPlaces.format(getReal()) + " + " + 
              twoDecimalPlaces.format(getImaginary()) + "i";
   }

} // end class Complex
