// file: PzGraphicsObj.java
//

// include the necessary system files
//
//import java.awt.*;
import java.lang.*;
import javax.swing.*;
import java.awt.Graphics;

// include the necessary local files
//
//import Constants;

// class: PzGraphicsObj
//
// this class implements an object which will hold the graphics and
// pixel bounds for a pole or zero in the pz_map
//
public class PzGraphicsObj implements Constants {
    
    // declare class variables
    //
    private int xmin = 0;
    private int xmax = 0;
    private int ymin = 0;
    private int ymax = 0;
    private int height = 0;
    private int width = 0;  
    private int xmin_conj = 100;
    private int xmax_conj = 110;
    private int ymin_conj = 100;
    private int ymax_conj = 110;
    private int height_conj = 10;
    private int width_conj = 10;  
    private int pz_indicator;
    
    // set flag to tell if this object is conjugated
    //
    public boolean conj_flag = false;
    
    // set flag to tell whether it is the pole/zero or its conjugate
    // which has the focus
    //
    private boolean conj_chosen = false;
    
    //*****************************************************************
    //
    // constructor methods
    //
    //*****************************************************************
    
    // method: PzGraphicsObj
    //
    // parameters:
    //     int xmin_a: minimum x value
    //     int ymin_a: minimum y value
    //     int xmax_a: maximum x value
    //     int ymax_a: maximum y value  
    // 
    // this method constructs a PzGraphicsObj in the appropriate bounds
    //
    public PzGraphicsObj(int xmin_a, int ymin_a, int xmax_a, int ymax_a,
			 int indicator_a) {
	
	// set the pixel limits of this object
	//
	xmin = xmin_a;
	ymin = ymin_a;
	xmax = xmax_a;    
	ymax = ymax_a; 
	height = ymax - ymin;
	width = xmax - xmin;
	
	// indicator of if this is a pole or zero
	//
	pz_indicator = indicator_a;
	
    }
    
    
    //***************************************************************
    //
    // private methods
    //
    //***************************************************************
    
    
    // method: set_limits
    //
    // parameters:
    //     int xmin_a: minimum x value
    //     int ymin_a: minimum y value
    //     int xmax_a: maximum x value
    //     int ymax_a: maximum y value  
    // 
    // this method will set the new limits of the object
    //
    // returns: boolean
    //
    public boolean set_limits(int xmin_a, int ymin_a, int xmax_a, int ymax_a) {
	
	// set the pixel limits of this object
	//
	xmin = xmin_a;
	ymin = ymin_a;
	xmax = xmax_a;    
	ymax = ymax_a;    
	height = ymax - ymin;
	width = xmax - xmin;
	
	// exit gracefully
	//
	return true;
    }
    
    
    // method: set_conj_limits
    //
    // parameters:
    //     int xmin_a: minimum x value
    //     int ymin_a: minimum y value
    //     int xmax_a: maximum x value
    //     int ymax_a: maximum y value  
    // 
    // this method will set the new limits of the object's conjugate
    //
    // returns: boolean
    //
    public boolean set_conj_limits(int xmin_a, int ymin_a, int xmax_a,
				   int ymax_a) {
	
	// set the pixel limits of this object
	//
	xmin_conj = xmin_a;
	ymin_conj = ymin_a;
	xmax_conj = xmax_a;    
	ymax_conj = ymax_a;    
	height_conj = ymax_conj - ymin_conj;
	width_conj = xmax_conj - xmin_conj;
	
	// exit gracefully
	//
	return true;
    }
    
    
    // method: is_conjugate
    //
    // parameters:
    //
    // this is a method to check if the object is a conjugate
    //
    // returns: boolean
    //
    public boolean is_conjugate() {
	return conj_flag;
    }
    
    
    // method: move_by_one
    //
    // parameters:
    //     int direction: direction to move in
    //
    // this is a method to move this object in any direction by one pixel
    //
    // returns: boolean
    //
    public boolean move_by_one (int direction) {
	
	// figure out which direction to move in
	//
	switch (direction) {
	    
	    // move up
	    //
	case 'i':
	case 'I':      
	    if (conj_flag) {
		if (conj_chosen) {
		    ymin_conj--;
		    ymax_conj--;
		    ymin++;
		    ymax++;
		}
		else {
		    ymin_conj++;
		    ymax_conj++;
		    ymin--;
		    ymax--;
		}
	    }
	    else {
		ymin--;
		ymax--;
	    }
	    
	    return true;
	    
	    // move down
	    //
	case 'k':
	case 'K':      
	    if (conj_flag) {
		if (conj_chosen) {
		    ymin_conj++;
		    ymax_conj++;
		    ymin--;
		    ymax--;
		}
		else {
		    ymin_conj--;
		    ymax_conj--;
		    ymin++;
		    ymax++;
		}
	    }
	    else {
		ymin++;
		ymax++;
	    }
	    return true;
	    
	    // move left
	    //
	case 'j':
	case 'J':      
	    if (conj_flag) {
		xmin_conj--;
		xmax_conj--;
		xmin--;
		xmax--;
	    }
	    else {
		xmin--;
		xmax--;
	    }
	    return true;
	    
	    // move right
	    //
	case 'l':
	case 'L':      
	    if (conj_flag) {
		xmin_conj++;
		xmax_conj++;
		xmin++;
		xmax++;
	    }
	    else {
		xmin++;
		xmax++;
	    }
	    return true;
	    
	default:
	    return false;
	    
	} // end switch
    }
    
    
    // method: getx
    //
    // parameters: (none)
    //
    // this is a method to return the x coordinate of this object
    //
    // returns: int
    //
    public int getx () {
	
	// calculate the x value
	//
	return ((xmax + xmin) >> 1);
    }
    
    
    // method: gety
    //
    // parameters: (none)
    //
    // this is a method to return the y coordinate of this object
    //
    // returns: int
    //
    public int gety () {
	
        return ((ymax + ymin) >> 1);
    }
    
    
    // method: does_contain
    //
    // parameters:
    //     int x: x value to test
    //     int y: y value to test
    //
    // this is a method to check if this object contains the input point
    //
    // returns: boolean
    //
    public boolean does_contain (int x, int y) {
	
	// test for x and y inside the limits
	//
	if ((x >= xmin) && (x <= xmax) && (y >= ymin) && (y <= ymax)) {
	    conj_chosen = false;
	    return true;
	}
	else if ((x >= xmin_conj) && (x <= xmax_conj) && (y >= ymin_conj) && 
		 (y <= ymax_conj)) {
	    conj_chosen = true;
	    return true;
	}
	else {
	    return false;
	}
    }
    
    
    // method: draw_self
    //
    // parameters: (none)
    //
    // this is a method to draw this pole or zero on the map when called
    //
    // returns: boolean
    //
    public boolean draw_self (Graphics graph) {
	
	// draw a 3d rectangle around the pole or zero
	//
	graph.draw3DRect(xmin, ymin, width, height, true);
	
	// check for a conjugate
	//
	if (conj_flag) {
	    graph.draw3DRect(xmin_conj, ymin_conj, width_conj, height_conj, true);
	}
	
	if (pz_indicator == Constants.POLE_INDICATOR) {
	    
	    // draw an x through the rectangle
	    //
	    graph.drawLine(xmin, ymin, xmax, ymax);
	    graph.drawLine(xmin, ymax, xmax, ymin);
	    
	    // check for a conjugate
	    //
	    if (conj_flag) {
		// draw an x through the rectangle
		//
		graph.drawLine(xmin_conj, ymin_conj, xmax_conj, ymax_conj);
		graph.drawLine(xmin_conj, ymax_conj, xmax_conj, ymin_conj);
	    }
	}
	else {
	    
	    // draw an oval
	    //
	    graph.fillOval(xmin, ymin, width, height);
	    
	    // check for a conjugate
	    //
	    if (conj_flag) {
		
		// draw an oval
		//
		graph.fillOval(xmin_conj, ymin_conj, width_conj, height_conj);
	    }
	}
	
	// exit gracefully
	//
	return true;
	
    }
    
} // end class PzGraphicsObj
