//Nathan Viniconis
//CSE269 - SHIN
//Class to do all physical drawing of the program..

import javax.swing.JInternalFrame;
import javax.swing.JDesktopPane;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
import javax.swing.JMenuBar;
import javax.swing.JFrame;
import javax.swing.*;

import java.awt.event.*;
import java.awt.*;
import java.util.Random;

import java.io.*;


public class DrawPanel extends JPanel implements MouseListener, MouseMotionListener	{
	
	GUIdata data;	
	Molecule tempMol;
	Receptor tempRec;
	Membrane tempMem;
	ColorChooser ColorThing = new ColorChooser();
	boolean ColorThingOpen = false;
	int numMito = 0;
	
//For Undo/Redo
	GUIdata[] AllData = new GUIdata[1000];
	int numData = 0;
	int onData = 0;
	int lowData = 0;
	boolean undid = false;
	
	Membrane cirCMem = new Membrane();
	Membrane cirNMem = new Membrane();
	Membrane newMem = new Membrane();

	int viewLayer = 0;
//For Drawing Circles
	int startingX;
	int startingY;
	boolean dragging = false;
	int cirRadius;
	
	int radius = 300;
	int mouseX,mouseY;
	int amount;
	boolean clicked = false;
	
	JLabel mouseText = new JLabel();
	JLabel curObj = new JLabel();
	
	
//********************MAIN CONSTRUCTOR******************	
	public DrawPanel()	{
		addMouseListener(this);
		addMouseMotionListener(this);
	}
//********************UNDO / REDO**********************
	//typeOfAction = 0 for undo and 1 for redo and 2 for update
	public int UnRedo(int typeOfAction)	{
		
		GUIdata temp = new GUIdata();
		
		//Copying and destroying reference.. temp=data
		temp = moveData2Temp(temp, data);
		
		//Used to store some data that shouldn't be in GUIdata
		int tButton, tPage, tType;
		tButton = data.getBUTTON();
		tPage = data.getPAGE();
		tType = data.getTYPE();	

	//if Update
		if(typeOfAction == 2)	{
			
			//numData = The total number of Data's on the stack
			//onData = the number in the stack that is being shown
			//lowData = the lowest number on the stack the User can Access
			
			//if updating and not on the lowest element in array, onData becomes the lowest value
			if(onData != numData)	{
				lowData = onData;
			}
			
			//Copy data to next spot in list
			AllData[onData] = new GUIdata();
			AllData[onData] = moveData2Temp(AllData[onData],temp);
			
			onData++;
			numData = onData;
		}
	//if Undo
		if(typeOfAction == 0)	{
			
			//if someting has been added, and undo's can be made
			if(onData > 1 && onData > lowData)	{
				
				//2 decrements are needed in order to grab right data
				onData--;
				onData--;
				//data = the previous data and destroys reference
				data = moveData2Temp(data,AllData[onData]);
				
				onData++;
			}
			else{
				System.out.println("no more to undo");
			}
		}
	//if Redo
		if(typeOfAction == 1)	{
			//if there are elements above the current
			if(onData < numData)	{
				data = moveData2Temp(data,AllData[onData]);
				
				onData++;
			}
			else{
				System.out.println("No more to redo");
			}
		}
		
		//Puts elements that shouldn't be in data back in data
		data.setcurSelect(tType,tPage,tButton);
		return(0);
	}	
	
//**********MOVE DATA AND DESTROY REFERENCE
	private GUIdata moveData2Temp(GUIdata temp, GUIdata from)	{
		
		int numMol,numRec,numMem;
		int i = 0;
		
		temp.setMultiple(from.getMultiple());
		temp.setTempMol(from.getTempMol());
		temp.setTempRec(from.getTempRec());
		temp.setTempMem(from.getTempMem());
		temp.setCount(from.getCount());
		temp.setAuthInfo(from.getAuthInfo());
		temp.setNumMol(from.getNumMol());
		temp.setNumRec(from.getNumRec());
		temp.setNumMem(from.getNumMem());
		temp.setBID(from.getBID());
		temp.setBwidth(from.getBwidth());
		temp.setBheight(from.getBheight());
		temp.setMemCount(from.getMemCount());
		temp.setMolCount(from.getMolCount());
		temp.setRecCount(from.getRecCount());
		temp.setName(from.getName());
		temp.setOrg(from.getOrg());
		temp.setTitle(from.getTitle());
		temp.setZip(from.getZip());
		temp.setState(from.getState());
		temp.setCity(from.getCity());
		temp.setStreet(from.getStreet());
		temp.setEmail(from.getEmail());
		temp.setDay(from.getDay());
		temp.setMonth(from.getMonth());
		temp.setYear(from.getYear());
		temp.setDefDest(from.getDefDest());
		
		numMol = from.getMolCount();
		numMem = from.getMemCount();
		numRec = from.getRecCount();
		
		while(i < numMol)	{
			temp.setMol(i,from.getMol(i));
			i++;
		}
		i=0;
		while(i < numMem)	{
			temp.setMem(i,from.getMem(i));
			i++;
		}
		i=0;
		while(i < numRec)	{
			temp.setRec(i,from.getRec(i));
			i++;
		}
		return(temp);
	}
	
	
	public void setMembranes(Membrane CM, Membrane NM)	{
		cirCMem = CM;
		cirNMem = NM;
	}
	
//*********************REPLACES PAINT********************
//this is called when .repaint() is called for this class
	public void paintComponent(Graphics g)	{	
		super.paintComponent(g);
		
		Graphics2D g2 = (Graphics2D) g;
      	//Draw Membranes
      	amount = 0;
      	while(amount < data.getMemCount() && viewLayer < 2)	{
      		tempMem = data.getMem(amount);
      		tempMem.draw(g2);
      		amount++;
     	}
     	//Draw Receptors
      	amount = 0;
      	while(amount < data.getRecCount() && viewLayer < 2)	{
      		tempRec = data.getRec(amount);
      		tempRec.draw(g2);
      		amount++;
     	}
      	//Draw Molecules
      	amount = 0;      	
      	while(amount < data.getMolCount() && viewLayer != 1)	{
      		tempMol = data.getMol(amount);
      		tempMol.draw(g2);
      		amount++;
      	}
	}
	
//Sets a reference to the data class so information can be shared.
	public void setData(GUIdata temp)	{
		data = temp;
		ColorThing.setData(data);
		ColorThing.setDrawPanel(this);
	}
	
//***** RETURNS MOUSE COORDS FOR GUI STATUS BAR
	public void getMouseText(JLabel temp)	{
		mouseText = temp;
	}
	public void getCurObj(JLabel temp)	{
		curObj = temp;
	}
	public double getDistance(int X1,int Y1,int X2,int Y2)	{
		int U,V;
		double X;
		
		U = Math.abs(Y1-Y2);
		V = Math.abs(X1-X2);
		
		X = Math.sqrt(U*U+V*V);
		
		return(X);
	}
	public boolean ifOverlapCM(int X, int Y, double Rad)	{
		boolean overlap;
		double Z;
		
		Z = getDistance((int)data.getMem(0).getX(),(int)data.getMem(0).getY(),X,Y);
		if((Z+Rad) > (double)data.getMem(0).getRadius())	{
			return(true);
		}
		else
			return(false);
			
	}
	// type = 0 for NM and 1 for mitos
	public boolean ifOverlapMem(int type,int X, int Y, double Rad)	{
		boolean overlap = false;
		double Z;
		int numOmem = data.getMemCount();
		int i = 1;
		
		if(type == 0)	{
			i=2;
		}
		if(type == 2)	{
			numOmem= numOmem-1;
		}
		while(i < numOmem)	{
			Z = getDistance(X,Y,(int)data.getMem(i).getX(),(int)data.getMem(i).getY());
			
			if(Z > (Rad + (double)data.getMem(i).getRadius()))	{
			}
			else
				overlap = true;
			i++;
		}
		if(overlap)	{
		}
		return(overlap);
	}
	
