//
//  newAngle.java
//  newAngle
//
//  Created by Chris Thiel on Sat Sep 21 2002.
//  Copyright (c) 2002 Chris Thiel. All rights reserved.
//  Educational use is free with permission 
//  send an email to me at cct@ktb.net
//
//  A simple Java applet that helps a student learn about vectors
//  Draws a list of vectors May 18, 2001 Chris Thiel, OFMCap.
//
//  ver 1.0 May 18, 2001
//  ver 2 -12 Apr 03- All controls in tha pplet, not webpage.

import java.awt.*;
import java.applet.*;
import java.awt.event.*;
import java.util.*;

public class vector2 extends Applet implements ActionListener,MouseListener,ItemListener {
    myCanvas canvas; 
    Panel np=new Panel();
    Panel wp=new Panel();
    Panel cp=new Panel();
    Panel sp=new Panel();
    Panel ep=new Panel();
    Label l1=new Label("Start Vector Near ");
    Label l2=new Label("Scale Factor");
    Label l3=new Label("Thickness");
    Label l4=new Label("Color ");
    Label l5=new Label("Background");
    
    public TextArea List=new TextArea("<1,1>",20,10,1);
    public Button clearBtn=new Button("Clear");
    public Button example1Btn=new Button("Example 1");
    public Button example2Btn=new Button("Example 2");
    
