import java.awt.*;
import java.applet.Applet;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.ItemListener;
import java.awt.event.ItemEvent;

public class DNS extends Applet implements Runnable, ActionListener{


	Thread myThread;

	Button pwrbtn, reset, choice1;
	
	boolean frozen=true;
	int j;
	int i;
	int Count;
	int Count2;
	int time = 30000000;
	int control;
	int control_local;
	int control_root;
	int control_interm;

	Choice scene;
	Choice root_type;
	Choice local_type;
	Choice interm_type;

	String name =" ";
	String name_local =" ";
	String name_root =" ";		
	String name_interm =" ";


	public void init()		
	{			
		setLayout (new FlowLayout(FlowLayout.CENTER,35,50));
				   
		
		InitAllVars();	
		scene = new Choice();
		scene.add("Root name server has the Destination IP address cached");
  		scene.add("Root name server has the Authoritative name server cached");
  		scene.add("Root name server has an Intermediate name server cached");
  		scene.add("Local name server has the Destination IP address cached");
		
		scene.addItemListener(new ItemListener(){
			public void itemStateChanged(ItemEvent e) {
			repaint();
			InitAllVars();
			stop();	
			pwrbtn.setLabel("Start");
			pwrbtn.setActionCommand("ON");	
			pwrbtn.setEnabled(true);
			}
			});
   

		root_type = new Choice();
		//root_type.add("Query type - Root N.S.");
		root_type.add("Iterative");
 		root_type.add("Recursive");
		
		root_type.addItemListener(new ItemListener(){ 
			public void itemStateChanged(ItemEvent e) {
			repaint();
			InitAllVars();
			stop();	
			pwrbtn.setLabel("Start");
			pwrbtn.setActionCommand("ON");	
			pwrbtn.setEnabled(true);
			}
			});	  



		local_type = new Choice();
		//local_type.add("Query type - Local N.S.");
		local_type.add("Iterative");
 		local_type.add("Recursive");
		
		local_type.addItemListener(new ItemListener(){
			public void itemStateChanged(ItemEvent e) {
			repaint();
			InitAllVars();
			stop();	
			pwrbtn.setLabel("Start");
			pwrbtn.setActionCommand("ON");	
			pwrbtn.setEnabled(true);
			}
			});


		interm_type = new Choice();
		//interm_type.add("Query type - Intermediate N.S.");
		interm_type.add("Iterative");
 		interm_type.add("Recursive");
		
		interm_type.addItemListener(new ItemListener(){
			public void itemStateChanged(ItemEvent e) {
			repaint();
			InitAllVars();
			stop();	
			pwrbtn.setLabel("Start");
			pwrbtn.setActionCommand("ON");	
			pwrbtn.setEnabled(true);
			}
			});
	


	//Adding different buttons
	pwrbtn = new Button("Start");
	pwrbtn.setActionCommand("ON");
	pwrbtn.addActionListener(this);
	reset = new Button("Reset");
	reset.setActionCommand("rst");
	reset.addActionListener(this);
	add(scene);
	add(local_type);
	add(root_type);
	//add(interm_type);
	add(pwrbtn);	
	add(reset);
	
	}



	//Simulation started
	public void start()
	{
	if (frozen)
	{
	}
	else
	{
	if (myThread == null)
	myThread = new Thread(this);			
	myThread.start();
	}
	}
		
	
	//Simulation stopped	
	public void stop()
	{
	myThread = null;
	repaint();
	}	
		
