// file: ZPlane.java
//

// import necessary local files
//
//import Constants;

// class: ZPlane.java
//
// this class contains the necessary methods to convert from z-plane
// coordinates to frequency coordinates
//
public class ZPlane implements Constants{
    
    //*****************************************************************
    //
    // constructor methods
    //
    //*****************************************************************
    
    // method: ZPlane
    //
    // parameters: (none)
    // 
    // this method constructs a ZPlane class
    //
    public ZPlane() {    
	
    }
    
    
    // method: get_freq
    //
    // parameters: 
    //     double z_real: (input) normalized real value of z
    //     double z_imag: (input) normalized imaginary value of z
    //     double sf: (input) sample frequency to find the magnitude at
    // 
    // this method returns the frequency of the point in the z-plane given
    // the sample-frequency
    //
    public static double get_freq (double z_real, double z_imag, double sf) {
	
	// determine where in the z-plane the point is
	//
	
	// no imaginary component
	//
	if (z_imag == 0.0) {
	    
	    // point on the left real-side
	    // 
	    if (z_real < 0.0) {
		return (0.5 * sf);
	    }
	    
	    // point on the right real-axis
	    //
	    else {
		return (0.0);
	    }
	    
	}
	
	// no real component
	//
	else if (z_real == 0.0) {
	    
	    // point on the lower imaginary axis
	    // 
	    if (z_imag < 0.0) {
		return (0.75 * sf);
	    }
	    
	    // point on the upper imaginary axis
	    //
	    else {
		return (0.25 * sf);
	    }
	    
	}
	
	// not on any axis so 
	// determine the frequency by figuring out which quadrant it is in
	//
	else {
	    
	    double arg = z_imag/z_real;
	    double angle = Math.atan(arg);
	    
	    // is it in the 2nd or 4th quads
	    //
	    if (arg < 0.0) {
		
		// determine which quadrant it is in
		//
		// 4th quad???
		//
		if (z_real > 0.0) {
		    return ((1 + (angle/Constants.ISIP_TWOPI)) * sf); 
		}
		
		// 2nd quad???
		//
		else {
		    return((0.5 + (angle/Constants.ISIP_TWOPI)) * sf);
		}
	    }
	    
	    // it's in either the 1st or 3rd quads
	    //
	    else {
		
		// determine which quad it is in
		//
		if (z_real > 0.0) {
		    
		    // it's in the first quad
		    //
		    return ((angle/Constants.ISIP_TWOPI) * sf);
		}
		
		else {
		    
		    // it's in the third quad
		    //
		    return ((0.5 + (angle/Constants.ISIP_TWOPI)) * sf);
		    
		}
	    }
	}
    }
    
    
    // method: get_band
    //
    // parameters: 
    //     double z_real: (input) normalized real value of z
    //     double z_imag: (input) normalized imaginary value of z
    //     double sf: (input) sample frequency to find the magnitude at
    // 
    // this method returns the bandwidth of the point in the z-plane given
    // the sample-frequency
    //
    public static double get_band(double z_real, double z_imag, double sf) {
	
	// find the magnitude
	//
	double mag = Math.sqrt((z_real * z_real) + (z_imag * z_imag));
	if (mag == 0.0) {
	    return (Double.MAX_VALUE);
	}
	else {
	    return (-(Math.log(mag) * sf / Math.PI));
	}
	
    }
    
    
    // method: get_real
    //
    // parameters: 
    //     double frequency: (input) normalized real value of z
    //     double bandwidth: (input) normalized imaginary value of z
    //     double sf: (input) sample frequency to find the magnitude at
    // 
    // this method returns the real coordinate in the z-plane given the
    // frequency, bandwidth and the sample-frequency
    //
    public static double get_real(double frequency, double bandwidth,
				  double sf) {
	
	double angle = (frequency / sf) * Constants.ISIP_TWOPI;
	double mag = Math.exp(-bandwidth / sf * Math.PI);
	
	return (mag * Math.cos(angle));
	
    }  
    
    // method: get_imag
    //
    // parameters: 
    //     double frequency: (input) frequency of pole/zero
    //     double bandwidth: (input) bandwidth of pole/zero
    //     double sf: (input) sample frequency to find the magnitude at
    // 
    // this method returns the imaginary coordinate in the z-plane given the
    // frequency, bandwidth, and the sample-frequency
    //
    public static double get_imag(double frequency, double bandwidth,
				  double sf) {
	
	
	double angle = (frequency / sf) * Constants.ISIP_TWOPI;
	double mag = Math.exp(-bandwidth / sf * Math.PI);
	
	return (mag * Math.sin(angle));
	
    }
    
    
} // end class Constants