    public Button redrawBtn=new Button("Redraw");
   
    
    Choice LocationMenu = new Choice();
    Choice ScaleMenu = new Choice();
    Choice ThicknessMenu = new Choice();
    Choice vColorMenu = new Choice();
    Choice bColorMenu = new Choice();
    // globals
    public int xMax=540;
    public int yMax=400;
    int i;
	String[] cName = new String[12]; // names of the colors
        
public void mouseClicked(MouseEvent e){
}
public void mouseEntered(MouseEvent e){

}
public void mouseExited(MouseEvent e){}
public void mouseReleased(MouseEvent e){
  }
public void mousePressed(MouseEvent e){
 UpdateEverything();
  repaint(); 
  canvas.repaint();
}

public void itemStateChanged(ItemEvent ie){
 UpdateEverything();
 repaint();
 canvas.repaint();
}
public void init() {
    cName[0]="black";
         cName[1]="red";
         cName[2]="green";
         cName[3]="blue";
         cName[4]="pink";
         cName[5]="orange";
         cName[6]="magenta";
         cName[7]="cyan";
         cName[8]="white";
         cName[9]="yellow";
         cName[10]="gray";
         cName[11]="darkGrey";
       setLayout(new BorderLayout());
     
        canvas= new myCanvas();
        canvas.setSize(xMax,yMax); 
        add("Center", canvas );
        add("South",sp);
        sp.setBackground(Color.red);
        //wp.setLayout(new GridLayout(3,1));
        wp.add(List);
        add("West", wp);
        wp.setBackground(Color.cyan);
       
        ep.setBackground(Color.orange);
        clearBtn.addActionListener(this);

        redrawBtn.addActionListener(this);
        example1Btn.addActionListener(this);
        example2Btn.addActionListener(this);
        sp.add(clearBtn);
        sp.add(redrawBtn);
        sp.add(example1Btn);
        sp.add(example2Btn);

        ep.setLayout(new FlowLayout());
		Panel p=new Panel();
		p.setLayout(new GridLayout(0,1));
        p.add(l1);//location
        LocationMenu.addItem("Top Left");
        LocationMenu.addItem("Top Center");
        LocationMenu.addItem("Top Right");
        LocationMenu.addItem("Middle Left");
        LocationMenu.addItem("Middle Center");
        LocationMenu.addItem("Middle Right");
        LocationMenu.addItem("Bottom Left");
        LocationMenu.addItem("Bottom Center");
	LocationMenu.addItem("Bottom Right");
        p.add(LocationMenu);
        p.add(l2);//scale factor
        ScaleMenu.addItem("2:1");
        ScaleMenu.addItem("1:1");
        ScaleMenu.addItem("1:2");
        ScaleMenu.addItem("1:3");
        ScaleMenu.addItem("1:4");
        ScaleMenu.addItem("1:5");
        ScaleMenu.addItem("1:10");
        ScaleMenu.addItem("1:20");
        ScaleMenu.addItem("1:50");
        ScaleMenu.addItem("1:100");
        p.add(ScaleMenu);
        
        p.add(l3);//line thickness
        ThicknessMenu.addItem("thin");
        ThicknessMenu.addItem("medium");
        ThicknessMenu.addItem("thick");
        ThicknessMenu.addItem("thicker still");
        ThicknessMenu.addItem("really thick");
        ThicknessMenu.addItem("extremely thick");
        ThicknessMenu.addItem("ludicrously thick");
        p.add(ThicknessMenu);
        p.add(l4);//vector color
        for (i=0; i<12; i++) vColorMenu.addItem(cName[i]);
        p.add(vColorMenu);
        p.add(l5);//background color
        for (i=0; i<12; i++) bColorMenu.addItem(cName[i]);
        p.add(bColorMenu);
        ep.add(p);
		add("East", ep);
    //Add mouse listeners to immediately refresh canvas
    List.addMouseListener(this);
	//set defaults:
		ThicknessMenu.select(0);
		vColorMenu.select(0);//black
		bColorMenu.select(8);//white
		ScaleMenu.select(4);// 1:4
		LocationMenu.select(4);//middle center
 
repaint();		
}

private void clearList(){
    List.setText("");
    repaint();
}
private void ex1(){
    List.setText("<10,10>\n<10,-10>\n<-20,0>");
    repaint();
}
private void ex2(){
    List.setText("<1,1.414>\n<-1,1.414>\n<2, 0>\n<1,1.414>\n<1,-1.414>\n<2,0>\n<-1,-1.414>\n<1,-1.414>\n<-2,0>\n<-1,-1.414>\n<-1,1.414>\n<-2,0>");
    repaint();
}
private Color colorOf(int c){
    Color x=Color.white;
    switch (c) {
        case(0):x=Color.black; break;
        case(1):x=Color.red; break;
       case(2):x=Color.green; break;
       case(3):x=Color.blue; break;
       case(4):x=Color.pink; break;
       case(5):x=Color.orange; break;
       case(6):x=Color.magenta; break;
       case(7):x=Color.cyan; break;
       case(8):x=Color.white; break;
       case(9):x=Color.yellow; break;
       case(10):x=Color.gray; break;
       case(11):x=Color.darkGray; break;
    }//of switch
    return x;
}
private int thicknessOf(int t){
 int x=t+1;
    switch (t) {
       
       case(3):x=5; break;
       case(4):x=8; break;
       case(5):x=10; break;
       case(6):x=15; break;
       
    }//of switch
    return x;

}
private double scalingOf(int s){
    double x=1.0;
    switch (s) {
        case(0):x=.5;break;
        case(1):x=1;break;
        case(2):x=2;break;
        case(3):x=3;break;
        case(4):x=5;break;
        case(5):x=10;break;
        case(6):x=20;break;
        case(7):x=50;break;
        case(8):x=100;break;
    }
    return x;
}
public void UpdateEverything(){
    
    canvas.list=List.getText();
    canvas.bColour=colorOf(bColorMenu.getSelectedIndex());
    canvas.vColour=colorOf(vColorMenu.getSelectedIndex());
    canvas.thickness=thicknessOf(ThicknessMenu.getSelectedIndex());
    canvas.sf=scalingOf(ScaleMenu.getSelectedIndex());
    canvas.startx=10+(int)((.5*xMax-10)*(LocationMenu.getSelectedIndex()%3));
    canvas.starty=10+(int)((.5*yMax-10)*(int)(LocationMenu.getSelectedIndex()/3));
}

public void actionPerformed(ActionEvent e){ 
    UpdateEverything();
    Object object=e.getSource();

    if (object==clearBtn){
     clearList();
        }
    
    if (object==example1Btn){
         ex1();
           }
    if (object==example2Btn){
         ex2();
            }
    repaint(); 
    canvas.repaint();
} 
    public void paint (Graphics g) {
        g.setColor(Color.red);
        g.drawString("This is here = ", 255 , 250);
    }
}
class myCanvas extends Canvas { 
private Font font = new Font("serif", Font.ITALIC + Font.BOLD, 14);
public String t;
public double ax=50.0;
public double ay=20.0;
public double bx=40.0;
public double by=-20.0;
public String list;
public Color bColour, vColour;
public int sop=11; //startOffPlace
public double sf=1; 	//scale factor
public int thickness=1; //thickness of vector lines
public int cx, cy,n;
public	int startx, starty; // holds starting coords
public int xMax=540;
public int yMax=400;
  
int MAX=400;
int i=0;
public	String Title;
	String s;
public	String message;
public	double vx[] = new double[MAX];//hold the list of user's vectors to draw
public	double vy[] = new double[MAX];

