package myuml;

import javax.swing.JComponent;
import com.borland.jbcl.layout.XYConstraints;
import com.umlet.control.Constants;
import java.util.ArrayList;
import java.io.Serializable;
import java.awt.Component;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import javax.swing.JOptionPane;

/**
 * <p>Title: Generación de Coreografías de Servicios Web</p>
 *
 * <p>Description: Superclase de la que heredan las demás clases </p>
 *
 * <p>Copyright: Copyright (c) 2007</p>
 *
 * <p>Company: UCLM</p>
 *
 * @version 1.0
 */
public class MyObjects extends JComponent implements Serializable {

    protected String name, id;

    protected XYConstraints xyc;

    protected MyListener listener = new MyListener();

    //Listas para almacenar los mensajes enviados y recibidos
    public ArrayList sendedMsg = new ArrayList();
    public ArrayList receivedMsg = new ArrayList();

    //Lista para almacenar los mensajes incluidos dentro de un frame
    public ArrayList includeMsg = new ArrayList();

    //Lista para los frames anidados dentro de este frame
    public ArrayList includeFrm = new ArrayList();

    //Color del componente
    protected Color col;

    //Variables asociadas al objeto
    public ArrayList variables = new ArrayList();

    /**
     * Crea un objeto y añade el controlador para los eventos del ratón
     *
     * @param c coordenadas del objeto
     */
    public MyObjects(XYConstraints c) {

        name = "";
        xyc = c;
        addListeners();
        col = Color.black;
        variables = new ArrayList();
    }


    /**
    * Método para añadir los controladores de eventos
    */
    protected void addListeners(){
        this.addMouseListener(listener);
        //this.addMouseMotionListener(listener);
    }

    /**
     * Método que devuelve el color del objeto
     *
     * @return color del objeto
     */
    public Color getCol(){
        return col;
    }

    /**
     * Método que permite establecer el color del objeto
     *
     * @param c color del objeto
     */
    public void setCol(Color  c){
        col = c;
    }

    /**
     * Método que devuelve el nombre que se le haya asociado a cada componente
     *
     * @return nombre del objeto
     */
    public String getName(){
        return name;
    }


    /**
     * Método que permite asociar un nombre al objeto con el que estemos
     * trabajando
     *
     * @param s nombre del objeto
     */
    public void setName(String s){
        name = s;
    }

    /**
     * Método que asigna un identificador único a cada objeto involucrado en el
     * diagrama
     *
     * @param ident cadena que contiene el identificador del objeto
     */
    public void setID(String ident){
         id=ident;
    }

    /**
     * Método que devuelve el identificador que tiene asignado cada objeto
     *
     * @return Devuelve una cadena que contiene el identificador del objeto
     */
    public String getID(){
         return id;
    }

    public XYConstraints getXY(){
        return xyc;
    }
    /**
    * Método que actualiza la posición de los mensajes que enviamos y
    * recibimos
    *
    * @param x coordenada x del elemento que se ha borrado
    * @param pos posición en la lista del elemento actual
    * @param lista lista de componentes
    */
    public void updatePosition(int x, int pos, Component[] lista) {

        //Para los mensajes enviados
        for(int i=0; i<sendedMsg.size(); i++){
            MyMessage m = (MyMessage)sendedMsg.get(i);

            //Se debe comprobar si el destino es un elemento anterior
            //o posterior que se ha desplazado
            boolean desplazado = false;

            for (int e = 0; e < lista.length; e++){

                //Para todos aquellos que se hayan desplazado
                if(x < lista[e].getX()){

                    if((lista[e] instanceof MyObjects) && ((MyObjects)lista[e]).receivedMsg.contains(m)){

                        desplazado = true;
                        break;

                    }

                }

            }

            //Si no se ha desplazado
            if(!desplazado){
                m.xyc.setWidth(m.xyc.getWidth() - 300);
            }
            //Si se ha desplazado
            else{
                m.xyc.setX(m.xyc.getX() - 300);
            }

        }

        //Para los mensajes recibidos
        for(int i=0; i<receivedMsg.size(); i++){
            MyMessage m = (MyMessage)receivedMsg.get(i);

            //Sólo nos interesa el caso en que el que realice el envío
            //no se haya desplazado
            boolean desplazado = true;

            for (int e = 0; e < lista.length; e++){

                //Para todos aquellos que no se hayan desplazado
                if(x > lista[e].getX()){

                    if((lista[e] instanceof MyObjects) && ((MyObjects)lista[e]).sendedMsg.contains(m)){

                        desplazado = false;
                        break;

                    }
                }
            }

            //Si no se ha desplazado
            if(!desplazado){
                m.xyc.setWidth(m.xyc.getWidth() - 300);
            }

        }
    }