	public void run()
	{
	control = 0;
	name = scene.getSelectedItem();	
	name_local = local_type.getSelectedItem();
	name_root = root_type.getSelectedItem();
	name_interm = interm_type.getSelectedItem();
			if(name == "Local name server has the Destination IP address cached")
			{
			control = 1;
			}	
			if(name == "Root name server has the Destination IP address cached")
			{
			control = 2;
			}
			if(name == "Root name server has an Intermediate name server cached")
			{
			control = 3;
			}
			if(name == "Root name server has the Authoritative name server cached")
			{
			control = 4;
			}

			if(name_local == "Iterative")
			control_local = 1;
			else if(name_local =="Recursive")
			control_local = 2;
			if(name_root == "Iterative")
			control_root = 1;
			else if(name_root =="Recursive")
			control_root = 2;
			if(name_interm == "Iterative")
			control_interm = 1;
			else if(name_interm =="Recursive")
			control_interm = 2;
		
	Thread CurThread = Thread.currentThread();
	
			
		
			
		pwrbtn.setEnabled(false);
		
		//repaint();
		
		stop();	
		}	
		
	
		public void actionPerformed(ActionEvent e)
		//Action of buttons defined.
		{
		String cmd = e.getActionCommand();
		if (cmd=="ON") 
			{
			frozen=false;
			pwrbtn.setLabel("Stop");
			pwrbtn.setActionCommand("OFF");
			start();
			}
		else if (cmd=="OFF")
		//Stops animation
			{
			frozen=true;
			pwrbtn.setLabel("Start");
			pwrbtn.setActionCommand("ON");
			repaint();
			stop();
			}
		else if (cmd=="rst") 
			{
			pwrbtn.setLabel("Start");
			pwrbtn.setActionCommand("ON");	
			pwrbtn.setEnabled(true);
			InitAllVars();
			repaint();	
			stop();	
			}	
		
		}

		public void InitAllVars()	//Initializes all variables
		{	
		Count= 0 ;
		Count2 =0;		
		control = 0;
		control_local =0;
		control_root = 0;
		control_interm = 0;		
		}


		public void paint(Graphics g)
		//All paint jobs are done here.
		{		
			Color c1 = new Color(00,66,33);
			Color c2 = new Color(50,190,15);
			
		g.setColor(Color.black);
		g.drawString("Enter scenario type",185,45);
   		g.drawString("Local name server",392,45);
		g.drawString("Root name server",515,45);
		
		//The Root name server
		g.setColor(c1);
   		g.fillRect(225,175,50,50);
		g.drawString("Root name server",285,200);

		//The Local name server
		g.setColor(c1);
   		g.fillRect(50,300,50,50);
		g.drawString("Local name server",110,325);

		//The Intermediate Name Server
		g.setColor(c1);
   		g.fillRect(400,300,50,50);
		g.drawString("Intermediate",390,365);
		g.drawString("name server",390,380); 

		//The Authoritative Name Server
		g.setColor(c1);
   		g.fillRect(600,300,50,50);
		g.drawString("Authoritative",660,325);
		g.drawString("name server",660,340);

		//The Destination
		g.setColor(c2);
   		g.fillRect(600,500,50,50);
		g.drawString("Destination host",660,525);

		//The Requesting host
		g.setColor(c2);
   		g.fillRect(50,450,50,50);
		g.drawString("Requesting host",110,475);

		
		     if(control == 1)
			{
			host_local(g);
			g.setColor(Color.green);
   			g.fillOval(50,300,50,50);
			for(i=0; i<time; i++)
				{
				}
			local_host(g);
			control =0;
			}

		    else if(control == 2)
			{
			host_local(g);
			g.setColor(Color.white);
			g.fillOval(50,300,50,50);
			for(i=0; i<time; i++)
				{
				}	
			local_root(g);
			g.setColor(Color.green);
			g.fillOval(225,175,50,50);
			for(i=0; i<time; i++)
				{
				}
			root_local(g);
			local_host(g);
			control =0;
			}

		    else if(control == 3)
			{
			host_local(g);
			g.setColor(Color.white);
			g.fillOval(50,300,50,50);
			for(i=0; i<time; i++)
				{
				}	
			local_root(g);
			g.setColor(Color.white);
			g.fillOval(225,175,50,50);
			for(i=0; i<time; i++)
				{
				}
				
				if(control_local == 1) //local calls interative
				{
				root_local(g);
				local_inter(g);
				g.setColor(Color.white);
				g.fillOval(400,300,50,50);
				for(i=0; i<time; i++)
				{
				}
				inter_local(g);
				local_autho(g);
				g.setColor(Color.green);
				g.fillOval(600,300,50,50);
				for(i=0; i<time; i++)
				{
				}
				autho_local(g);
				local_host(g);
				}
				
				else if(control_local == 2) //local calls recursive
				{
				root_inter(g);
				g.setColor(Color.white);
				g.fillOval(400,300,50,50);
				for(i=0; i<time; i++)
				{
				}
					if(control_root == 1)
					{
					inter_root(g);
					root_autho(g);
					g.setColor(Color.green);
					g.fillOval(600,300,50,50);
					for(i=0; i<time; i++)
					{
					}
					autho_root(g);
					root_local(g);
					local_host(g);
					}
	
					else if(control_root == 2)
					{
					inter_autho(g);
					g.setColor(Color.green);
					g.fillOval(600,300,50,50);
					for(i=0; i<time; i++)
					{
					}
					autho_inter(g);
					inter_root(g);
					root_local(g);
					local_host(g);
					}
				
				}
			control = 0;
			}



		     else if(control == 4)
			{
			host_local(g);
			g.setColor(Color.white);
			g.fillOval(50,300,50,50);
			for(i=0; i<time; i++)
				{
				}	
			local_root(g);
			g.setColor(Color.white);
			g.fillOval(225,175,50,50);
			for(i=0; i<time; i++)
				{
				}
				
				if(control_local == 1) //local calls interative
				{
				root_local(g);
				local_autho(g);
				g.setColor(Color.green);
				g.fillOval(600,300,50,50);
				for(i=0; i<time; i++)
				{
				}
				autho_local(g);
				local_host(g);
				control = 0;
				}
				
				else if(control_local == 2) //local calls recursive
				{
				root_autho(g);
				g.setColor(Color.green);
				g.fillOval(600,300,50,50);
				for(i=0; i<time; i++)
				{
				}
				autho_root(g);
				root_local(g);
				local_host(g);
				control = 0;
				}
			
			}

		}				

