package ui.view;

import classes.*;
import classes.comparator.UnitGraphPointComperator;
import interfaces.GraphEditable;
import interfaces.GraphEditable.Graphtype;
import interfaces.LocalMode;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import ui.controller.Control;
import ui.controller.SingletonControl;
import ui.model.Model;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Path2D;
import java.awt.geom.Point2D;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.ListIterator;

/**
 * This Class represents a Graph where the User can model the behavior of
 * elements and switches over time.
 *
 * @author Tom Troppmann
 */
public class UnitGraph extends JPanel implements MouseListener, MouseMotionListener, ComponentListener {

    private static final long serialVersionUID = 1L;
	
	
	// Normal Settings
	private int border = 4;
	private int clickThreshholdSquared = 25;
	
	// Display Settings
	/**
	 * The size of a dot in the graph.
	 * It should be at least 1.
	 * */
	int dotSize = 8;
	/** The Color of a dot in the graph. */
	Color dotColor = Color.blue;
	Color editDotColor = new Color(255, 119, 0);
	
	//Intern Variables
	//TODO: JavaDoc
	private LinkedList<UnitGraphPoint> actualGraphPoints = new LinkedList<UnitGraphPoint>();
	private Graphtype actualGraphType;
	private GraphEditable actualElement;
	Position editPosition;
	boolean editMode = false;
	private enum pointType {Normal, StartPoint, EndPoint};
	pointType editPoint = pointType.Normal;
	
	//Maybe Needed
	private Model model;
	private Control controller;
	
	
	private int widthWithBorder, heightWithBorder;
	
	
	
	
	
	
    /**
     * Constructor.
     *
     * @param model   the Model
     * @param control the Controller
     */
    public UnitGraph(final Model model, Control control) {
        setCursor(Cursor.getPredefinedCursor(Cursor.CROSSHAIR_CURSOR));
        this.controller = control;
        this.model = model;
        this.setBackground(Color.WHITE);

        this.addMouseListener(this);
        this.addMouseMotionListener(this);
        this.addComponentListener(this);
    }
    /**
     * When the UnitGraph should represent a new GraphEditable Element.
     * Its Updates the Graph and give access to the Element.
     * @param element
     */
    public void initNewElement(GraphEditable element)
    {
    	overrideUnitGraph(element.getStateGraph());
    	actualGraphType = element.getGraphType();
    	actualElement = element;
    	repaint();
    }
    
    
    