    /**
   * Añade un mensaje a la lista de mensajes enviados
   *
   * @param msg mensaje que se añade
   * @param y coordenada de la altura a la que se quiere poner el mensaje
   */
    public void addSendMessage(MyMessage msg, int y){

        JPanel panel = (JPanel) msg.getParent();
        Component lista[] = panel.getComponents();

        boolean after_exception = false;
        boolean inside_frame = false;

        for (int i = 0; i < lista.length; i++) {

            if (lista[i] instanceof MyFrame && ((MyObjects) lista[i]).getName().compareTo("exception") == 0){

                System.out.println("height:"+((MyObjects) lista[i]).getHeight());
                System.out.println("y:"+y);
                System.out.println("y_inicial:"+((MyObjects) lista[i]).getY());
                System.out.println("y_final:"+(((MyObjects) lista[i]).getY() + ((MyObjects) lista[i]).getHeight()));

            }

            if (lista[i] instanceof MyFrame && ((MyObjects) lista[i]).getName().compareTo("exception") == 0 &&
                    y > ((MyObjects) lista[i]).getY()) {

                after_exception = true;
            }

            if (lista[i] instanceof MyFrame && y > ((MyObjects) lista[i]).getY() &&
                    y <
                    (((MyObjects) lista[i]).getY() + ((MyObjects) lista[i]).getHeight())) {

                    inside_frame = true;

            }
        }

        //Primero se debe mirar que no se haya colocado más abajo de un frame
        //de excepción a no ser que esté dentro
        if(after_exception && !inside_frame){

            //eliminar mensaje
            panel.remove(0);

            //Mostrar mensaje de error
            JOptionPane optionPane= new JOptionPane();
            Object[] options = {"Ok"};
            optionPane.showOptionDialog(optionPane,"Nothing can be placed after exception","Error",optionPane.YES_NO_OPTION,optionPane.INFORMATION_MESSAGE, null, options, null);

        }

        else{

            sendedMsg.add(msg);
            msg.source = this;
            msg.xyc.setX(xyc.getX() + xyc.getWidth() / 2);
            msg.xyc.setY(xyc.getY() + y);

        }
    }


