/*PLEASE DO NOT EDIT THIS CODE*/
/*This code was generated using the UMPLE 1.20.2.4305 modeling language!*/


import java.util.*;
import java.awt.*;
import java.awt.Canvas;

// line 84 "diagram.ump"
public class Simulation extends Canvas
{

  //------------------------
  // MEMBER VARIABLES
  //------------------------

  //------------------------
  // CONSTRUCTOR
  //------------------------

  public Simulation()
  {
    super();
  }

  //------------------------
  // INTERFACE
  //------------------------

  public void delete()
  {}

  // line 93 "diagram.ump"
   public void initGraphics(){
    setSize(200, 200);
    setBackground(Color.white);
  }

  // line 98 "diagram.ump"
   public static  void main(String [] args){
    Thread.currentThread().setUncaughtExceptionHandler(new UmpleExceptionHandler());
    Thread.setDefaultUncaughtExceptionHandler(new UmpleExceptionHandler());
    //GraphicsProgram class is now a type of canvas
	      //since it extends the Canvas class
	      //lets instantiate it
	    Simulation GP = new Simulation();  

	    GP.initGraphics();
	    //create a new frame to which we will add a canvas
	    Frame aFrame = new Frame();
	    aFrame.setSize(600,800);
	    
	    //add the canvas
	    aFrame.add(GP);
		    
		aFrame.setVisible(true);
	    java.util.List<Atom> atoms =  new java.util.ArrayList<Atom>();
	    double timeStep = 0.001;
	 	SimulationSystem theSystem = new SimulationSystem(timeStep);
	    EnergyState simpleState = new EnergyState(20);
	    for(int i = 0; i < 20; i++){
	      atoms.add(new Atom(new Vector(i,i,0),new Vector(0.001,0,0),simpleState,1,theSystem));
	    } 

	    for(;true;){    
	    	GP.timeStep(theSystem);
	    	GP.drawSystem(theSystem);
		}
  }

  // line 127 "diagram.ump"
   public void drawSystem(SimulationSystem aSystem){
    Graphics g = this.getGraphics();
	    	update(g);
    		for(int i = 0; i < aSystem.numberOfAtoms();i++ ) {
    			Atom atom = aSystem.getAtom(i);
    			atom.draw(g);
    		}
  }

  // line 136 "diagram.ump"
   public void timeStep(SimulationSystem aSystem){
    java.util.List<Pair<Atom,PhysicalObject>> collisionList = new java.util.ArrayList<Pair<Atom,PhysicalObject>>(); 
    	Pair<Atom,PhysicalObject> collision;
    	for(int i = 0; i < aSystem.numberOfAtoms();i++ ) {
      		Atom atom = aSystem.getAtom(i);
    	  	collision = calculateNewPosition(atom,aSystem);
    	  	if(collision.getRight() == null){
    	  		collisionList.add(collision);	
    	  	}    	  	
    	  	processSingularInteractions(aSystem,atom,collision);
    	  	calculateKineticEnergy(atom);
   		}
   		processNonSingularInteractions(aSystem,collisionList);
  }

  // line 158 "diagram.ump"
   public PhysicalObject checkForCollisions(Atom atom, SimulationSystem aSystem){
    PhysicalObject collided = null;
    	for(int i = 0; i < aSystem.numberOfPhysicalObjects();i++ ) {
  			PhysicalObject object = aSystem.getPhysicalObject(i);
  			if(object.collides(atom)){
  				collided = object;
  				break;
  			} 
  		}
  		return collided;
  }

  // line 170 "diagram.ump"
   public void calculateKineticEnergy(Atom atom){
    atom.setKineticEnergy(atom.getMass()*atom.getMass()*atom.getVelocity().mag2()*0.5);
  }

  // line 175 "diagram.ump"
   public void processSingularInteractions(SimulationSystem aSystem, Atom atom, Pair<Atom,PhysicalObject> collision){
    
  }

  // line 179 "diagram.ump"
   public void processNonSingularInteractions(SimulationSystem aSystem, java.util.List<Pair<Atom,PhysicalObject>> collisionList){
    
  }

  // line 184 "diagram.ump"
   public void paint(Graphics g){
    
  }
  
  //------------------------
  // DEVELOPER CODE - PROVIDED AS-IS
  //------------------------
  