    /**
     * Paints the Graph, the Grid, the actual Line fro the currentIteration
     * @param g Graphics
     */
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2D = (Graphics2D) g;
        drawGrid(g2D);
        g2D.setColor(Color.BLACK);
        g2D.setRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
        g2D.setStroke(new BasicStroke(2));
        drawUnitGraph(g2D);
        g2D.setColor(dotColor);
        if(editMode)
        {
        	drawUnitGraphPointsReleased(g2D);
        }else
        {
        	 drawUnitGraphPoints(g2D);
        }
        g2D.setColor(dotColor);
        g2D.setStroke(new BasicStroke(1));
        drawCurrentIterartionLine(g2D);
    }

    // Draw Methods only to let the User see the changes. Nothing its saved here or changed.
    /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * This Methods draws the UnitGraph whether its a boolGraph or a doubleGraph.
     * @param g to draw.
     */
    private void drawUnitGraph(Graphics2D g) {
    	switch(actualGraphType) {
    	case boolGraph:
    		if(editMode)
    			drawBoolGraphInEditMode(g);
    		else
    			drawBoolGraph(g);
    		break;
    	case doubleGraph:
    		if(editMode)
    			drawDoubleGraphInEditMode(g);
    		else
    			drawDoubleGraph(g);
    		break;
    	default:
    		throw new UnsupportedOperationException();
    	}
    }
    /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * This Methods draws the UnitGraphPoints of the UnitGraph.
     * @param g to draw.
     */
    private void drawUnitGraphPoints(Graphics2D g) {
    	g.setColor(dotColor);
    	for(UnitGraphPoint p : actualGraphPoints){
    		drawDot(g, p.displayedPosition);
    	}
    }
    /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * This Methods draws the UnitGraphPoints of the UnitGraph when its in EditMode.
     * @param g to draw.
     */
    private void drawUnitGraphPointsReleased(Graphics2D g) {
    	drawUnitGraphPoints(g);
    	g.setColor(editDotColor);
    	drawDot(g, editPosition);
    }
    /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * This Methods draws the Grid on the Canvas.
     * @param g2D to draw.
     */
	private void drawGrid(Graphics2D g2D) {
        g2D.setStroke(new BasicStroke(1));
        g2D.setColor(Color.lightGray);
        int amountOfLines = 10;
        int width = widthWithBorder + 2 * border;
        int height = heightWithBorder;
        for(int i = 0; i<=amountOfLines; i++)
        {
        	int linehieght = (int) (((double)i/ (double) amountOfLines) * (double) height) + border;
        	g2D.drawLine(0, linehieght, width, linehieght);
        }
	}
    
	 /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * This Method draws the CurrentIterationLine.
     * @param g2D to draw.
     */
    private void drawCurrentIterartionLine(Graphics2D g)
    {
    	int cur = model.getCurIteration();
    	int max = model.getIterations();
    	double where;
    	if(!this.isUsingLocalPeriod()) {
    		where = ((double) cur)/((double) max);
    	}
    	else
    	{
    		int lPeriod = this.getLocalPeriod();
    		where = ((double) cur%lPeriod)/((double) lPeriod);
    	}
    	Position oben = new Position(border + (int)(where * widthWithBorder), 0);
    	Position unten = new Position(border + (int)(where * widthWithBorder), 2 * border + heightWithBorder);
    	drawLine(g,oben,unten);
    	
    }
    
    /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * This Method draws a line between two Positions on the Canvas.
     * @param g2D to draw.
     * @param start the Position of one end of the line to draw. 
     * @param end the other Ends Position of the Line to draw.
     */
    private void drawLine(Graphics2D g, Position start, Position end)
    {
    	Path2D.Double path = new Path2D.Double();
    	path.moveTo(start.x, start.y);
    	path.lineTo(end.x, end.y);
    	g.draw(path);
    }
    
    /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * Initialize a Cubic BezierCurve.
     * @param start The Position to start the Curve.
     */
    private Path2D.Double initBezier(Position start) {
    	//Good Source for basic understanding for Bezier Curves
        //http://www.theappguruz.com/blog/bezier-curve-in-games
    	Path2D.Double path = new Path2D.Double();
    	path.moveTo(start.x, start.y);
		return path;
    }
    /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * Calculate the Path of a the Cubic BezierCurve with the special controlPoints to make the wanted behavior.
     * @param path the path of the Bezier.
     * @param actaul the actual Position of the Path.
     * @param target the end Position of the Curve.
     */
    private void curveTo(Path2D.Double path, Position actual, Position target) {
         double mitte = (actual.x + target.x)* 0.5;
         path.curveTo(mitte, actual.y, mitte, target.y, target.x, target.y);
    }
    /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * Draws a Dot at a Position.
     * @param g to draw.
     * @param p the position of the Dot.
     */
    private void drawDot(Graphics2D g, Position p)
    {    	
    	g.fillOval(p.x -dotSize/2, p.y-dotSize/2, dotSize, dotSize);
    }
    
    
    /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * This Method draws the UnitGraph as BoolGraph.
     * @param g2D to draw.
     */
    private void drawBoolGraph(Graphics2D g) {
    	if(actualGraphPoints.size() <= 1) return;
    	LinkedList<Position> cornerPoints =  new LinkedList<Position>();
     	ListIterator<UnitGraphPoint> iter = actualGraphPoints.listIterator();
     	Position actual = actualGraphPoints.getFirst().displayedPosition;
     	Path2D.Double path = new Path2D.Double();
     	path.moveTo(actual.x, actual.y);
     	while (iter.hasNext())
    	{
    		Position target = iter.next().displayedPosition;
    		//BooleanConnection
    		path.lineTo(target.x, actual.y); //line to corner
    		cornerPoints.add(new Position(target.x, actual.y)); //save corner
    		path.lineTo(target.x, target.y); //line to next Point
    		
    		actual = target;
    	}
     	g.draw(path);
     	//Draw the Points on the Corner that dont exist in Data but should be visual
     	g.setColor(dotColor);
     	for(Position p: cornerPoints)
     	{
     		drawDot(g, p);
     	}
     	
    }
    /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * This Method draws the UnitGraph as BoolGraph in EditMode.
     * @param g2D to draw.
     */
    private void drawBoolGraphInEditMode(Graphics2D g) {
    	LinkedList<Position> before = new LinkedList<Position>();
     	LinkedList<Position> after = new LinkedList<Position>();
     	for(UnitGraphPoint p: actualGraphPoints)
     	{
     		if(p.displayedPosition.x < editPosition.x)
     			before.add(p.displayedPosition);
     		else
     			after.add(p.displayedPosition);
     	}    	
     	g.setColor(Color.BLACK);
     	drawBoolGraphFromList(g, before);
     	g.setColor(Color.BLACK);
     	drawBoolGraphFromList(g, after);
     	//EditGraph
     	LinkedList<Position> middle = new LinkedList<Position>();
     	if(!before.isEmpty()) middle.add(before.getLast());
     	middle.add(editPosition);
    	if(!after.isEmpty()) middle.add(after.getFirst());
    	
    	g.setColor(editDotColor);
    	drawBoolGraphFromList(g, middle);
    	drawSnappingHint(g);
    }
    
    /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * This Method draws a red Hint to signal the User the snapping of the hovered Point under the Cursor in EditMode.
     * @param g2D to draw.
     */
    private void drawSnappingHint(Graphics2D g)
    {
    	//ColorHint
    	g.setColor(Color.RED);
    	//Threshhold Line
    	final float dash1[] = {10.0f};
        final BasicStroke dashed =new BasicStroke(2.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f);
        g.setStroke(dashed);
        
        
        int halfheight =  border + heightWithBorder / 2;
        g.drawLine(0, halfheight , widthWithBorder + 2 * border, halfheight);
        //Threshhold Text
        g.drawString("Snapping Threshold", 10, halfheight - 2);
    }
    
    
    
    /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * This Method draws a partial Graph from a Position List as BoolGraph.
     * @param g2D to draw.
     * @param list the PositionList to draw a BoolGraph
     */
	private void drawBoolGraphFromList(Graphics2D g, LinkedList<Position> list) {
		if(list.size() <= 1) return;
     	ListIterator<Position> iter = list.listIterator();
      	LinkedList<Position> cornerPoints =  new LinkedList<Position>();
     	Position actual = list.getFirst();
     	Path2D.Double path = new Path2D.Double();
     	path.moveTo(actual.x, actual.y);
     	while (iter.hasNext())
    	{
    		Position target = iter.next();
    		//BooleanConnection
    		path.lineTo(target.x, actual.y); //line to corner
    		cornerPoints.add(new Position(target.x, actual.y)); //save corner
    		path.lineTo(target.x, target.y); //line to next Point
    		actual = target;
    	}
     	g.draw(path);
    	g.setColor(dotColor);
     	for(Position p: cornerPoints)
     	{
     		drawDot(g, p);
     	}
	}
    
	  /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * This Method draws the UnitGraph as DoubleGraph.
     * @param g2D to draw.
     */
    private void drawDoubleGraph(Graphics2D g) {
    	if(actualGraphPoints.isEmpty()) throw new IndexOutOfBoundsException("A Graph Without Points is not supportet jet");
    	ListIterator<UnitGraphPoint> iter = actualGraphPoints.listIterator();
    	Position actual = iter.next().displayedPosition;
    	Path2D.Double path = this.initBezier(actual);
    	while (iter.hasNext())
    	{
    		Position target = iter.next().displayedPosition;
    		this.curveTo(path, actual, target);
    		actual = target;
    	}
    	g.draw(path);
    	
    }
    /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * This Method draws the UnitGraph as DoubleGraph in EditMode.
     * @param g2D to draw.
     */
    private void drawDoubleGraphInEditMode(Graphics2D g) {
     	LinkedList<Position> before = new LinkedList<Position>();
     	LinkedList<Position> after = new LinkedList<Position>();
     	for(UnitGraphPoint p: actualGraphPoints)
     	{
     		if(p.displayedPosition.x < editPosition.x)
     			before.add(p.displayedPosition);
     		else
     			after.add(p.displayedPosition);
     	}    	
     	drawUnitGraphFromList(g, before);
     	drawUnitGraphFromList(g, after);
     	//EditGraph
     	LinkedList<Position> middle = new LinkedList<Position>();
     	if(!before.isEmpty()) middle.add(before.getLast());
     	middle.add(editPosition);
    	if(!after.isEmpty()) middle.add(after.getFirst());
    	
    	g.setColor(editDotColor);
    	drawUnitGraphFromList(g, middle);
    }
    
    /**
     * Helper Method to draw the UnitGraphPanel. {@link UnitGraph#paintComponent(Graphics)}
     * <p>
     * This Method draws a partial Graph from a Position List as DoubleGraph.
     * @param g2D to draw.
     * @param list the PositionList to draw a DoubleGraph
     */
	private void drawUnitGraphFromList(Graphics2D g, LinkedList<Position> list) {
		if(list.size() <= 1) return;
     	ListIterator<Position> iter = list.listIterator();
     	Position actual = list.getFirst();
     	Path2D.Double path = this.initBezier(actual);
     	while (iter.hasNext())
    	{
    		Position target = iter.next();
    		curveTo(path, actual, target);
    		actual = target;
    	}
     	g.draw(path);
	}
  
    //Under the hood functions to calculate and function the 
    /**
     * A unitgraphpoint have a x and y position to store the data of a graph point.
     * Also it have a displayposition to store the Position of the GraphPoints on the Canvas. 
     * e.g. when the canvas has 500 width and 200 height a GraphPoint with the X=0.5 and Y=1.0 should have a displayposition of (250,3) when border is 3.
     */
    private void updateRepresentativePositions()
    {
    	for(UnitGraphPoint p : actualGraphPoints) {
    		p.calcDisplayedPosition(border, widthWithBorder, heightWithBorder);
    	}
    }
    /**
     * Takes a List of GraphPoints and convert it to the actual UnitGraphPoints with displayposition in the {@link #actualGraphPoints}
     * @param stateCurve the list of GraphPoint
     */
    private void overrideUnitGraph(LinkedList<Point2D.Double> stateCurve) {
    	actualGraphPoints.clear();
    	for(Point2D.Double p: stateCurve){
    		actualGraphPoints.add(new UnitGraphPoint(p));
    	}
    	updateRepresentativePositions();
    }
    
    /**
     * When the PanelSize Change the width and height to calculate the drawings have to be adjusted.
     */
    private void calculateWidthHeight()
    {
    	widthWithBorder = this.getWidth() - 2 * border;
    	heightWithBorder = this.getHeight() - 2 * border;
    }
    
    /**
     * Save the actualGraphPoint List to the GraphEditable Element.
     */
    private void saveGraph() {
    	LinkedList<Point2D.Double> actual = actualElement.getStateGraph();
    	actual.clear();
    	for(UnitGraphPoint p: actualGraphPoints)
    	{
    		actual.add(p.getPoint());
    	}
    	actualElement.sampleGraph();
    }
    /**
     * Remove a UnitGraphPoint from the UnitGraphPoint list ({@link #actualGraphPoints} when its near a given Position.
     * @param mPosition
     */
    private void removePointNearPosition(Position mPosition) {
    	ListIterator<UnitGraphPoint> iter = actualGraphPoints.listIterator();
    	while (iter.hasNext())
    	{
    		if(near(mPosition,iter.next().displayedPosition))
    		{
    			iter.remove();
    			break;
    		}
    	}
    }
    
    
    /**
     * Determine if the Point is a StartPoint , EndPoint or a NormalPoint a.k.a. in between Points.
     * @param mPosition The Position to check.
     */
    private void  detectStartEndPoint(Position mPosition)
    {
    	UnitGraphPoint first = actualGraphPoints.getFirst();
    	UnitGraphPoint last = actualGraphPoints.getLast();
    	if(near(mPosition, first.displayedPosition)) editPoint = pointType.StartPoint;
    	else if(near(mPosition, last.displayedPosition))  editPoint = pointType.EndPoint;
    	else editPoint = pointType.Normal;
    }

    /**
     * Determine if a Point is near the Cursor (depends on Mode what near means). To detect if it should grab the Point or create a new Point. 
     * @param actual
     * @param target
     * @return
     */
	private boolean near(Position actual, Position target) {
		switch(actualGraphType)
		{
		case boolGraph: //Distance only with X 
			int xDis = target.x - actual.x;
			return xDis * xDis  < clickThreshholdSquared;
		case doubleGraph:
			return actual.squareDistance(target) < clickThreshholdSquared;
		default:
			return false;
		}	
	}
    
	/**
	 * When the Mouse Drag a Point it updates each time the position.
	 * @param newPosition
	 */
    private void updateEditPointPosition(Position newPosition) {
    	//make it in the bounds of the UnitGraph no Point out of the Border
    	Position currentPosition = setInBounds(newPosition);
    	if(editPoint != pointType.Normal) attachToBorder(currentPosition);
    	if(actualGraphType == Graphtype.boolGraph) snapBoolean(currentPosition);
    	this.editPosition = currentPosition;
    }
    
    
    /**
     * No Point on the UnitGraph should exit the UnitGraph.
     * @param p the Position
	 * @return the updated Position.
     */
	private Position setInBounds(Position p) {
		p.clampX(border, border + widthWithBorder);
		p.clampY(border, border + heightWithBorder);
		return p;
	}
    
	
	
	/**
	 * For Switches the Point have to be Snap to the Top or the Bottem.
	 * @param p the Position
	 * @return the updated Position.
	 */
	private Position snapBoolean(Position p)
	{
		if (p.y < border + heightWithBorder / 2) {
			p.y = border;
		} else {
			p.y = border + heightWithBorder;
		}
		return p;
	}
	
	
	/**
	 * The First Point has to be at 0(LeftSide) and Last Point has to be at 1(RightSide).  
	 * @param p the Position
	 * @return the updated Position.
	 */
	private Position attachToBorder(Position p)
	{
		switch(editPoint)
		{
		case StartPoint:
			p.x = border;
			break;
		case EndPoint:
			p.x = border + widthWithBorder;
			break;
		default:
			break;
		}
		return p;
	}
	/**
	 * Insert a Position in the UnitGraphList at the right order.
	 * Its sorted based on the xValues.
	 * @param pos The new UnitGraphPoints Position
	 */
    private void insertNewGraphPoint(Position pos)
    {
    	setInBounds(pos);
    	ListIterator<UnitGraphPoint> iter2 = actualGraphPoints.listIterator();
    	while (iter2.hasNext())
    	{
    		Position tempPosition = iter2.next().displayedPosition;
    		if(pos.x <= tempPosition.x)
    		{
    			//previous to go back a position to make the new point before the the Position with greater X
    			iter2.previous();
    			iter2.add(generateUnitGraphPoint(pos));
    			break;
    		}
    	}
    	if(!iter2.hasNext()) //if behind last point
    	{
    		iter2.add(generateUnitGraphPoint(pos));
    	}
    }
    /**
     * Generate a UnitGraphPoint from a normal Position in the UnitGraph.
     * @param pos the normal pos with xValues from 0..Width and yValues from 0..Height
     * @return a UnitGraphPoint
     */
	private UnitGraphPoint generateUnitGraphPoint(Position pos) {
		UnitGraphPoint temp = new UnitGraphPoint((double) (pos.x - border) / (double) widthWithBorder,
				1 - (double) (pos.y - border) / (double) heightWithBorder, true);
		temp.displayedPosition = pos;
		return temp;
	}

    /**
     * Update the Point Position 
     */
	@Override
    public void mouseDragged(MouseEvent e) {
    	updateEditPointPosition(new Position(e.getPoint()));
    	repaint();
    }

    @Override
    public void mouseMoved(MouseEvent e) {
    }

    @Override
    public void mouseClicked(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

    /**
     * The First Step.
     * When LeftMouseButton its checks if a point is to grab under the cursor or create a new Point. Then enter EditMode.
     * When RightMouseButton its delete a point if its under the Curser.
     */
    @Override
    public void mousePressed(MouseEvent e) {
		Position mPosition = new Position(e.getPoint());
		if (e.getButton() == MouseEvent.BUTTON3) {
			// RightMouseButtonEvent
			detectStartEndPoint(mPosition);
			if (editPoint == pointType.Normal) {
				removePointNearPosition(mPosition);
				repaint();
			}
			editMode = false;

		} else if (e.getButton() == MouseEvent.BUTTON1) {
			// LeftMouseButtonEvent
			detectStartEndPoint(mPosition);
			removePointNearPosition(mPosition);
			updateEditPointPosition(mPosition);
			editMode = true;
			repaint();
		}
	}

    /**
     * The last step to save the Changes.
     * Its insert the Hovering Point and exit EditMode.
     */
    @Override
    public void mouseReleased(MouseEvent e) {
    	if(editMode)
    	{
    		this.insertNewGraphPoint(editPosition);
    		editMode = false;
    		repaint();
    	}
    	saveGraph();
    }

    /**
     * When the Component is Resized.
     *
     * @param e ComponentEvent
     */
    public void componentResized(ComponentEvent e) {
    	calculateWidthHeight();
    	updateRepresentativePositions();
        repaint();
    }

    @Override
    public void componentHidden(ComponentEvent e) {
    }

    @Override
    public void componentMoved(ComponentEvent e) {

    }

    @Override
    public void componentShown(ComponentEvent e) {
    }

    /**
     * Resets the graph to normal.
     */
    public void reset() {
       	if(this.actualElement != null) {
       		actualElement.reset();
       		overrideUnitGraph(actualElement.getStateGraph());
       		repaint();
       	}
       	
    }


    
    //LocalMode access methods...
    //To access a element from the GUI for the LocalMode
	public void setUseLocalPeriod(boolean state) {
		if(this.actualElement != null) {
			((LocalMode) actualElement).setUseLocalPeriod(state);
       	}
	}

	public void setLocalPeriod(int localLength) {
		if(this.actualElement != null) {
			((LocalMode) actualElement).setLocalPeriod(localLength);
       	}
	}
	
	public int getLocalPeriod() {
		if(this.actualElement != null) {
			return ((LocalMode) actualElement).getLocalPeriod();
       	}
		return -1;
	}
	
	public boolean isUsingLocalPeriod() {
		if(this.actualElement != null) {
			return ((LocalMode) actualElement).isUsingLocalPeriod();
       	}
		return false;
	}

	
	/**
	 * @deprecated
	 * @param cps
	 */
	public void repaintGraph(AbstractCpsObject cps) {
		System.out.println("repaintGraph");
	}
   
	/**
	 * @deprecated
	 * @param obj
	 */
	public void update(ArrayList<AbstractCpsObject> obj) {
		
	}
    

}