			// end of paint







		public void host_local(Graphics g){
		Count = 420;
			for(j=0; j<4; j++)
			{
			g.setColor(Color.green);
   			g.fillRect(50,Count,10,8);
			Count = Count - 20;
				for(i=0; i<time; i++)
				{
				}
			}
		}

		
		
		public void local_host(Graphics g){
		Count = 360;
			for(j=0; j<4; j++)
			{
			g.setColor(Color.red);
			g.fillRect(80,Count,10,8);
			Count = Count + 20;
				for(i=0; i<time; i++)
				{
				}
			}
		}		


		public void local_root(Graphics g){
		Count = 50;
		Count2 = 275;
		for(j=0; j<6; j++)
		{
			g.setColor(Color.green);
   			g.fillRect(Count,Count2,10,8);
			Count = Count + 29;
			Count2 = Count2 - 20;
				for(i=0; i<time; i++)
				{
				}	
		}
		}


		public void root_local(Graphics g){
		Count = 195;
		Count2 = 205;
		for(j=0; j<5; j++)
		{
			g.setColor(Color.red);
   			g.fillRect(Count,Count2,10,8);
			Count = Count - 29;
			Count2 = Count2 + 18;
				for(i=0; i<time; i++)
				{
				}	
		}
		}


		public void root_inter(Graphics g){
		Count = 285;
		Count2 = 175;
		for(j=0; j<6; j++)
		{
			g.setColor(Color.green);
   			g.fillRect(Count,Count2,10,8);
			Count = Count + 29;
			Count2 = Count2 + 20;
				for(i=0; i<time; i++)
				{
				}	
		}
		}


		public void inter_root(Graphics g){
		Count = 400;
		Count2 = 280;
		for(j=0; j<5; j++)
		{
			g.setColor(Color.red);
   			g.fillRect(Count,Count2,10,8);
			Count = Count - 27;
			Count2 = Count2 - 20;
				for(i=0; i<time; i++)
				{
				}	
		}
		}