    /**
     * Añade un mensaje a la lista de mensajes recibidos
     *
     * @param msg mensaje que se recibe
     */
    public void addReceiveMessage(MyMessage msg){
        receivedMsg.add(msg);
        msg.dest = this;

        //Modificar para que pinte el mensaje en la coordenada y adecuada según
        //su posición

        //Ver el número de mensajes que ya existan con una coordenada y menor
        //También se deben contar los frames
        int contador = 0;
        JPanel panel = (JPanel) msg.getParent();
        Component lista [] = panel.getComponents();

        ArrayList id_frames = new ArrayList();

        for (int i = 0; i < lista.length; i++) {

            if (lista[i] instanceof MyMessage && msg.xyc.getY() > ((MyMessage)lista[i]).getY()){
                if(!(msg.getID().compareTo(((MyMessage)lista[i]).getID())==0))
                    contador = contador + 1;
            }

            if (lista[i] instanceof MyFrame && msg.xyc.getY() > ((MyFrame)lista[i]).getY()){

                if(msg.xyc.getY() > (((MyFrame)lista[i]).getY()) + ((MyFrame)lista[i]).getHeight()){

                    if(((MyFrame)lista[i]).getName().compareTo("alt_else")!=0)
                        contador = contador + 2;
                    else
                        contador = contador + 3;

                }
                else{
                    //Está dentro de un frame
                    id_frames.add(((MyFrame)lista[i]).getID());

                    contador = contador + 1;

                }
            }

        }

        //Guardar la coordenada Y antes de modificarla
        int coord_y = msg.xyc.getY();

        XYConstraints c = msg.getXY();

        //Coordenada y en la que se va a dibujar el mensaje
        c.setY(140 + 30*contador);

        msg.editXYconstraints(c);

        msg.xyc.setWidth(xyc.getX() + xyc.getWidth()/2 - msg.xyc.getX());
        if(msg.xyc.getWidth()>0){
            msg.setLocation(msg.xyc.getX(), msg.xyc.getY());
            msg.setSize(msg.xyc.getWidth(), msg.xyc.getHeight());
        }
        else{
            msg.xyc.setX(msg.dest.getX() + msg.dest.getWidth()/2);
            msg.setLocation(msg.xyc.getX(), msg.xyc.getY());
            msg.setSize(-msg.xyc.getWidth(), msg.xyc.getHeight());
        }

        //Ver si está en la parte else de un alt_else para modificar la coordenada del mensaje
        for (int i = 0; i < lista.length; i++) {

            if (lista[i] instanceof MyFrame && coord_y <= ((MyFrame)lista[i]).getY()+((MyFrame)lista[i]).getHeight()){

                if(id_frames.contains(((MyFrame)lista[i]).getID())){

                    if(((MyFrame)lista[i]).getName().compareTo("alt_else")==0){

                        ArrayList separadores = ((MyFrame)lista[i]).separadores;

                        if(((Integer)separadores.get(0)).intValue() + lista[i].getY() < coord_y){

                            XYConstraints c_men = (msg.getXY());
                            c_men.setY(c_men.getY() + 30);

                            msg.editXYconstraints(c_men);


                        }

                    }

                }

            }

        }

        //También se debe desplazar la coordenada Y de los mensajes posteriores

        for (int i = 0; i < lista.length; i++) {

            if (lista[i] instanceof MyMessage && coord_y <= ((MyMessage)lista[i]).getY()){

                if(!(msg.getID().compareTo(((MyMessage)lista[i]).getID())==0)){

                    XYConstraints c2 = ((MyMessage)lista[i]).getXY();
                    c2.setY(c2.getY() + 30);

                    ((MyMessage) lista[i]).editXYconstraints(c2);

                }

            }

            //También se deben desplazar los frames posteriores
            if (lista[i] instanceof MyFrame && coord_y <= ((MyFrame)lista[i]).getY()+((MyFrame)lista[i]).getHeight()){

                if(!(id_frames.contains(((MyFrame)lista[i]).getID()))){

                    XYConstraints c2 = ((MyFrame)lista[i]).getXY();
                    c2.setY(c2.getY() + 30);

                    ((MyFrame) lista[i]).editXYconstraints(c2);

                }

                //En caso de que se haya dibujado el mensaje dentro del frame
                //se amplia su altura
                else{

                    XYConstraints c2 = ((MyFrame)lista[i]).getXY();
                    c2.setHeight(c2.getHeight() + 30);

                    ((MyFrame) lista[i]).editXYconstraints(c2);

                    //También se debe añadir a la lista de mensaejes incluidos
                    ((MyFrame) lista[i]).includeMessage(msg);

                    //En el caso de que el frame sea "par" o "alt" se deben tener también
                    //en cuenta las líneas de separación internas

                    if(((MyFrame)lista[i]).getName().compareTo("par")==0 || ((MyFrame) lista[i]).getName().compareTo("alt") == 0){

                        boolean posterior = false;
                        ArrayList separadores = ((MyFrame)lista[i]).separadores;

                        //Desplazar los separadores posteriores en caso de que los haya
                        for(int j = 0; j < separadores.size(); j ++){

                            if(((Integer)separadores.get(j)).intValue() + lista[i].getY() > coord_y){

                                int valor = ((Integer)separadores.get(j)).intValue();

                                separadores.remove(j);
                                separadores.add(j,new Integer(valor + 30));

                                posterior = true;

                            }

                        }

                        //Dibujar debajo del mensaje si no hay ninguna línea posterior
                        if(!posterior){

                            ((MyFrame) lista[i]).addSeparador(new Integer(msg.xyc.getY() -
                                                            ((MyFrame) lista[i]).getY() + 28));
                        }

                    }

                    //En el caso de que el frame sea "alt_else" se debe tener en cuenta la línea
                    //de separación interna

                    if(((MyFrame)lista[i]).getName().compareTo("alt_else")==0){

                        ArrayList separadores = ((MyFrame)lista[i]).separadores;

                        //Desplazar el separador si es posterior
                        if(((Integer)separadores.get(0)).intValue() + lista[i].getY() > coord_y){

                            int valor = ((Integer)separadores.get(0)).intValue();

                            separadores.remove(0);
                            separadores.add(0,new Integer(valor + 30));

                        }

                    }


                }

            }

        }

        //Ampliar la línea de los actors y lifelines
        for (int i = 0; i < lista.length; i++) {

            if (lista[i] instanceof MyLifeLine){

                MyLifeLine lin = ((MyLifeLine)lista[i]);

                XYConstraints c2 = lin.getXY();

                c2.setHeight(c2.getHeight() + 30);

                lin.editXYconstraints(c2);

            }

            if (lista[i] instanceof MyActor){

                MyActor lin = ((MyActor)lista[i]);

                XYConstraints c2 = lin.getXY();

                c2.setHeight(c2.getHeight() + 30);

                lin.editXYconstraints(c2);

            }


        }


        //Se debe repintar el panel que contiene a los objetos
        panel.repaint();
        panel.updateUI();

    }