  // line 150 diagram.ump
  public  Pair<Atom,PhysicalObject> calculateNewPosition (Atom atom, SimulationSystem aSystem) 
  {
    Vector newPosition = atom.getVelocity().copy().mult(aSystem.getTimestep()).add(atom.getPosition());
  		atom.setPosition(newPosition);
  		PhysicalObject collidedObject = checkForCollisions(atom,aSystem);
  		return new Pair<Atom,PhysicalObject>(atom,collidedObject);
  }

  
  public static class UmpleExceptionHandler implements Thread.UncaughtExceptionHandler
  {
    public void uncaughtException(Thread t, Throwable e)
    {
      translate(e);
      if(e.getCause()!=null)
      {
        translate(e.getCause());
      }
      e.printStackTrace();
    }
    public void translate(Throwable e)
    {
      java.util.List<StackTraceElement> result = new java.util.ArrayList<StackTraceElement>();
      StackTraceElement[] elements = e.getStackTrace();
      try
      {
        for(StackTraceElement element:elements)
        {
          String className = element.getClassName();
          String methodName = element.getMethodName();
          boolean methodFound = false;
          int index = className.lastIndexOf('.')+1;
          try {
            java.lang.reflect.Method query = this.getClass().getMethod(className.substring(index)+"_"+methodName,new Class[]{});
            UmpleSourceData sourceInformation = (UmpleSourceData)query.invoke(this,new Object[]{});
            for(int i=0;i<sourceInformation.size();++i)
            {
              int distanceFromStart = element.getLineNumber()-sourceInformation.getJavaLine(i)-(("main".equals(methodName))?2:0);
              if(distanceFromStart>=0&&distanceFromStart<=sourceInformation.getLength(i))
              {
                result.add(new StackTraceElement(element.getClassName(),element.getMethodName(),sourceInformation.getFileName(i),sourceInformation.getUmpleLine(i)+distanceFromStart));
                methodFound = true;
                break;
              }
            }
          }
          catch (Exception e2){}
          if(!methodFound)
          {
            result.add(element);
          }
        }
      }
      catch (Exception e1)
      {
        e1.printStackTrace();
      }
      e.setStackTrace(result.toArray(new StackTraceElement[0]));
    }
  //The following methods Map Java lines back to their original Umple file / line    
    public UmpleSourceData Atom_draw(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(20).setJavaLines(144).setLengths(4);}
    public UmpleSourceData Vector_mag2(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(41).setJavaLines(81).setLengths(4);}
    public UmpleSourceData Vector_mult(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(45).setJavaLines(86).setLengths(7);}
    public UmpleSourceData Vector_mag(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(37).setJavaLines(76).setLengths(4);}
    public UmpleSourceData Vector_add(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(51).setJavaLines(94).setLengths(4);}
    public UmpleSourceData Vector_copy(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(54).setJavaLines(99).setLengths(4);}
    public UmpleSourceData PhysicalObject_collides(){ return new UmpleSourceData().setFileNames("diagram.ump"," diagram.ump").setUmpleLines(64, 67).setJavaLines(89, 94).setLengths(4, 4);}
    public UmpleSourceData Simulation_initGraphics(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(92).setJavaLines(33).setLengths(5);}
    public UmpleSourceData Simulation_timeStep(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(135).setJavaLines(81).setLengths(15);}
    public UmpleSourceData Simulation_drawSystem(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(126).setJavaLines(71).setLengths(9);}
    public UmpleSourceData Simulation_calculateKineticEnergy(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(169).setJavaLines(110).setLengths(4);}
    public UmpleSourceData Simulation_paint(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(183).setJavaLines(125).setLengths(4);}
    public UmpleSourceData Simulation_processNonSingularInteractions(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(178).setJavaLines(120).setLengths(4);}
    public UmpleSourceData Simulation_processSingularInteractions(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(174).setJavaLines(115).setLengths(4);}
    public UmpleSourceData Simulation_checkForCollisions(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(157).setJavaLines(97).setLengths(12);}
    public UmpleSourceData Simulation_main(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(97).setJavaLines(39).setLengths(31);}
    public UmpleSourceData Pair_getLeft(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(206).setJavaLines(40).setLengths(4);}
    public UmpleSourceData Pair_Pair(){ return new UmpleSourceData().setFileNames("diagram.ump"," diagram.ump").setUmpleLines(195, 201).setJavaLines(28, 34).setLengths(5, 5);}
    public UmpleSourceData Pair_getRight(){ return new UmpleSourceData().setFileNames("diagram.ump").setUmpleLines(207).setJavaLines(45).setLengths(4);}

  }
  public static class UmpleSourceData
  {
    String[] umpleFileNames;
    Integer[] umpleLines;
    Integer[] umpleJavaLines;
    Integer[] umpleLengths;
    
    public UmpleSourceData(){
    }
    public String getFileName(int i){
      return umpleFileNames[i];
    }
    public Integer getUmpleLine(int i){
      return umpleLines[i];
    }
    public Integer getJavaLine(int i){
      return umpleJavaLines[i];
    }
    public Integer getLength(int i){
      return umpleLengths[i];
    }
    public UmpleSourceData setFileNames(String... filenames){
      umpleFileNames = filenames;
      return this;
    }
    public UmpleSourceData setUmpleLines(Integer... umplelines){
      umpleLines = umplelines;
      return this;
    }
    public UmpleSourceData setJavaLines(Integer... javalines){
      umpleJavaLines = javalines;
      return this;
    }
    public UmpleSourceData setLengths(Integer... lengths){
      umpleLengths = lengths;
      return this;
    }
    public int size(){
      return umpleFileNames.length;
    }
  } 
}