	public int numMolsInMem(Membrane mems)	{
		int numMols = data.getMolCount();
		int nummols = 0;
		int i=0;
		
		while(i<numMols)	{
			if(mems.containsPoint(data.getMol(i).getX(),data.getMol(i).getY()))	{
				nummols++;
			}
			i++;
		}
		return(nummols);
	}
	
	public void EraseMolArea(int X, int Y, double Rad)	{
		Membrane mem = new Membrane();
		Molecule mol = new Molecule();
		boolean change = true;
		int i,numMol;
		mem.setX(X);
		mem.setY(Y);
		mem.setRadius((int)Rad);
		numMol = data.getMolCount();
		i=0;
		while(i<numMol)	{
			if(mem.containsPoint(data.getMol(i).getX(),data.getMol(i).getY()))	{
				data.Remove(data.getMol(i));
				change = false;
				numMol--;
				
			}
			i++;
			if(change == false)	{
				i=0;
				change = true;
			}
		}
	}
	public void EraseRecArea(int X, int Y, double Rad)	{
		Membrane mem = new Membrane();
		Receptor rec = new Receptor();
		boolean change = true;
		int i,numRec;
		mem.setX(X);
		mem.setY(Y);
		mem.setRadius((int)Rad);
		numRec = data.getRecCount();
		i=0;
		while(i<numRec)	{
			if(mem.containsPoint(data.getRec(i).getX(),data.getRec(i).getY()))	{
				data.Remove(data.getRec(i));
				change = false;
				numRec--;
				
			}
			i++;
			if(change == false)	{
				i=0;
				change = true;
			}
		}
	}
		
		
		
		

//**********************FOR VIEWS****************************