 myCanvas(){ 
	 
	setBackground(bColour); 
 } 
private void setString (String userInput) {
	i=0; //reset number of pairs
	n=0;
	
	message=null; //reset error message
	//convert new line chars from unix/win
	userInput.trim(); 
	while (userInput.indexOf("\n") >=0) {
	   userInput= 
	     userInput.substring(0, userInput.indexOf("\n")) + " ; " +
	     userInput.substring(userInput.indexOf("\n")+1);
	}
	//convert return chars from macOS 
	while (userInput.indexOf("\r") >=0) {
	   userInput= 
	     userInput.substring(0, userInput.indexOf("\r")) + " ; " +
	     userInput.substring(userInput.indexOf("\r")+1);
	}
	if ( !(userInput.endsWith(" ;"))) userInput = userInput+" ;";
	
	
	//replace commas with spaces for parsing
	userInput=userInput.replace(',',' ');
	
	
	// Now that the lines are cleaned up read in pairs  
	StringTokenizer t= new StringTokenizer(userInput, " ", false);
	while ((t.hasMoreTokens()) && (i<MAX)) {
	  try{
	  	s = t.nextToken();
	  	if (s.charAt(0)!=';'){	
	  	 	s= s.substring(s.indexOf("<")+1);
	  	 	vx[i]=Float.valueOf(s).floatValue(); 
	  	 	s = t.nextToken();
	  	 	s= s.substring(0, s.indexOf(">"));
      	 	vy[i]=Float.valueOf(s).floatValue(); 
      	 	if (t.hasMoreTokens() ) s=t.nextToken();// the ; separator
	  	 	i++;
	  	 }//end of if
	  	}// end of try
	  catch(Exception e) {
	    //message = e.toString();
	    message = "Huh? See Line "+(i+1)+" around \""+s+"\"";
	  }//end of catch
 	  
	}//end of while loop
	n = i;
	
}


private int sX(double x){
    return (int)(5*x);
}
private int sY(double y){
    return 125-(int)(5*y);
}
private double angleA(){
    double d=Math.sqrt((sY(ay)-sY(0))*(sY(ay)-sY(0))+(sX(ax)-150)*(sX(ax)-150));
    double acute= (180/Math.PI)*Math.asin((sY(0)-sY(ay))/d);
    if (acute<0) acute *= -1;
    if ((sX(ax)>150)&&(sY(ay)>=sY(0))) acute = acute+180;//bottom right
    if ((sX(ax)>150)&&(sY(ay)<sY(0))) acute = 180-acute;//top right
    if ((sX(ax)<=150)&&(sY(ay)>=sY(0))) acute = 360-acute;//bottom left
   
    return acute;
}
private double angleB(){
    double d=Math.sqrt((sY(by)-sY(0))*(sY(by)-sY(0))+(sX(bx)-150)*(sX(bx)-150));
    double acute= (180/Math.PI)*Math.asin((sY(0)-sY(by))/d);
    if (acute<0) acute *= -1;
    if ((sX(bx)>150)&&(sY(by)>=sY(0))) acute = acute;//bottom right
    if ((sX(bx)>150)&&(sY(by)<=sY(0))) acute = 360-acute;//top right
    if ((sX(bx)<=150)&&(sY(by)>=sY(0))) acute = 180-acute;//bottom left
    if ((sX(bx)<=150)&&(sY(by)<sY(0))) acute = 180+acute;//top left
   
    return acute;
}
private void thickLine(Graphics g, int thickness, int x1, int y1, int x2, int y2){
    int j;
    int k;
    for (j=0; j<thickness; j++) for (k=0; k<thickness; k++){
            g.drawLine(x1+j,yMax-y1+k,x2+j,yMax-y2+k);
    }
}
public void paint( Graphics g ){ 
    setString(list);
    setBackground(bColour); 
    g.setColor(vColour);
    g.setFont(font);
    g.drawString(n+" vectors read", 30, 60 );
    cx=startx;
		cy=yMax-starty;
		if (n>0) for (i=0; i<n; i++){

			thickLine(g,thickness, cx,cy,cx+(int)(sf*vx[i]),cy+(int)(sf*vy[i]) );
			cx=cx+(int)(sf*vx[i]);
			cy=cy+(int)(sf*vy[i]);
		}
		g.setColor(Color.red);
		if (message!=null) g.drawString(message, 30, 330 );
     } 
} 
