// Test sample 5.

package oracle.wireless.me.sample1;

import java.util.Vector;

import javax.microedition.lcdui.*;
import javax.microedition.midlet.*;

import oracle.wireless.me.core.*;

/**
 * Sample5 demonstrates call queueing.  Normally, you should queue a call
 * only if there is a network error when trying to invoke the call.
 */
public class Sample5 extends MIDlet implements CommandListener
{
    private ServiceFactory serviceFactory;
    private Service service;

    private Display display;
    private Form form;
    private Command exitCommand;
    private Command queueCommand;
    private Command clearQCommand;
    private Command clearCCommand;
    private Command clearSCommand;

    public Sample5()
    {
    }

    protected void startApp() throws MIDletStateChangeException
    {
	    if (display == null) {
	      initMIDlet();
	    }
    }

    protected void pauseApp()
    {
      try {
	      ServiceManager.getInstance().close();
      }
      catch (Exception e) {
      }
      //System.out.println("Sample5 paused");
    }

    protected void destroyApp(boolean unconditional)
	      throws MIDletStateChangeException
    {
	    exitMIDlet();
    }

    public void commandAction(Command c, Displayable d)
    {
	    if (c == exitCommand) {
	      exitMIDlet();
	    }
	    else if (c == queueCommand) {
	      callService();
	    }
	    else if (c == clearQCommand) {
	      clearQueue();
	    }
	    else if (c == clearCCommand) {
	      clearCache();
    	}
    	else if (c == clearSCommand) {
	      clearScreen();
	    }
    }


  /**
   * Clear ALL queued calls from the queue.
   */
  void clearQueue()
  {
    try {
      ServiceManager sm = ServiceManager.getInstance();
      sm.cancelAllQueue();
      form.append( "Queue cleared.\n" );
    }
    catch (ServiceException e) {
      //System.out.println("Error clearing queue: " + e.getErrorCode() + " " + e.getMessage());
      form.append("Error with code: " + e.getErrorCode() + ", clearing queue, message: " + e.getMessage() + "\n");
    }
  }


  /**
   * Clear ALL entries from the response cache.
   */
  void clearCache()
  {
    try {
      ServiceManager sm = ServiceManager.getInstance();
      sm.clearCache();
      form.append( "Cache cleared.\n" );
    }
    catch (ServiceException e) {
      //System.out.println("Error clearing cache: " + e.getErrorCode() + " " + e.getMessage());
      form.append("Error with code: " + e.getErrorCode() + ", clearing cache, message: " + e.getMessage() + "\n");
    }
  }

  // Clear the screen.
  void clearScreen()
  {
    for (int i = (form.size() - 1); i >= 0; i--) {
      form.delete(i);
    }
  }

    private void initMIDlet()
    {
      // Get the URL of the J2ME proxy server.
      String servURL = getAppProperty("oracle-j2me-server-url");

      if (servURL == null) {
	      servURL = "http://localhost:7777/mcs/wsproxy/proxy";
	      //System.out.println("Unable to get j2me_proxy app property, using default: " + servURL);
      }

      serviceFactory = ServiceFactory.getInstance();
      service = serviceFactory.createService(servURL, "DEFAULT", "TestWebService");

      // Display, etc.
      display = Display.getDisplay(this);

      exitCommand = new Command("Exit", Command.EXIT, 1);
      queueCommand = new Command("Queue hello", Command.SCREEN, 1);
      clearQCommand = new Command("Clear Queue", Command.SCREEN, 2);
      clearCCommand = new Command("Clear Cache", Command.SCREEN, 2);
      clearSCommand = new Command("Clear Screen", Command.SCREEN, 2);

      form = new SimpleForm();
      display.setCurrent( form );
    }


  // On exit from the midlet, clear cache and queue.
  private void exitMIDlet()
  {
    clearQueue();
    clearCache();
    try {
      ServiceManager.getInstance().close();
    }
    catch (Exception e) {
    }
    notifyDestroyed();
  }