	public void setView(int curView)	{
		viewLayer = curView;
	}

	public boolean IsPtOnMem(int X, int Y)	{
    	int i = 0;	
    	boolean onMem = false;
    	int numOfMems = data.getMemCount();
    	Membrane Bmem = new Membrane();
    	Membrane Smem = new Membrane();

    	while(i<numOfMems && onMem == false)	{
    		Bmem.setX(data.getMem(i).getX());
    		Bmem.setY(data.getMem(i).getY());
    		Smem.setX(data.getMem(i).getX());
    		Smem.setY(data.getMem(i).getY());
    		Bmem.setRadius((int)data.getMem(i).getRadius()+2);
    		Smem.setRadius((int)data.getMem(i).getRadius()-4);
    				
    		if(Bmem.containsPoint(X,Y) && !Smem.containsPoint(X,Y))	{
    			onMem = true;
    		}
    		i++;
    	}
    	return(onMem);
    }
//****************************LISTENERS*****************************	
	public void mouseClicked(MouseEvent e)	{
		//for ken's algorithm
		int clickType = e.getButton();
		int tX = e.getX();
    		int tY = e.getY();
if(clickType==1 && data.getTYPE() != 60)	{
		int rand1,rand2;
		Random Rand = new Random();
		boolean memDown = true;
		boolean CMexists;
		boolean NMexists;
		boolean NoGo= false;
		int numRec;
    			int i = 0;
    			String tID = "";
		if(data.getTYPE() == 2 && data.getMemCount() == 0)	{
			JOptionPane.showMessageDialog(null, "You must place down a Membrane before a Receptor", 
				"alert", JOptionPane.ERROR_MESSAGE);
			memDown = false;
		}
		
		if(data.getMemCount() > 0)	{
			CMexists = true;
		}
		else{
			CMexists = false;
		}
		if(data.getMemCount() > 1)	{
			NMexists = true;
		}
		else{
			NMexists = false;
		}
		if(data.getTYPE() == 0 && CMexists == false && data.getBUTTON() != 1)	{
			JOptionPane.showMessageDialog(null, "You must place down a Cell Membrane before another Membrane", 
				"alert", JOptionPane.ERROR_MESSAGE);
				NoGo = true;
			
		}
		else if(data.getTYPE()==0 && NMexists == false && ( data.getBUTTON() == 3 || data.getBUTTON() == 4))	{
			JOptionPane.showMessageDialog(null, "You must place down a Nuclear Membrane before a Mitochondria", 
				"alert", JOptionPane.ERROR_MESSAGE);
				NoGo = true;
		}
		
		//When circle is not being drawn.....
		if(data.getTYPE() < 3 || data.getTYPE() == 20){

  
			tempMol = data.getTempMol();
			tempRec = data.getTempRec();
			tempMem = data.getTempMem();
      //set up a lot of temporary variables
    		Molecule addMol = new Molecule();
    		Molecule addMol2 = new Molecule();
    		Molecule addMol3 = new Molecule();
    		Molecule addMol4 = new Molecule();
    		Receptor addRec = new Receptor();
    		Membrane addMem = new Membrane(); 
    	
    	//grabs attributes from temp
    		addMol.setColor(tempMol.getColor());
    		addMol.setRadius(4);
    		addMol.setDescription(tempMol.getDescription());
    		addMol.setDestination(tempMol.getDestination());
    		addMol2.setColor(tempMol.getColor());
    		addMol2.setRadius(4);
    		addMol2.setDescription(tempMol.getDescription());
    		addMol.setDestination(tempMol.getDestination());
    		addMol3.setColor(tempMol.getColor());
    		addMol3.setRadius(4);
    		addMol3.setDescription(tempMol.getDescription());
    		addMol.setDestination(tempMol.getDestination());
    		addMol4.setColor(tempMol.getColor());
    		addMol4.setRadius(4);
    		addMol4.setDescription(tempMol.getDescription());
    		addMol.setDestination(tempMol.getDestination());
    		
    		addRec.setColor(tempRec.getColor());
    		addRec.setRadius(10);
    		addRec.setDescription(tempRec.getDescription());
    		addMem.setColor(tempMem.getColor());
    		addMem.setRadius((int)tempMem.getRadius());
    		addMem.setDescription(tempMem.getDescription());
    
 
    	//If molecule
    		if(data.getTYPE() == 1)	{
    	    			
    			//If only one is to be placed
    			if(!data.getMultiple())	{
    				addMol.setPosition(tX,tY);
    				if(viewLayer != 1 && !IsPtOnMem(tX,tY))	{
    					addMol.setColor(tempMol.getColor());
    					data.Add(addMol);
    					UnRedo(2);
    				}
    			}
    			else{
    			//4 are to be placed
    				
    				if(viewLayer != 1)	{
    					rand1 = Rand.nextInt(5);
    					rand2 = Rand.nextInt(5);
    					addMol.setPosition(tX-4-rand1,tY-4-rand2);
    					if(!IsPtOnMem(tX-4-rand1,tY-4-rand2))
    						data.Add(addMol);
    					rand1 = Rand.nextInt(5);
    					rand2 = Rand.nextInt(5);
    					addMol2.setPosition(tX+6+rand1,tY-6-rand2);
    					if(!IsPtOnMem(tX+6+rand1,tY-6-rand2))
    						data.Add(addMol2);
    					rand1 = Rand.nextInt(5);
    					rand2 = Rand.nextInt(5);
    					addMol3.setPosition(tX-6-rand1,tY+6+rand2);
    					if(!IsPtOnMem(tX-6-rand1,tY+6+rand2))
    						data.Add(addMol3);
    					rand1 = Rand.nextInt(5);
    					rand2 = Rand.nextInt(5);
    					addMol4.setPosition(tX+4+rand1,tY+4+rand2);
    					if(!IsPtOnMem(tX+4+rand1,tY+4+rand2))
    						data.Add(addMol4);
    					UnRedo(2);
    				}
    			}
    		}
  		//Receptor Placed
    		else if(data.getTYPE() == 2 && memDown)	{
//********************************************************88
//               Place where ken's algorithm has to go somehow
//**********************************************************
    			int dist,closestcirc=0,closestdist=9999,howfar; 
    			double tempX,tempY;
    			Membrane tempMem;
    			int sX[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
				int sY[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
				int rad[] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
    			int numCir;
    			int Xcoord = tX;
    			int Ycoord = tY;
    			int RecX;
    			int RecY;
    			    			
					if(data.getMem(i).containsPoint(tX,tY))	{
						numCir = data.getMemCount();
						for(i=1;i<numCir;i++)	{
							tempMem = data.getMem(i);
							sX[i]=(int)tempMem.getX();
							sY[i]=(int)tempMem.getY();
							rad[i]=(int)tempMem.getRadius();
						}
					}
					else	{
						numCir = 1;
						tempMem = data.getMem(0);
						sX[0]=(int)tempMem.getX();
						sY[0]=(int)tempMem.getY();
						rad[0] = (int)tempMem.getRadius();
					}
					
					for(int count=0;count<numCir;count++){
						howfar=(int)Math.sqrt((Xcoord-sX[count])*(Xcoord-sX[count])+(Ycoord-sY[count])*(Ycoord-sY[count]))-rad[count];
						if (howfar<closestdist){
    						closestdist=howfar;
    						closestcirc=count;
						}
    				}
   
    				dist = (int)Math.sqrt((Xcoord-sX[closestcirc])*(Xcoord-sX[closestcirc])+
    		               (Ycoord-sY[closestcirc])*(Ycoord-sY[closestcirc]));
    				tempX = ((double)dist-(double)rad[closestcirc])/(double)dist*(double)(Xcoord-sX[closestcirc]);
    				tempY = ((double)dist-(double)rad[closestcirc])/(double)dist*(double)(Ycoord-sY[closestcirc]);

    				RecX = Xcoord-(int)tempX;
    				RecY = Ycoord-(int)tempY;

    				addRec.setBondedTo(data.getMem(closestcirc).getID());
    			
    			addRec.setPosition(RecX,RecY);
    			if(viewLayer != 2)	{
    				data.Add(addRec);
    				UnRedo(2);
    			}
    		}
    	//Membrane Placed
    		else if(data.getTYPE() == 0 && NoGo == false)	{
    			addMem.setPosition(tX,tY);
    		//Adds to cellmembrane iff page=button=1
    			if(data.getPAGE() == 1 && data.getBUTTON() == 1 && data.getMemCount() == 0)	{
    				if(viewLayer !=2 )	{
    					data.AddCM(addMem);
    					int tNumMols = data.getMolCount();
    					int tx,ty;
						Molecule tmol = new Molecule();
						i=0;
						while(i<tNumMols)	{
							tx = (int)data.getMol(i).getX();
							ty = (int)data.getMol(i).getY();
							if(IsPtOnMem(tx,ty) == true)	{
								data.Remove(data.getMol(i));
							}
							i++;
						}
    					UnRedo(2);
    				}
    			}
    		//Adds to nucMembrane iff page=1 and button=2
    			else if(data.getPAGE() == 1 && data.getBUTTON() == 2)	{
    				if(viewLayer !=2 && !ifOverlapCM((int)addMem.getX(),(int)addMem.getY(),addMem.getRadius()) && !ifOverlapMem(0,(int)addMem.getX(),(int)addMem.getY(),addMem.getRadius()))	{
    					data.AddNM(addMem);
    					int tNumMols = data.getMolCount();
    					int tx,ty;
						Molecule tmol = new Molecule();
						i=0;
						while(i<tNumMols)	{
							tx = (int)data.getMol(i).getX();
							ty = (int)data.getMol(i).getY();
							if(IsPtOnMem(tx,ty) == true)	{
								data.Remove(data.getMol(i));
							}
							i++;
						}
						tID = "0001";
     					i = 0;
     					numRec = data.getRecCount();
     					while(i < numRec)	{
     						if(data.getRec(i).getBondedTo() == tID)	{
     							data.Remove(data.getRecBondedTo(tID));
     							i=0;
     							numRec--;
     						}
     						i++;
     					}
    					UnRedo(2);
    					repaint();
    				}
    			}
    			else	{
    				if(viewLayer !=2 && !ifOverlapCM((int)addMem.getX(),(int)addMem.getY(),addMem.getRadius())&& !ifOverlapMem(1,(int)addMem.getX(),(int)addMem.getY(),addMem.getRadius()))	{
    					data.Add(addMem);
    					int tNumMols = data.getMolCount();
    					int tx,ty;
						Molecule tmol = new Molecule();
						i=0;
						while(i<tNumMols)	{
							tx = (int)data.getMol(i).getX();
							ty = (int)data.getMol(i).getY();
							if(IsPtOnMem(tx,ty) == true)	{
								data.Remove(data.getMol(i));
							}
							i++;
						}
							
						    					
    					UnRedo(2);
    				}
    			}	
    		}
    	//curTYPE 20 = ERASE
    		else if(data.getTYPE() == 20)	{
    		//If Molecule
    			if(data.getTypeXY(tX,tY) == "molecule")	{
     				addMol = data.getMolXY(tX,tY);
     				data.Remove(addMol);
     				UnRedo(2);

     			}
     		//If Receptor
     			else if(data.getTypeXY(tX,tY) == "receptor")	{
     				addRec = data.getRecXY(tX,tY);
     				data.Remove(addRec);
     				UnRedo(2);
     			}
     		//If Membrane
     			else if(data.getTypeXY(tX,tY) == "membrane")	{
     				addMem = data.getMemXY(tX,tY);
     				if(addMem.getID() == "0000" || addMem.getID() == "0001")	{
     					System.out.println("no erase, important membrane");
     				}
     				else	{
     					tID = addMem.getID();
     					if(numMolsInMem(addMem) > 0)	{
     						Object[] options2 = { "Yes", "No" };
							int selectedOption2 = JOptionPane.showOptionDialog(null, "Would you Like to Erase the Molecules too?", "Warning", 
								JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE,	
								null, options2, options2[0]);
							if(selectedOption2 ==0)	{
								EraseMolArea((int)addMem.getX(),(int)addMem.getY(),addMem.getRadius());
								EraseRecArea((int)addMem.getX(),(int)addMem.getY(),addMem.getRadius());
							}
						}	
						if(data.getDefDest() == addMem.getID())	{
							data.setDefDest("0001");
						}
     					data.Remove(addMem);
     					i=0;
     					while(i<data.getMolCount())	{
     						if(data.getMol(i).getDestination().compareTo(addMem.getID())==0)	{
     							data.getMol(i).setDestination("0001");
     						}
     						i++;
     					}
     					i = 0;
     					numRec = data.getRecCount();
     					while(i < numRec)	{
     						if(data.getRec(i).getBondedTo() == tID)	{
     							addRec = data.getRecBondedTo(tID);
     							data.Remove(addRec);
     							i=0;
     							numRec--;
     						}
     						i++;
     					}
     					UnRedo(2);
     				}
     			}
    		}
		}
}
//Right Click
else if(data.getTYPE() != 60)	{
		int nMol = data.getMolCount();
		int nMem = data.getMemCount();
		int nRec = data.getRecCount();
		boolean found = false;
		int i=0;
		while(i<nMol && !found)	{
			if(data.getMol(i).containsPoint(tX,tY))	{
//Color change with Molecule..
			

        //Find name of Molecule and put in String
        		String molName = data.getMol(i).getDescription();
  
				
		//Set up window
				ColorThing.setDescription(molName);
				ColorThing.setOldColor(data.getMol(i).getColorC());

				
				if(ColorThing.isShowing() == true)	{
					ColorThing.hide();
				}
				
				ColorThing.pack();
				ColorThing.show();
           
            found = true;
			}
			i++;
		}
//Color change with Receptor..
		i=0;
		while(i<nRec && !found)	{
			if(data.getRec(i).containsPoint(tX,tY))	{
				
				
				String recName = data.getRec(i).getDescription();
  
				
		//Set up window
				ColorThing.setDescription(recName);
				ColorThing.setOldColor(data.getRec(i).getColorC());

				
				if(ColorThing.isShowing() == true)	{
					ColorThing.hide();
				}
				
				ColorThing.pack();
				ColorThing.show();
				
				
				
				
				
				found = true;
			}
			i++;
		}
//Color change with Membrane..		
		i = nMem-1;
		while(i >=0 && !found)	{
			if(data.getMem(i).containsPoint(tX,tY))	{
				
				String memName = data.getMem(i).getDescription();
  
				
		//Set up window
				ColorThing.setDescription(memName);
				ColorThing.setOldColor(data.getMem(i).getColorC());

				
				if(ColorThing.isShowing() == true)	{
					ColorThing.hide();
				}
				
				ColorThing.pack();
				ColorThing.show();
				found = true;
			}
			i--;
		}
		
		
		
		
		
		
}
//for choose Dest
else	{
	int mmm = data.getMemCount()-1;
	int i =1;
	boolean fou = false;
	while(mmm >= i && !fou)	{
		if(data.getMem(mmm).containsPoint(tX,tY))	{
			
			data.setDefDest(data.getMem(mmm).getID());
			fou = true;
		
		}
		mmm--;
	}
	if(fou==false)	{
		data.setDefDest("0001");
	
	}
	UnRedo(2);
}
			
		repaint();
	}	

	public void mousePressed(MouseEvent e)	{
		newMem = new Membrane();
		boolean NoGo = false;
		
		//when a custom membrane has been selected
		if((data.getTYPE()==40 || data.getTYPE()==41 || data.getTYPE()==42 || data.getTYPE() == 50) && e.getButton() == 1) 	{
			newMem.setRadius(20);
			if(data.getTYPE() == 50)	{
				newMem.setRadius(1);
			}

			newMem.setPosition(e.getX(),e.getY());
		
			if(data.getTYPE()==40 )	{
				if(data.getMemCount() > 0)	{
					newMem.setColorC(data.getMem(0).getColorC());
					newMem.setDescription(data.getMem(0).getDescription());
				}
				else	{
					newMem.setColor("99FF00");
					newMem.setDescription("Cellular Cytoplasm");
				}
				
				dragging = true;
			}
			else if(data.getTYPE()==41 && !ifOverlapCM(e.getX(),e.getY(),20) && !ifOverlapMem(0,e.getX(),e.getY(),20))	{
				
				if(data.getMemCount() > 1)	{
					newMem.setColorC(data.getMem(1).getColorC());
					newMem.setDescription(data.getMem(1).getDescription());
				}
				else	{
					newMem.setColor("FF0099");
					newMem.setDescription("Nuclear Cytoplasm");
				}
				dragging = true;
			}
			else if(data.getTYPE()==42 && !ifOverlapCM(e.getX(),e.getY(),20) && !ifOverlapMem(1,e.getX(),e.getY(),20))	{
				newMem.setColor("FFFF66");
				numMito++;
				newMem.setDescription("Mitochondria G"+numMito+" Cytoplasm");
				dragging = true;
			}
			else if(data.getTYPE()==50)	{
				newMem.setColor("000000");
				dragging = true;
				data.Add(newMem);
			}
		}
	}
	public void mouseReleased(MouseEvent e)	{
		dragging = false;
		int tNumMols = data.getMolCount();
    		int tx,ty,i;
			Molecule tmol = new Molecule();
			i=0;
			while(i<tNumMols)	{
				tx = (int)data.getMol(i).getX();
				ty = (int)data.getMol(i).getY();
				if(IsPtOnMem(tx,ty) == true)	{
					data.Remove(data.getMol(i));
				}
				i++;
			}
		if(data.getTYPE()==40 || data.getTYPE()==41 || data.getTYPE()==42)	{			
			UnRedo(2);
		}
		//*************** 5050500550500505050505
		else if(data.getTYPE()==50 && e.getButton()==1)	{
			int mm = data.getMemCount()-1;
			EraseMolArea((int)data.getMem(mm).getX(),(int)data.getMem(mm).getY(),data.getMem(mm).getRadius());
			EraseRecArea((int)data.getMem(mm).getX(),(int)data.getMem(mm).getY(),data.getMem(mm).getRadius());
			data.Remove(data.getMem(mm));
			UnRedo(2);
		}
		repaint();
	}
	public void mouseEntered(MouseEvent e)	{
	}
	public void mouseExited(MouseEvent e)	{
	}
	//changes the label for the mouse tracker
	public void mouseMoved(MouseEvent m)	{	
		int curX,curY;
		
		curX = m.getX();
		curY = m.getY();

		mouseText.setText(" " + curX + "," + curY);
		//Mouseover shows Stats
		curObj.setText("Type: "+data.ReturnTag(curX,curY)+" , ID:" + data.getIDXY(curX,curY));
	}
	public void mouseDragged(MouseEvent e){
		if(dragging && viewLayer < 2)	{          
			cirRadius = (int)Math.sqrt((e.getX()-newMem.getX())*(e.getX()-newMem.getX())+(e.getY()-newMem.getY())*(e.getY()-newMem.getY()));
			
			if(cirRadius < 15)	
				cirRadius = 15;
			//CUSTOM CELL MEMBRANE
			if( data.getTYPE() == 40)	{
				newMem.setRadius(cirRadius);
				data.AddCM(newMem);
			}
			//CUSTOM NUCLEAR MEMBRANE
			else if( data.getTYPE() == 41)	{
				if(!ifOverlapCM((int)newMem.getX(),(int)newMem.getY(),cirRadius )&& !ifOverlapMem(0,(int)newMem.getX(),(int)newMem.getY(),cirRadius) )	{
					newMem.setRadius(cirRadius);
					data.AddNM(newMem);
				
					String tID = "0001";
					Receptor addRec = new Receptor();
					int numRec = data.getRecCount();
					int i = 0;
					while(i < numRec)	{
     					if(data.getRec(i).getBondedTo() == tID)	{
     						addRec = data.getRecBondedTo(tID);
     						data.Remove(addRec);
     						i=0;
     						numRec--;
     					}
     					i++;
     				}
     		 	}
     		 	else if(cirRadius < newMem.getRadius())	{
     		 		newMem.setRadius(cirRadius);
     		 		data.AddNM(newMem);
     		 	}
					
			}
			//CUSTOM MEMBRANE
			else if(data.getTYPE() == 42)	{
				boolean erase = false;
				double radius = newMem.getRadius();
				
				
				if(!ifOverlapCM((int)newMem.getX(),(int)newMem.getY(),cirRadius) &&
				   !ifOverlapMem(2,(int)newMem.getX(),(int)newMem.getY(),cirRadius))	{
				   		newMem.setRadius((int)radius);
				   		if(data.ifExists(newMem))	{
				   			data.Remove(newMem);
				   		}
				   		newMem.setRadius(cirRadius);
				   		data.Add(newMem);
				}
				else if(cirRadius < radius)	{
					newMem.setRadius((int)radius);
					if(data.ifExists(newMem))	{
						data.Remove(newMem);
					}
					newMem.setRadius(cirRadius);
					data.Add(newMem);
				}				
			}	
			else if(data.getTYPE() == 50)	{
				
				if(data.ifExists(newMem))	{
				   	data.Remove(newMem);
				}
				   	newMem.setRadius(cirRadius);
				   	data.Add(newMem);
			}
					
		}	
		repaint();
	}
}




				