		public void inter_autho(Graphics g){
		Count = 456;
		Count2 = 300;
		for(j=0; j<5; j++)
		{
			g.setColor(Color.green);
   			g.fillRect(Count,Count2,10,8);
			Count = Count + 29;
				for(i=0; i<time; i++)
				{
				}	
		}
		}

		
		public void autho_inter(Graphics g){
		Count = 570;
		Count2 = 330;
		for(j=0; j<5; j++)
		{
			g.setColor(Color.red);
   			g.fillRect(Count,Count2,10,8);
			Count = Count - 29;
				for(i=0; i<time; i++)
				{
				}	
		}
		}

		public void local_inter(Graphics g){
		Count = 110;
		Count2 = 300;
		for(j=0; j<10; j++)
		{
			g.setColor(Color.green);
   			g.fillRect(Count,Count2,10,8);
			Count = Count + 29;
				for(i=0; i<time; i++)
				{
				}	
		}
		}

		public void inter_local(Graphics g){
		Count = 370;
		Count2 = 330;
		for(j=0; j<10; j++)
		{
			g.setColor(Color.red);
   			g.fillRect(Count,Count2,10,8);
			Count = Count - 29;
				for(i=0; i<time; i++)
				{
				}	
		}
		}

		public void root_autho(Graphics g){
		Count = 289;
		Count2 = 175;
		for(j=0; j<12; j++)
		{
			g.setColor(Color.green);
   			g.fillRect(Count,Count2,10,8);
			Count = Count + 28;
				for(i=0; i<time; i++)
				{
				}	
		}
		
		for(j=0; j<6; j++)
		{
			g.setColor(Color.green);
   			g.fillRect(630,Count2,10,8);
			Count2 = Count2 + 21;
				for(i=0; i<time; i++)
				{
				}	
		}
		
		
		}


		public void autho_root(Graphics g){
		Count = 600;
		Count2 = 280;
		for(j=0; j<3; j++)
		{
			g.setColor(Color.red);
   			g.fillRect(Count,Count2,10,8);
			Count2 = Count2 - 24;
				for(i=0; i<time; i++)
				{
				}	
		}
		for(j=0; j<12; j++)
		{
			g.setColor(Color.red);
   			g.fillRect(Count,Count2,10,8);
			Count = Count - 28;
				for(i=0; i<time; i++)
				{
				}	
		}

		}

		public void local_autho(Graphics g){
		Count = 115;
		Count2 = 355;
		for(j=0; j<3; j++)
		{
			g.setColor(Color.green);
   			g.fillRect(Count,Count2,10,8);
			Count2 = Count2 + 20;
			Count = Count + 28;
				for(i=0; i<time; i++)
				{
				}	
		}
		for(j=0; j<13; j++)
		{
			g.setColor(Color.green);
   			g.fillRect(Count,Count2,10,8);
			Count = Count + 31;
				for(i=0; i<time; i++)
				{
				}	
		}

		for(j=0; j<4; j++)
		{
			g.setColor(Color.green);
   			g.fillRect(Count,Count2,10,8);
			Count2 = Count2 - 20;
				for(i=0; i<time; i++)
				{
				}	
		}

		}



		public void autho_local(Graphics g){
		Count = 630;
		Count2 = 355;

		for(j=0; j<4; j++)
		{
			g.setColor(Color.red);
   			g.fillRect(Count,Count2,10,8);
			Count2 = Count2 + 20;
				for(i=0; i<time; i++)
				{
				}	
		}
		
		for(j=0; j<14; j++)
		{
			g.setColor(Color.red);
   			g.fillRect(Count,Count2,10,8);
			Count = Count - 31;
				for(i=0; i<time; i++)
				{
				}	
		}

		
		for(j=0; j<5; j++)
		{
			g.setColor(Color.red);
   			g.fillRect(Count,Count2,10,8);
			Count2 = Count2 - 20;
			Count = Count - 27;
				for(i=0; i<time; i++)
				{
				}	
		}
		
		}
}