/**
 * A simple implementation of complex numbers (those of the form
 * x + y*i) that supports a small set of operations.
 * <p>
 * Copyright (c) 1998 Samuel A. Rebelsky.  All rights reserved.
 *
 * @author Samuel A. Rebelsky
 * @version 1.1 of January 1998
 */
public class Complex 
  implements Cloneable
{

  // +------------+--------------------------------------------------------
  // | Attributes |
  // +------------+

  /**
   * The real part of a complex number which is represented in
   * traditional "x + y*i" format.
   */
  protected double real_part;
  /**
   * The imaginary part of a complex number which is represented
   * in traditional "x + y*i" format.  
   */
  protected double imaginary_part;


  // +--------------+------------------------------------------------------
  // | Constructors |
  // +--------------+

  /**
   * Initialize to 0.0 + 0.0i
   */
  public Complex()
  {
    this(0.0, 0.0);
  } // Complex()
  /**
   * Initialize to x + y*i
   */
  public Complex(double x,double y)
  {
    real_part = x;
    imaginary_part = y;
  } // Complex(double,double)
  /**
   * Initialize to x + 0.0i
   */
  public Complex(double x)
  {
     this(x,0.0);
  } // Complex(double)


  // +-----------+---------------------------------------------------------
  // | Accessors |
  // +-----------+

  /**
   * Get the imaginary part of this complex number.
   */
  public double getImaginary()
  {
    return imaginary_part;
  } // getImaginary

  /**
   * Get the radius of the vector corresponding to this complex number.
   */
  public double getRadius()
  {
    return Math.sqrt(real_part*real_part + imaginary_part*imaginary_part);
  } // getRadius()

  /**
   * Get the real part of this complex number.
   */
  public double getReal()
  {
    return real_part;
  } // getReal()


  // +-----------+---------------------------------------------------------
  // | Modifiers |
  // +-----------+

  /**
   * Set/change the value of this complex number to x + y*i.
   */
  public void setValue(double x, double y) 
  {
    real_part = x;
    imaginary_part = y;
  } // setValue


  // +------------------+--------------------------------------------------
  // | Standard Methods |
  // +------------------+

  /**
   * Make a copy of this complex number.
   */
  public Object clone()
  {
    return new Complex(real_part, imaginary_part);
  } // clone

  /**
   * Determine if another complex number equals this complex number.
   */
  public boolean equals(Complex other)
  {
    return ( (other.real_part == real_part) &&
             (other.imaginary_part == imaginary_part) );
  } // equals(Complex)

  /**
   * Determine if another object equals this complex number.
   */
  public boolean equals(Object other)
  {
    return ( (other instanceof Complex) &&
             (equals((Complex) other)) );
  } // equals(Object)

  /**
   * Compute a hash code for this number.
   */
  public int hashCode()
  {
    // The Double version of the real part
    Double real_double = new Double(real_part);
    // The Double version of the imaginary part
    Double imag_double = new Double(imaginary_part);
    // Combine them in an interesting fashion (2/3 of the real part
    // and 1/3 of the imaginary part)
    return ( (real_double.hashCode() * 2 / 3) +
             (imag_double.hashCode() / 3) );
  } //hashCode

  /**
   * Build a string representation of the current complex number.
   */
  public String toString()
  {
    return (real_part + "+" + imaginary_part + "i");
  } // toString()

} // Complex

