// Exercise10_10.java: Draw generic functions
import java.awt.*;
import javax.swing.*;

public class Exercise10_10 extends JFrame {
  public Exercise10_10() {
    getContentPane().setLayout(new GridLayout(1, 2, 5, 5));
    getContentPane().add(new DrawSine());
    getContentPane().add(new DrawCosine());
  }
  
  public static void main(String[] args) {
    Exercise10_10 frame = new Exercise10_10();
    frame.setSize(400, 400);
    frame.setTitle("Exercise 10.10");
    frame.setVisible(true);
  }
}

class DrawXSquare extends AbstractDrawFunction {
  /**Implement the fuction*/
  public double f(double x) {
    // scaleFactor for adjusting y coordinates
    double scaleFactor = 0.01;
    
    return scaleFactor*x*x;
  }
}

class DrawSine extends AbstractDrawFunction {
  public double f(double x) {
    return 50*Math.sin((x/100.0)*2*Math.PI);
  }
}

class DrawCosine extends AbstractDrawFunction {
  public double f(double x) {
    return 50*Math.cos((x/100.0)*2*Math.PI);
  }
}

abstract class AbstractDrawFunction extends JPanel {
  /**Polygon to hold the points*/
  private Polygon p = new Polygon();
  
  /**Default constructor*/
  protected AbstractDrawFunction() {
    drawFunction();
    setBackground(Color.white);
  }
  
  /**Draw the function*/
  public abstract double f(double x);
  
  /**Obtain points for x coordinates 100, 101, ..., 300*/
  public void drawFunction() {
    for (int x = -100; x <= 100; x++) {
      p.addPoint(x+200, 200-(int)f(x));
    }
  }
  
  /**Paint the function diagram*/
  public void paintComponent(Graphics g) {
    super.paintComponent(g);
    
    // Draw x axis
    g.drawLine(10, 200, 390, 200);
    
    // Draw y axis
    g.drawLine(200,30, 200, 390);
    
    // Draw arrows on x axis
    g.drawLine(390, 200, 370, 190);
    g.drawLine(390, 200, 370, 210);
    
    // Draw arrows on y axis
    g.drawLine(200, 30, 190, 50);
    g.drawLine(200, 30, 210, 50);
    
    // Draw x, y
    g.drawString("X", 370, 170);
    g.drawString("Y", 220, 40);
    
    // Draw a polygon line by connecting the points in the polygon
    g.drawPolyline(p.xpoints, p.ypoints, p.npoints);
  }
}