package profiles.uitest;

import profiles.*;
import java.awt.*;
import java.util.Vector;

/**
 * Rappresenta un dispositivi con il servizio di profili. Questo oggetto
 * autogestisce la sua tabella di routing con un thread. Inoltre contiene
 * un oggetto ProfileMathcher al quale delega la gestione dei profili.
 * @author Lorenzo Moretti
 * @version 1.0
 */

public class UIDevice implements Device {
  /** Raggio del cerchio rosso (o giallo) disegnato come dispositivo.*/
  public static final int INTERNAL_RADIUS = 10;
  private int radius;
  private int posX;
  private int posY;
  private static int nextID = 0;
  private String curID;
  BasicService basicService = null;
  RoutingTable rt = null;
  // Gestore tabella di routing.
  RoutingManager rtMngr = null;
  // Gestore dei profili.
  ProfileMatcher pMatcher = null;

  Profile profile = null;

  UIDevice() {
  }

  public UIDevice(SimulationPanel bs, int posX, int posY, int radius) {
    basicService = bs;
    curID = "" + nextID;
    nextID++;
    this.posX = posX;
    this.posY = posY;
    this.radius = radius;

    rt = new RoutingTable(this);

    // Autoupdate routing table
    rtMngr = new RoutingManager(rt,bs);
    rtMngr.start();

    // Profiles
    profile = new Profile(curID);
    pMatcher = new ProfileMatcher(this, bs, profile);
    pMatcher.start();
  }

  public void paint(Graphics g) {
    g.setColor((pMatcher.isElected()? Color.YELLOW:Color.RED));
    g.fillOval(posX-(INTERNAL_RADIUS/2), posY-(INTERNAL_RADIUS/2),
               INTERNAL_RADIUS, INTERNAL_RADIUS);

    g.setColor(Color.GREEN);
    g.drawOval(posX-(radius/2),posY-(radius/2),
               radius,radius);

    g.setColor(Color.BLACK);
    g.drawString(curID,posX, posY);
  }



  public int getRadius() {
    return radius;
  }
  public void setRadius(int radius) {
    this.radius = radius;
  }
  public int getPosX() {
    return posX;
  }
  public void setPosX(int posX) {
    this.posX = posX;
  }
  public int getPosY() {
    return posY;
  }
  public void setPosY(int posY) {
    this.posY = posY;
  }

  public String getId() {
    return curID;
  }

  public RoutingTable getRoutingTable() {
    return rt;
  }

  public void refresh(BasicService bs) {
    rt.update(bs);
  }

  public Profile getProfile() {
    return profile;
  }

  public void receive(Message m) {
    //TestFrame.appendMessage("Device #" + curID +
    //                        " riceve messaggio '" + m.getMessage() + "'");
    if (m.getMessage().equals("PREQ"))
      pMatcher.profileRequested(m.getSrcDevice());
    else if (((String)m.getMessage()).charAt(0) == '@')
      pMatcher.addProfile(Profile.fromString(m.getMessage().toString()));
  }

  public void destroy() {
    pMatcher.stopRunning();
    rtMngr.stopUpdating();
  }

  public String toString() {
    return "{"+ getId() + getRoutingTable().toString() + "}";
  }

  public static UIDevice fromString(String str) {
    UIDevice dev = new UIDevice();
    parseUIDevice(str, dev);
    return dev;
  }

  static int parseUIDevice(String str, UIDevice dev) {
    int pos = 0;
    if (str.charAt(pos) != '{')
      throw new IllegalArgumentException("Missing {");

    StringBuffer sbuff = new StringBuffer();

    pos = 1;
    while (str.charAt(pos) != '[') {
      sbuff.append(str.charAt(pos));
      pos++;
    }


    RoutingTable rt =  new RoutingTable(dev);
    pos += parseRoutingTable(str.substring(pos), rt);
    if (str.charAt(pos)!='}')
      throw new IllegalArgumentException("Missing }");

    dev.curID = sbuff.toString();
    dev.rt = rt;
    return pos++;
  }

  static int parseRoutingTable(String str, RoutingTable rt) {
    int pos = 0;
    if (str.charAt(pos) != '[')
      throw new IllegalArgumentException("Missing [");

    pos++;
    while (str.charAt(pos) != ']') {
      if (str.charAt(pos) == '{') {
        UIDevice d = new UIDevice();
        pos += parseUIDevice(str.substring(pos), d);
        rt.addDevice(d);
      }
      pos++;
    }

    return ++pos;
  }
  public ProfileMatcher getPMatcher() {
    return pMatcher;
  }

}