/*  
This applet will plot a graph
*/ 


import java.applet.Applet;
import java.awt.*;
import java.util.Date;
import java.util.Random;

// These classes are for Url's.
import java.net.*;
// import an extra class for the ActionListener
import java.awt.event.*;


public class guess extends Applet implements ActionListener {
// Specify variables that will be needed everywhere, anytime here 
	private Image buffer;
	private Graphics bufG;

       	Font bigFont; 
       	Font verybigFont; 
	Font smallFont;
	Font verysmallFont;
	Color whiteColor; 
	Color blackColor; 
	Color greyColor; 
	Color redColor; 
	Color greenColor; 
	Color blueColor; 
	Color orangeColor; 
	Color bgColor; 
	Button computeButton;
	TextField xField;
	TextArea yField;

	URL base;
	MediaTracker mt;
	boolean firsttime;	
	int counter = 0;
	int[] xvalues = new int[100];
	int[] yvalues = new int[100];

	public void init()  
	{ 
		// Resize, in case the HTML author forgot to
		resize(350, 450);

                // Prepare double-buffer
                buffer = createImage(350, 450);
                bufG = buffer.getGraphics();

		// Tell the applet not to use a layout manager.
                setLayout(null);

		// initialize the MediaTracker
                mt = new MediaTracker(this);

		// The try-catch is necessary when the URL isn't valid
                // Of course this one is valid, since it is generated by
                // Java itself.
		try {
                      // getDocumentbase gets the applet path.
                      base = getDocumentBase();
              	}

		catch (Exception e) {}

		// Get the images (not used here)
	
        	// Will use Arial as type, 16 as size and bold as style 
	        smallFont = new Font("Arial",Font.BOLD,12); 
	        bigFont = new Font("Arial",Font.BOLD,16); 
	        verybigFont = new Font("Arial",Font.BOLD,24); 
	        verysmallFont = new Font("Arial",Font.BOLD,8); 
	        whiteColor = Color.white; 
	        blackColor = Color.black; 
	        greyColor = Color.gray; 
	        redColor = Color.red; 
	        greenColor = Color.green; 
	        blueColor = Color.blue; 
	        orangeColor = Color.orange; 
	        bgColor = new Color(255, 237, 169);

		xField = new TextField("?");
		FontMetrics fm = bufG.getFontMetrics(bigFont);
                int w1 = fm.stringWidth("Tast inn et heltall x: ");
                xField.setBounds(20+w1,10,40,30);

		yField = new TextArea("");
                yField.setBounds(20+w1,50,100,100);
		
		computeButton = new Button("Beregn f(x)");
		computeButton.setBounds(20+w1+45,10,100,30);

		 // Attach actions to the components
                computeButton.addActionListener(this);
                xField.addActionListener(this);

		add(xField);
		add(yField);
		add(computeButton);

		// Set first time flag
		firsttime = true;
        } 

	// When the button is clicked this method will get automatically called
        public void actionPerformed(ActionEvent evt)
        {
                // Here we will ask what component called this method
                if (evt.getSource() == computeButton || evt.getSource() == xField) {
			int n1 = readInput();
			xvalues[counter] = n1;
			xField.setText( String.valueOf(n1) );
			yField.appendText( "f(" + String.valueOf(n1) + ") = " + String.valueOf(computeF(n1)) + "\n");

			counter++;

			firsttime = false;
                	repaint();
		}
	}

	// When the sliders are adjusted this method will get called
        public void doAction() 
	{
		firsttime = false;

		// Read current values and repaint
               	repaint();
	}

        public void stop() 
        { 
        } 


	// Update method gets rid of flickering
        public void update(Graphics g)  
        { 
		paint(g);
	}

        // Now lets draw things on screen 
        public void paint(Graphics g)  
        { 
		int i, ix, iy;
		String s;

		// Draw background
	        bufG.setColor(bgColor); 
		bufG.fillRect(0, 0, 350, 450);

		// Don't do much if first time
		if (!firsttime) {
		}	// All this if not firsttime
		else {
			// All this if firsttime
		}

		// Draw a coordinate system
	        bufG.setColor(blackColor); 
                bufG.drawLine(40,400,280,400);
                bufG.drawLine(40,170,280,170);
                bufG.drawLine(40,400,40,170);
                bufG.drawLine(280,400,280,170);
	
                bufG.setFont(verysmallFont);
		for (ix=0;ix<=20;ix+=5)
		{
			bufG.drawLine( findX(ix), 400, findX(ix),390 );
			bufG.drawLine( findX(ix), 170, findX(ix),180 );
			s = "" + ix;
			FontMetrics fm = bufG.getFontMetrics(verysmallFont);
			int w1 = fm.stringWidth(s);
			bufG.drawString( s, findX(ix)-w1/2, 420);
		}
		for (iy=0;iy<=5;iy+=1)
		{
			bufG.drawLine( 40, findY(iy), 50, findY(iy) );
			bufG.drawLine( 280, findY(iy), 270, findY(iy) );
			s = "" + iy;
			FontMetrics fm = bufG.getFontMetrics(verysmallFont);
			int w1 = fm.stringWidth(s);
			bufG.drawString( s, 40-w1-5, findY(iy) + 3 );
		}

                bufG.setFont(smallFont);
		s = "x";
		bufG.drawString( s, 150, 440);

		s = "f(x)";
		bufG.drawString( s, 5, 160);
                
		s = "Tast inn et heltall x: ";
		bufG.drawString( s, 10, 25);

		s = "Funksjonen svarer med: ";
		bufG.drawString( s, 10, 65);

		// Draw the points
		bufG.setColor(greenColor);
		for (i=0;i<counter;i++) {
			int n1 = xvalues[i];
			int n2 = computeF(n1);
	                bufG.fillOval(findX(n1)-4, findY(n2)-4, 10, 10);
		}

		 // Copy buffer on screen
                g.drawImage(buffer, 0, 0, this);
        } 

	private int findX( int worldX )
	{
		return (int)(40 + (double)(worldX-0)/20.0*(double)(280-40));
	}

	private int findY( int worldY )
	{
		return (int)(400 - (double)((worldY-0)/5.0)*(double)(400-170));
	}

	// Compute x modulo 4, the secret function
	private int computeF( int x )
	{
		return x%4;
	}

	// Get latest input x-value
	private int readInput( )
	{
		String sa = xField.getText();
		try {
                	return Integer.valueOf(sa).intValue();
		}
		catch (Exception e) {
			return 0;
		}

	}
} 