  // Call the remote procedure using the queue.
    private void callService()
    {
      int retCode;
      String retVal = null;

      boolean done = false;
      short tries = 0;

      // Maximum number of times to check if queued call succeeded.
      final short maxTries = 20;

      // Create call with no caching (0 minutes to live).
      Call call = service.createCall("hello", 0);
      Response response;
      Call invokedCall;

      Vector params = new Vector();
      params.addElement(new String("World"));

      try {
	      ServiceManager sm = ServiceManager.getInstance();
	
	      if (call == null) {
	        retVal = "Call object is null!\n";
	      }
	      else {
	        // This is a test of call queueing, but it is not real because you're always
	        // supposed to invoke the call before queueing it, and you should
	        // only queue it if the call failed because of a network error
          // (ServiceException.getErrorCode returns ServiceException.CONNECTION_FAILED)

	        System.out.println("About to queue call...");

	        // Parameters are set when you call Call.invoke().
          // For this example, however, the invoke() method has not been called,
          // so we set them with setParameters().
	        call.setParameters( params );

	        // Queue the call.
	        retCode = sm.queueCall( call );
	  
	        System.out.println("Call queued!");

	        // Loop until dequeued call is found, or max tries reached.
	        while ( !done && ( tries < maxTries )) {
	          tries++;

	          System.out.println("Will sleep 10 seconds.");

	          try {
	            // Sleep 10 seconds.
	            Thread.sleep( 10000 );
	          }
	          catch (InterruptedException e) {
	          }
	  
	          System.out.println("Woke up, check if queued call has succeeded.");

	          // Get list of all queued calls that have been invoked.
	          // (true parameter means get only queued calls that have been
	          // invoked)
	          int[] invokedCalls = sm.getQueuedCalls( true );

	          if (invokedCalls != null) {
	            // Check if the call we queued is on the list of invoked calls.
	            for (int i = 0; i < invokedCalls.length; i++) {
		            if (invokedCalls[i] == retCode) {
		              // found invoked call
		              System.out.println("Queued call succeeded.");
		              done = true;
		            }
	            }
	          }
	        }

	        if (done) {
	          // Found invoked call id.  Get the call object.
	          invokedCall = sm.getQueuedCall( retCode );

	          // System.out.println("After getQueuedCall.");

	          if ( invokedCall == null ) {
	            //System.out.println("Invoked call not found!");
	            retVal = "Invoked call not found!\n";
	          }
	          else {
	            // So that the service object in this sample
	            // gets the session information, copy the service
	            // object from the invoked call to the service object
	            // of this sample.
	            this.service = invokedCall.getService();

	            // Get the response of the invoked call.
	            response = invokedCall.getResponse();

	            // System.out.println("After call.getResponse.");
	      
	            if ( response == null ) {
		            //System.out.println("Response is null!");
		            retVal = "Response is null!\n";
	            }
	            else {
		            // Check if the response is valid (0 = OK).
		            retCode = response.getReturnCode();
	  
		            //System.out.println("Return code is: " + retCode);
		
		            if (retCode == 0) {
		              // Check if return is null.
		              if (response.getString() == null) {
		                retVal = "Null or void return.\n";
		              }
		              else {
		                retVal = response.getString() + "\n";
		              }
		            }
		            else {  // return code not 0
		              retVal = "Call unsuccessful: " + response.getErrorMsg() + "\n";
		            }
	            }
	          }
	        }
	        else {
	          retVal = "Waited, but call not invoked.\n";
	        }
	      }
      }
      catch (ServiceException e) {
	      retVal = new String("Error with code: " + e.getErrorCode() + ", message: " + e.getMessage() + "\n");
      }

      // Display the result of the call.
      form.append( new StringItem( null, retVal ) );
    }

    class SimpleForm extends Form
    {
      SimpleForm() {
	      super( "Sample5" );

  	    addCommand(exitCommand);
	      addCommand(queueCommand);
	      addCommand(clearQCommand);
	      addCommand(clearCCommand);
  	    addCommand(clearSCommand);

  	    setCommandListener(Sample5.this);
	    }
    }
}
