package net.benhui.btgallery.spp_gui;

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

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

/**
 *
 * <p>Title: Example Serial Port Profile 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.
 * </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 SPP_MIDlet extends MIDlet implements CommandListener
{
  // commonly used singleton object
  public static SPP_MIDlet instance;
  public static Display display;

  // GUI component/screen
  public SPP_Screen spp_screen = null;

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

  // SPP client logic
  SPP_Client spp_client  = null;

  // SPP server logic
  SPP_Server spp_server = null;

  public SPP_MIDlet()
  {
    instance = this;
  }

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

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

    spp_client = new SPP_Client();
    spp_server = new SPP_Server(); // server not yet started in constructor
    spp_screen = new SPP_Screen();


    display.setCurrent( spp_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( spp_screen );
      // found at least one service. since we search for SerialPort
      // service, so we can send a message to this service using SPP connection
//      spp_client.send_SPP_message( 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();
	  bluelet.showUI();
	  display.setCurrent(bluelet.getServiceUI());

    } else if ( c.equals( BLUElet.SELECTEDSERVICE ) )
    {
     display.setCurrent( spp_screen );  
	  Thread t = new Thread(  new WTK22beta2Patch() );
     t.start();
    } else if ( c.equals( BLUElet.SELECTED ) )
    {
      display.setCurrent( spp_screen );
    } else if ( d == spp_screen && c.getLabel().equals("Run Serial Client") )
    {
      //
      // do SPP client operation
      // first use Bluelet to discover server service
      bluelet.startInquiry( DiscoveryAgent.GIAC, new UUID[]{ SPP_Server.uuid, SPP_Server.uuid2 , SPP_Server.uuid3 } );
      display.setCurrent( bluelet.getUI() );

    } else if ( d == spp_screen && c.getLabel().equals("Start Serial Server") )
    {
      //
      // start local SPP server
      //
      spp_server.run_server();

    } else if ( c.equals( BLUElet.BACK ) )
    {
      display.setCurrent( spp_screen );
    } else if (d == spp_screen && c.getLabel().equals("Exit"))
    {
        // Exit application.
        try
        {
          // attemp to close the server connection before existing...
          spp_server.done = true;
          spp_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);
    SPP_MIDlet.instance.spp_screen.add(s);
  }

  /**
   * 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 SerialPort
      // service, so we can send a message to this service using SPP connection
      spp_client.send_SPP_message( bluelet.getSelectedService(), "Sample Test Message" );

    }
  }

}
