package net.benhui.btgallery.l2cap_gui;

import java.io.*;
import javax.bluetooth.*;
import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

import net.benhui.btgallery.bluelet.*;
import net.benhui.btgallery.l2cap_bt.*;

/***
 *
 * <p>Title: Example Serial Port Profile Client Main MIDlet</p>
 * <p>Description: This MIDlet can invoke both server and client functions.
 * See SPP_Client for actual Bluetooth client opeartions.
 * See SPP_Server for actual Bluetooth server operations.
 * @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 L2CAP_MIDlet extends MIDlet implements CommandListener
{
  // commonly used singleton object
  public static L2CAP_MIDlet instance;
  public static Display display;

  // GUI component/screen
  public L2CAP_Screen l2cap_screen = null;

  // utilize Bluelet to do device disvcovery and service discovery
  BLUElet bluelet = null;

  // L2CAP client logic
  L2CAP_Client l2cap_client  = null;
  // L2CAP server logic
  L2CAP_Server l2cap_server = null;


  public L2CAP_MIDlet()
  {
    instance = this;
  }

  /**
   * Implements MIDlet lifecycle
   */
  public void startApp()
  {
    display = Display.getDisplay(this);

    bluelet = new BLUElet( this, this );
    bluelet.startApp();

    l2cap_client = new L2CAP_Client();
    l2cap_server = new L2CAP_Server(); // server not yet started in constructor
    l2cap_screen = new L2CAP_Screen();


    display.setCurrent( l2cap_screen );

  }

  /**
   * Implements MIDlet lifecycle
   */
  public void pauseApp()
  {
    bluelet.pauseApp();
  }

  /**
   * Implements MIDlet lifecycle
   */
  public void destroyApp(boolean unconditional)
  {
    bluelet.destroyApp( unconditional );
  }

  /**
   * Exit MIDlet
   */
  public static void quitApp()
  {
    instance.destroyApp(true);
    instance.notifyDestroyed();
    instance = null;
  }



  /**
   * Handle user action and input.
   * All GUI Command are directed to this function for simplicity of this demo.
   * @param c
   * @param d
   */
  public void commandAction(Command c, Displayable d)
  {
    if ( c.equals( BLUElet.COMPLETED ) )
    {
      display.setCurrent( l2cap_screen );
      // found at least one service. since we search for L2CAP
      // service, so we can send a message to this service using L2CAP connection
//      l2cap_client.send_L2CAP_packet( bluelet.getFirstDiscoveredService(), "Sample Test Message" );
//
// WTK2.2 beta 2 patch note:
// - above solution works with WTK 2.2 beta 1, but doesn't work with beta 2. it will hang the emulator
// - below does work with WTK 2.2 beta 2, by using a background thread to send the message
      Thread t = new Thread(  new WTK22beta2Patch() );
      t.start();


    } else if ( d == l2cap_screen && c.getLabel().equals("Run L2CAP Client") )
    {
      //
      // do client operation
      // first use Bluelet to discover server service
      bluelet.startInquiry( DiscoveryAgent.GIAC, new UUID[]{ L2CAP_Server.uuid } );
      display.setCurrent( bluelet.getUI() );

    } else if ( d == l2cap_screen && c.getLabel().equals("Start L2CAP Server") )
    {
      //
      // start local SPP server
      //
      l2cap_server = new L2CAP_Server();
      l2cap_server.run_server();

    } else if ( c.equals( BLUElet.BACK ) )
    {
      display.setCurrent( l2cap_screen );
    } else if (d == l2cap_screen && c.getLabel().equals("Exit"))
    {
        // Exit application.
        try
        {
          // attemp to close the server connection before existing...
          l2cap_server.done = true;
          l2cap_server.server.close();
        }
        catch (IOException ex)
        {
        }
        quitApp();

    }

  }


  /**
   * An utility function to display a log message
   * @param s String
   */
  public static void log(String s)
  {
    System.out.println(s);
    L2CAP_MIDlet.instance.l2cap_screen.msgs.addElement( s );
    L2CAP_MIDlet.instance.l2cap_screen.repaint();
  }

  /**
   * An utility function that show a alert box that display an exception message.
   * @param e
   * @param next_screen
   */
  public static void alert( Exception e, Displayable next_screen )
  {
    Alert alert = new Alert( "Benhui.net", "Exception: "+e.getClass().getName()+" "+e.getMessage(), null, AlertType.INFO );
    alert.setTimeout( Alert.FOREVER );
    display.setCurrent( alert, next_screen );

  }

  /**
   * An utility function that show a alert box that display a message.
   *
   * @param m String
   * @param next_screen Screen
   */
  public static void alert( String m, Displayable next_screen )
  {
    Alert alert = new Alert( "Benhui.net", m, null, AlertType.INFO );
    alert.setTimeout( Alert.FOREVER );
    display.setCurrent( alert, next_screen );

  }

  public class WTK22beta2Patch implements Runnable
  {
    public void run()
    {
      // found at least one service. since we search for L2CAP
      // service, so we can send a message to this service using L2CAP connection
      l2cap_client.send_L2CAP_packet( bluelet.getSelectedService(), "Sample Test Message" );

    }
  }

}