    /**
  * Añade un mensaje a la lista de mensajes de un frame
  *
  * @param msg mensaje que se añade
  */
   public void includeMessage(MyMessage msg){

       includeMsg.add(msg);

   }

   /**
  * Añade un frame a la lista de frames de un frame
  *
  * @param frm frame que se añade
  */
   public void includeFrame(MyFrame frm){

       includeFrm.add(frm);

   }


   /**
   * Añade un frame al diagrama
   *
   * @param frm frame que se añade
   * @param y coordenada de la altura a la que se quiere poner el frame
   */
    public void addPositionFrame(MyFrame frm, int y){

        JPanel panel = (JPanel) frm.getParent();
        Component lista[] = panel.getComponents();

        boolean after_exception = false;
        boolean inside_frame = false;

        for (int i = 0; i < lista.length; i++) {

            if (lista[i] instanceof MyFrame && ((MyObjects) lista[i]).getName().compareTo("exception") == 0){

                System.out.println("height:"+((MyObjects) lista[i]).getHeight());
                System.out.println("y:"+y);
                System.out.println("y_inicial:"+((MyObjects) lista[i]).getY());
                System.out.println("y_final:"+(((MyObjects) lista[i]).getY() + ((MyObjects) lista[i]).getHeight()));

            }


            if (lista[i] instanceof MyFrame && ((MyObjects) lista[i]).getName().compareTo("exception") == 0 &&
                    y > ((MyObjects) lista[i]).getY()) {

                after_exception = true;
            }

            if (lista[i] instanceof MyFrame && y > ((MyObjects) lista[i]).getY() &&
                    y <
                    (((MyObjects) lista[i]).getY() + ((MyObjects) lista[i]).getHeight())) {

                if (!(frm.getID().compareTo(((MyObjects) lista[i]).getID()) == 0)) {

                    inside_frame = true;

                }
            }
        }

        //Primero se debe mirar que no se haya colocado más abajo de un frame
        //de excepción a no ser que esté dentro
        if(after_exception && !inside_frame){

            //Ver la posicion del ultimo frame que se haya añadido a la lista
            int posicion = 0;

            for (int i = 0; i < lista.length; i++) {

                //Si se trata de un frame
                if ((lista[i] instanceof MyFrame)) {

                    posicion = i;
                    break;

                }

            }

            //eliminar frame
            panel.remove(posicion);

            //Mostrar mensaje de error
            JOptionPane optionPane= new JOptionPane();
            Object[] options = {"Ok"};
            optionPane.showOptionDialog(optionPane,"Nothing can be placed after exception","Error",optionPane.YES_NO_OPTION,optionPane.INFORMATION_MESSAGE, null, options, null);

        }

        else{
            frm.colocado = true;

            //Dibujar a la altura adecuada según los mensajes y frames anteriores
            XYConstraints c = frm.getXY();
            int n_anteriores = 0;
            int n_frames_anteriores = 0;
            int n_frames_alt_else = 0;
            int n_anidamientos = 0;


            for (int i = 0; i < lista.length; i++) {

                if ((lista[i] instanceof MyMessage) && y > ((MyObjects) lista[i]).getY()) {

                    if (!(frm.getID().compareTo(((MyObjects) lista[i]).getID()) == 0))
                        n_anteriores++;
                }
                if (lista[i] instanceof MyFrame &&
                    ((MyObjects) lista[i]).getName().compareTo("alt_else") != 0 &&
                    y > ((MyObjects) lista[i]).getY() &&
                    y >
                    (((MyObjects) lista[i]).getY() + ((MyObjects) lista[i]).getHeight())) {

                    if (!(frm.getID().compareTo(((MyObjects) lista[i]).getID()) == 0))
                        n_frames_anteriores++;
                }

                if (lista[i] instanceof MyFrame &&
                    ((MyObjects) lista[i]).getName().compareTo("alt_else") == 0 &&
                    y > ((MyObjects) lista[i]).getY() &&
                    y >
                    (((MyObjects) lista[i]).getY() + ((MyObjects) lista[i]).getHeight())) {

                    if (!(frm.getID().compareTo(((MyObjects) lista[i]).getID()) == 0))
                        n_frames_alt_else++;
                }

                //Si se trata de un frame y la coordenada Y esta dentro entonces
                //se debe anidar el nuevo frame dentro

                if (lista[i] instanceof MyFrame && y > ((MyObjects) lista[i]).getY() &&
                    y <
                    (((MyObjects) lista[i]).getY() + ((MyObjects) lista[i]).getHeight())) {

                    if (!(frm.getID().compareTo(((MyObjects) lista[i]).getID()) == 0)) {

                        //Subir el contador de anidamientos
                        n_anidamientos++;

                        //Se debe ampliar el espacio del frame que lo contiene
                        XYConstraints c2 = ((MyFrame) lista[i]).getXY();

                        if (frm.getName().compareTo("alt_else") != 0)
                            c2.setHeight(c2.getHeight() + 60);
                        else
                            c2.setHeight(c2.getHeight() + 90);

                        ((MyFrame) lista[i]).editXYconstraints(c2);

                        ((MyFrame) lista[i]).includeFrame(frm);

                    }
                }

            }

            //Modificar la coordenada Y según mensajes anteriores, frames anteriores y nivel de anidamiento
            c.setY(c.getY() + n_anteriores * 30 + n_frames_anteriores * 60 +
                   n_frames_alt_else * 90 + n_anidamientos * 30);

            //Modificar la anchura del frame según el nivel de anidamiento
            c.setX(c.getX() + n_anidamientos * 2);
            c.setWidth(c.getWidth() - n_anidamientos * 4);

            frm.editXYconstraints(c);

            //Ver si hay que modificar la y del frame por estar en la parte del else de un alt_else
            for (int i = 0; i < lista.length; i++) {

                if (lista[i] instanceof MyFrame && y > ((MyObjects) lista[i]).getY() &&
                    y <
                    (((MyObjects) lista[i]).getY() + ((MyObjects) lista[i]).getHeight()) &&
                    ((MyFrame) lista[i]).getName().compareTo("alt_else") == 0) {

                    if (!(frm.getID().compareTo(((MyObjects) lista[i]).getID()) == 0)) {

                        ArrayList separadores = ((MyFrame) lista[i]).separadores;

                        if (((Integer) separadores.get(0)).intValue() + lista[i].getY() <
                            y) {

                            c.setY(c.getY() + 30);

                            frm.editXYconstraints(c);

                        }
                    }
                }

            }

            //En el caso de que el frame sea "par" o "alt" se deben tener también
            //en cuenta las líneas de separación internas
            for (int i = 0; i < lista.length; i++) {

                if (lista[i] instanceof MyFrame && y > ((MyObjects) lista[i]).getY() &&
                    y <
                    (((MyObjects) lista[i]).getY() + ((MyObjects) lista[i]).getHeight()) &&
                    (((MyFrame) lista[i]).getName().compareTo("par") == 0 ||
                     ((MyFrame) lista[i]).getName().compareTo("alt") == 0)) {

                    if (!(frm.getID().compareTo(((MyObjects) lista[i]).getID()) == 0)) {

                        boolean posterior = false;
                        ArrayList separadores = ((MyFrame) lista[i]).separadores;

                        //Desplazar los separadores posteriores en caso de que los haya
                        for (int j = 0; j < separadores.size(); j++) {

                            if (((Integer) separadores.get(j)).intValue() +
                                lista[i].getY() > y) {

                                int valor = ((Integer) separadores.get(j)).intValue();

                                separadores.remove(j);

                                if (frm.getName().compareTo("alt_else") != 0)
                                    separadores.add(j, new Integer(valor + 60));
                                else
                                    separadores.add(j, new Integer(valor + 90));

                                posterior = true;

                            }

                        }

                        //Dibujar debajo del frame si no hay ninguna línea posterior
                        if (!posterior) {

                            if (frm.getName().compareTo("alt_else") != 0)
                                ((MyFrame) lista[i]).addSeparador(new Integer(c.getY() -
                                        ((MyFrame) lista[i]).getY() + 58));
                            else
                                ((MyFrame) lista[i]).addSeparador(new Integer(c.getY() -
                                        ((MyFrame) lista[i]).getY() + 88));
                        }

                    }
                }

            }

            //En el caso de que el frame sea "alt_else" se debe tener
            //en cuenta la línea de separación interna
            for (int i = 0; i < lista.length; i++) {

                if (lista[i] instanceof MyFrame && y > ((MyObjects) lista[i]).getY() &&
                    y <
                    (((MyObjects) lista[i]).getY() + ((MyObjects) lista[i]).getHeight()) &&
                    ((MyFrame) lista[i]).getName().compareTo("alt_else") == 0) {

                    if (!(frm.getID().compareTo(((MyObjects) lista[i]).getID()) == 0)) {

                        ArrayList separadores = ((MyFrame) lista[i]).separadores;

                        //Desplazar el separador si es posterior
                        if (((Integer) separadores.get(0)).intValue() + lista[i].getY() >
                            y) {

                            int valor = ((Integer) separadores.get(0)).intValue();

                            separadores.remove(0);

                            if (frm.getName().compareTo("alt_else") != 0)
                                separadores.add(0, new Integer(valor + 60));
                            else
                                separadores.add(0, new Integer(valor + 90));
                        }

                    }
                }

            }

            //Se debe desplazar la coordenada Y de los mensajes posteriores

            for (int i = 0; i < lista.length; i++) {

                if (lista[i] instanceof MyMessage &&
                    frm.xyc.getY() <= ((MyMessage) lista[i]).getY()) {

                    XYConstraints c2 = ((MyMessage) lista[i]).getXY();

                    if (frm.getName().compareTo("alt_else") != 0)
                        c2.setY(c2.getY() + 60);
                    else
                        c2.setY(c2.getY() + 90);

                    ((MyMessage) lista[i]).editXYconstraints(c2);

                }

                //También se deben desplazar los frames posteriores
                if (lista[i] instanceof MyFrame &&
                    frm.xyc.getY() <= ((MyFrame) lista[i]).getY()) {

                    if (!(frm.getID().compareTo(((MyFrame) lista[i]).getID()) == 0)) {
                        XYConstraints c2 = ((MyFrame) lista[i]).getXY();

                        if (frm.getName().compareTo("alt_else") != 0)
                            c2.setY(c2.getY() + 60);
                        else
                            c2.setY(c2.getY() + 90);

                        ((MyFrame) lista[i]).editXYconstraints(c2);

                    }
                }
            }

            //Ampliar la línea de los actors y lifelines
            for (int i = 0; i < lista.length; i++) {

                if (lista[i] instanceof MyLifeLine) {

                    MyLifeLine lin = ((MyLifeLine) lista[i]);

                    XYConstraints c2 = lin.getXY();

                    if (frm.getName().compareTo("alt_else") != 0)
                        c2.setHeight(c2.getHeight() + 60);
                    else
                        c2.setHeight(c2.getHeight() + 90);

                    lin.editXYconstraints(c2);

                }

                if (lista[i] instanceof MyActor) {

                    MyActor lin = ((MyActor) lista[i]);

                    XYConstraints c2 = lin.getXY();

                    if (frm.getName().compareTo("alt_else") != 0)
                        c2.setHeight(c2.getHeight() + 60);
                    else
                        c2.setHeight(c2.getHeight() + 90);

                    lin.editXYconstraints(c2);

                }

            }

            //Se debe repintar el panel que contiene a los objetos
            panel.repaint();
            panel.updateUI();
        }
    }

