package net.benhui.btgallery.discovery_bt;

import java.util.*;
import javax.microedition.lcdui.*;
import javax.bluetooth.*;
import net.benhui.btgallery.discovery_gui.*;
import net.benhui.btgallery.*;
/**
 * <p>Title: Component that does device discovery and service discovery.</p>
 * This code demostrate how to code device discovery and service discovery.
 *
 * Description: Important areas are doDiscoverDevice(), doDiscoverService() and Listener class
 * <p>Copyright: Copyright (c) 2003</p>
 * <p>Company: </p>
 * @author Ben Hui (www.benhui.net)
 * @version 1.0
 *
 * LICENSE:
 * This code is licensed under GPL. (See http://www.gnu.org/copyleft/gpl.html)
 */

public class DiscoveryImpl
{
  // Bluetooth singleton object
  LocalDevice device;
  DiscoveryAgent agent;

  // list of RemoteDevice discovered
  public static Vector devices = new Vector();
  // list of DeviceClass discovered (not used in this example)
  public static Vector deviceClasses = new Vector();
  // list of ServiceRecrod discovered for one RemoteDevice
  public static Vector services = new Vector();

  /**
   * Perform Bluetooth device discovery.
   *
   */
  public void doDiscoverDevice()
  {
    try
    {
      //
      // initialize the JABWT stack
      device = LocalDevice.getLocalDevice(); // obtain reference to singleton
      device.setDiscoverable(DiscoveryAgent.GIAC); // set Discover mode to GIAC
      agent = device.getDiscoveryAgent(); // obtain reference to singleton

      // start Bluetooth inquiry (GIAC mode)
      // inquiry response direct to Listener object
      agent.startInquiry( DiscoveryAgent.GIAC, new Listener() );


    } catch ( BluetoothStateException e )
    {
      e.printStackTrace();

      Discovery_MIDlet.alert( e, Discovery_MIDlet.instance.deviceDiscoveryUI );
    }
  }
  /**
   * Perform service discovery on a remote device.
   * @param remote the remote device to inquire services for
   */
  public void doDiscoverService(RemoteDevice remote)
  {
    try
    {
      //
      // this large array of integer values will tell JABWT to query
      // for all known attributes
      // see https://www.bluetooth.org/foundry/assignnumb/document/service_discovery
      // section 4.5 for meaning of these IDs
      //
      // note: you don't have to retrieve all attribute everytime. in fact, you
      // can put null for attr and retrieve just the default values. that probably
      // good enough for most cases. we list all attributes for demo purpose
      //
      // note: For Nokia 6230, there is a limit (13) of number of attribute to retrieve
      // and this large array will cause error. If you are using Nokia 6230, you should
      // reduce this array to 13 elements. Just pick any 13 of them and make sure you pick
      // 0x0001 (ServiceClassID) so we can display the profiel name
      int[] attr = new int[]{0x0000, 0x0001, 0x0002, 0x0003, 0x0004,
          0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D,
          0x0100, 0x0101, 0x0102, 0x0200, 0x0201,
          0x0301, 0x0302, 0x0303, 0x0304, 0x0305, 0x0306, 0x0307, 0x0308, 0x0309,
          0x030A, 0x030B, 0x030C, 0x030D, 0x030E, 0x0310, 0x0311, 0x0312, 0x0313 };
      //
      // search for L2CAP services, most services based on L2CAP
      //
      // note: Rococo simulator required a new instance of Listener for
      // every search. not sure if this is also the case in real devices
      agent.searchServices( attr, // attributes to retrieve from remote device
                           new UUID[]{ new UUID( 0x0100 )  }, // search criteria, 0x0100 = L2CAP
                           remote,
                           new Listener()); // direct discovery response to Listener object
    }
    catch ( BluetoothStateException e )
    {
      e.printStackTrace();
      Discovery_MIDlet.alert( e, Discovery_MIDlet.instance.deviceDiscoveryUI );

    }

  }


  /**
   *
   * <p>Title: DiscoveryListener implementation that handle discovery response (callback)</p>
   * <p>Description: </p>
   * <p>Copyright: Copyright (c) 2003</p>
   * @author Ben Hui (www.benhui.net)
   * @version 1.0
   */
  class Listener implements DiscoveryListener
  {
    /**
     * Implements DiscoveryListener interface.
     * This function in invoked for each RemoteDevice discovered by JABWT.
     * See JSR-82 API spec for documentation.
     * @param remoteDevice
     * @param deviceClass
     */
    public void deviceDiscovered(RemoteDevice remoteDevice,
                                 DeviceClass deviceClass)
    {
      log("A remote Bluetooth device is discovered:");
      Util.printRemoteDevice( remoteDevice, deviceClass );
      // store the device in the list for later use
      devices.addElement( remoteDevice );
      deviceClasses.addElement( deviceClass );
    }

    /**
     * Implements DiscoveryListener interface.
     * This function is invoked when the device discovery is completed.
     * See JSR-82 API spec for documentation.
     * @param complete
     */
    public void inquiryCompleted(int complete)
    {
      log("service discovery completed with return code:"+complete);
      log(""+devices.size()+" devices are discovered");


      if ( devices.size() == 0 )
      {
        // cannot find any Bluetooth device, tell user about this
        Alert alert = new Alert( "Problem!", "No Bluetooth device found", null, AlertType.INFO );
        alert.setTimeout(3000);
        Discovery_MIDlet.instance.deviceDiscoveryUI.setMsg("[Press Inquiry]");
        Discovery_MIDlet.display.setCurrent( alert, Discovery_MIDlet.instance.deviceDiscoveryUI );

      } else
      {
        // update the GUI list to reflect all the found devices
        Discovery_MIDlet.instance.deviceDiscoveryUI.showui();
        Discovery_MIDlet.display.setCurrent( Discovery_MIDlet.instance.deviceDiscoveryUI );

      }

    }
    /**
     * Implements DiscoveryListener interface.
     * This function is invoked when services are found on a RemoteDevice.
     * See JSR-82 API spec for documentation.
     * @param transId
     * @param records
     */
    public void servicesDiscovered(int transId, ServiceRecord[] records)
    {
      log("Remote Bluetooth services is discovered:");
      for ( int i=0; i< records.length;  i ++ )
      {
        ServiceRecord record = records[i];
        Util.printServiceRecord( record );
        // store the service records in list for later use
        services.addElement( record );
      }
    }

    /**
     * Implements DiscoveryListener interface.
     * This function is invoked when service discovery is completed on a RemoteDevice.
     * See JSR-82 API spec for documentation.
     * @param transId
     * @param complete
     */
    public void serviceSearchCompleted(int transId, int complete)
    {
      log("service discovery completed with return code:"+complete);
      log(""+services.size()+" services are discovered");

      if ( complete == SERVICE_SEARCH_COMPLETED || complete ==  SERVICE_SEARCH_NO_RECORDS )
      {
        // reflect the GUI to show all found services
        Discovery_MIDlet.instance.serviceDiscoveryUI.showui();
        Discovery_MIDlet.display.setCurrent(Discovery_MIDlet.instance.serviceDiscoveryUI);
      } else
      {
        // other possible complete values are
        // SERVICE_SEARCH_DEVICE_NOT_REACHABLE
        // SERVICE_SEARCH_ERROR
        // SERVICE_SEARCH_TERMINATED
        //
        // tell user about the problem
        Discovery_MIDlet.alert( "Service Discovery imcomplete", Discovery_MIDlet.instance.deviceDiscoveryUI );
      }

    }

  } // Listener


  public void log(String m)
  {
    Discovery_MIDlet.log( m );
  }
}
