package profilesj2me;

import profiles.*;
import java.util.Vector;
import javax.microedition.io.*;
import javax.bluetooth.*;
import java.io.IOException;
import profiles.Message;


/**
 * Il fulcro dell'applicazione per J2ME. Implementa i servizi di base,
 * basandosi su JSR-82. Tutti i dattagli della comunicazione bluetooth sono
 * nascosti. Questo è un'oggetto attivo.
 *
 * @author Lorenzo Moretti
 * @version 1.0
 */


public final class J2MEBasicService implements BasicService {

  /**
   * UUID del servizio Profiles. E' chiaramente univoco ed identifica
   * questa classe di applicazioni via bluetooth.
   */
  public final static UUID SERVICE_UUID = new UUID(0x65f4aabb);

  LocalDevice localDevice;
  DiscoveryAgent discoveryAgent = null;
  J2MEBasicServiceServer connectionServer = null;
  J2MEBasicServiceDiscoverer discoverer = null;

  J2MEDevice listener = null;
  Vector devicesInRange = new Vector();


  /**
   * Crea un nuovo oggetto. Automaticamente partono i servizi di ricezione e
   * di discovery di periferiche nelle vicinanze.
   *
   * @throws BluetoothStateException
   * @throws IOException
   */
  public J2MEBasicService() throws BluetoothStateException, IOException {

    localDevice = LocalDevice.getLocalDevice();
    discoveryAgent = localDevice.getDiscoveryAgent();
    discoverer= new J2MEBasicServiceDiscoverer(this);
    connectionServer = new J2MEBasicServiceServer(this);

    // Attiva il servizio di ascolto connessioni
    connectionServer.start();

    // Attiva il servizio di ricerca dispositivi
    discoverer.start();
  }

  /**
   * Libera le risorse e ferma i thread interni. Da prima di terminare.
   *
   */
  public void destroy() {
    connectionServer.stopListening();
    discoverer.stopUpdating();
  }

  /**
   * Ottiene la lista delle periferiche con questo servizio attivo nei paraggi.
   * @param device può essere null. Parametro non utilizzato.
   * @return un Vector di risultati, con dimensione 0 se non è stato trovato
   * nulla.
   */
  public Vector getDevicesInRange(Device device) {
    return devicesInRange;
  }

  void setDevicesInRange(Vector devs) {
    devicesInRange = devs;
  }

  /**
   * Restituisce un dispositivo se questo è disponibile.
   * @param string l'identificativo del dispositivo.
   * @return il dispositivo se è stato trovato, null altrimenti.
   */
  public Device getDevice(String id) {
    Vector devs = getDevicesInRange(null);
    int pos = -1;
    for (int i = 0; i < devs.size(); i++) {
      if (((J2MEDevice)devs.elementAt(i)).getURL().startsWith(id,10)) {
        pos = i;
        break;
      }
    }

    if (pos == -1)
      return null;

    return (J2MEDevice)devs.elementAt(pos);
  }

  J2MEBasicServiceServer getJ2MEBasicServiceServer() {
    return connectionServer;
  }

  J2MEBasicServiceDiscoverer getJ2MEBasicServiceDiscoverer() {
    return discoverer;
  }


  public void registerListnerDevice(Device device) {
    listener = (J2MEDevice)device;
  }

  public Device getRegisteredListenerDevice() {
    return listener;
  }

  /**
   * Invia un messaggio.
   * @param message il messaggio
   */

  public void deliverMessage(Message message) {
    if (message.getType() == Message.USR_MSG) {
      System.out.println("deliver User message");
    }

    J2MEBasicServiceSender sndr = new J2MEBasicServiceSender(this,
        (TextMessage) message);
    sndr.start();
  }



  public void bcast(Device dev, Message msg) {
    Vector newRoute = new Vector();

    if (msg.decTimeToLive() > 0) {
      for (int i = 0; i < devicesInRange.size(); i++) {
        newRoute.removeAllElements();
        newRoute.addElement( ( (Device) devicesInRange.elementAt(i)).getId());
        msg.setRoute(newRoute);
        deliverMessage(msg);
        System.out.println("Inviato messaggio bcast: " + msg);
      }
    }
  }

}