    /**
   * Añade un frame de excepción al diagrama
   *
   * @param frm frame que se añade
   */
    public void addPositionFrameException(MyFrame frm){
        frm.colocado = true;

        //Dibujar a la altura adecuada según los mensajes y frames anteriores
        //En este caso se dibujará siempre al final
        XYConstraints c = frm.getXY();
        int n_anteriores = 0;
        int n_frames_anteriores = 0;
        int n_frames_alt_else = 0;

        JPanel panel = (JPanel) frm.getParent();
        Component lista [] = panel.getComponents();

        for (int i = 0; i < lista.length; i++) {

            if (lista[i] instanceof MyMessage){

                if (!(frm.getID().compareTo(((MyObjects) lista[i]).getID()) == 0))
                    n_anteriores++;
            }
            if (lista[i] instanceof MyFrame && ((MyObjects)lista[i]).getName().compareTo("alt_else")!=0){

                if(!(frm.getID().compareTo(((MyObjects)lista[i]).getID())==0))
                    n_frames_anteriores++;
            }

            if (lista[i] instanceof MyFrame && ((MyObjects)lista[i]).getName().compareTo("alt_else")==0){

                if(!(frm.getID().compareTo(((MyObjects)lista[i]).getID())==0))
                    n_frames_alt_else++;
            }
        }

        //Modificar la coordenada Y según mensajes anteriores
        c.setY(c.getY() + n_anteriores * 30 + n_frames_anteriores * 60+ n_frames_alt_else *90);

        frm.editXYconstraints(c);

        //Ampliar la línea de los actors y lifelines
        for (int i = 0; i < lista.length; i++) {

            if (lista[i] instanceof MyLifeLine){

                MyLifeLine lin = ((MyLifeLine)lista[i]);

                XYConstraints c2 = lin.getXY();

                if(frm.getName().compareTo("alt_else")!=0)
                    c2.setHeight(c2.getHeight() + 60);
                else
                    c2.setHeight(c2.getHeight() + 90);

                lin.editXYconstraints(c2);

            }

            if (lista[i] instanceof MyActor){

                MyActor lin = ((MyActor)lista[i]);

                XYConstraints c2 = lin.getXY();

                if(frm.getName().compareTo("alt_else")!=0)
                    c2.setHeight(c2.getHeight() + 60);
                else
                    c2.setHeight(c2.getHeight() + 90);

                lin.editXYconstraints(c2);

            }


        }


        //Se debe repintar el panel que contiene a los objetos
        panel.repaint();
        panel.updateUI();

    }



    /**
    * Dibuja los mensajes que se han ido almacenando en las listas, tanto en la
    * de enviados como en la de recibidos
    *
    * @param xOffset desplazamiento de un objeto en el eje de las x
    */
    public void repaintMessages(int xOffset){
        for(int i=0; i<sendedMsg.size(); i++){
            MyMessage m = (MyMessage)sendedMsg.get(i);

            int w = m.xyc.getWidth() - xOffset;
            //El desplazamiento es negativo ya que a medida que avanzamos hacia
            //el destino, va siendo menor
            if(w>0){
                m.setLocation(m.source.getX() + m.source.getWidth() / 2, m.xyc.getY());
                m.setSize(w, m.getHeight());
            }
            else{
                m.setLocation(m.dest.getX() + m.dest.getWidth()/2, m.xyc.getY());
                m.setSize(-w, m.getHeight());
            }
            m.xyc.setWidth(w);
        }
        for(int i=0; i<receivedMsg.size(); i++){
            MyMessage m = (MyMessage)receivedMsg.get(i);
            int w = m.xyc.getWidth() + xOffset;
            //En este caso el desplazamiento es positivo, ya que vamos desde la
            //derecha hacia la izquierda y va aumentando.
            if(w>0){
                m.setLocation(m.source.getX() + m.source.getWidth() / 2, m.xyc.getY());
                m.setSize(w, m.getHeight());
            }
            else{
                m.setLocation(m.dest.getX() + m.dest.getWidth() / 2, m.xyc.getY());
                m.setSize( -w, m.getHeight());
            }
            m.xyc.setWidth(w);
        }
    }

    /**
   * Borra un mensaje a la lista de mensajes enviados
   *
   * @param msg mensaje que se borra
   */
    public void deleteSendMessage(MyMessage msg){

        sendedMsg.remove(msg);

    }

    /**
     * Borra un mensaje de la lista de mensajes recibidos
     *
     * @param msg mensaje que se borra
     */
    public void deleteReceiveMessage(MyMessage msg){

        receivedMsg.remove(msg);

    }

    /**
     * Borra un mensaje de la lista de mensajes incluidos
     *
     * @param msg mensaje que se borra
     */
    public void deleteIncludeMessage(MyMessage msg){

        includeMsg.remove(msg);

    }

    /**
     * Modifica las coordenadas del objeto
     *
     * @param c nuevas coordenas
     */
    public void editXYconstraints(XYConstraints c){

        xyc = c;

    }

    public ArrayList getVariables(){

        return variables;

    }

    public void setVariables(ArrayList al){

        variables = al;

    }

}
