import java.util.Vector;
import javax.microedition.midlet.*;
import javax.microedition.lcdui.*;
import javax.microedition.io.*;

public class WakeOnLan extends MIDlet implements CommandListener {

       private Display display;
       private Form mainScr;

       private Command OKCommand;
       private Command ClearCommand;
       private Command exitCommand;

       private static TextField tfIP;
       private static TextField tfMAC;

       private Alert alert;

       private static final int PORT = 9;

       public WakeOnLan(){
               display = Display.getDisplay(this);
               mainScr = new Form("WakeOnLan Mob");
               tfIP = new TextField("IP Address:\n", "", 16, 0);
               tfMAC = new TextField("MAC Address:\n", "", 17, 0);
               mainScr.append(tfIP);
               mainScr.append(tfMAC);
               mainScr.append("� 2007 jambel.net");
               OKCommand = new Command("Send", Command.OK, 1);
               ClearCommand = new Command("Clear", Command.ITEM, 1);
               exitCommand = new Command("Exit", Command.EXIT, 1);
               mainScr.addCommand(OKCommand);
               mainScr.addCommand(ClearCommand);
               mainScr.addCommand(exitCommand);
               mainScr.setCommandListener(this);
       }

       private class SendPacket implements Runnable {
               public void run(){
                       SendStr(tfIP.getString(), tfMAC.getString());
               }

               private void SendStr(String ipStr, String macStr) {
                       if(ipStr.length() == 0 || macStr.length() == 0)
                       {
                               alert = new Alert("Please fill IP and MAC address fields.");
                               display.setCurrent(alert, mainScr);
                               return;
                       }
                       else
                       {
                               try {
                                       byte[] macBytes = getMacBytes();
                                       byte[] bytes = new byte[6 + 16 * macBytes.length];
                                       for (int i = 0; i < 6; i++) {
                                       bytes[i] = (byte) 0xff;
                               }
                               for (int i = 6; i < bytes.length; i += macBytes.length) {
                                       System.arraycopy(macBytes, 0, bytes, i, macBytes.length);
                               }

                               String address = "datagram://" + ipStr + ":" + PORT;
                               DatagramConnection packet = (DatagramConnection)Connector.open(address);
                               Datagram dgram = packet.newDatagram(bytes, bytes.length, address);
                               packet.send(dgram);
                               packet.close();

                               alert = new Alert("Wake-on-LAN packet sent.");
                               display.setCurrent(alert, mainScr);
                               }
                               catch (Exception e) {
                                       alert = new Alert("Failed to send Wake-on-LAN packet: " + e);
                                       display.setCurrent(alert, mainScr);
                                       return;
                                       //System.exit(1);
                               }
                       }
               }
       }

       private byte[] getMacBytes() throws IllegalArgumentException {
               byte[] bytes = new byte[6];
               String sep;
               if(tfMAC.getString().indexOf(":") > 0)
                       sep=":";
               else
                       sep="-";
               String[] hex = split(tfMAC.getString(),sep);
               if (hex.length != 6) {
                       throw new IllegalArgumentException("Invalid MAC address.");
               }
               try {
                       for (int i = 0; i < 6; i++) {
                               bytes[i] = (byte) Integer.parseInt(hex[i], 16);
                       }
               }
               catch (NumberFormatException e) {
                       throw new IllegalArgumentException("Invalid hex digit in MAC address.");
               }
       return bytes;
       }

       private static String[] split(String original, String separator) {
               Vector nodes = new Vector();

               // Parse nodes into vector
               int index = original.indexOf(separator);
               while(index>=0) {
                       nodes.addElement( original.substring(0, index) );
                       original = original.substring(index+separator.length());
                       index = original.indexOf(separator);
               }
               // Get the last node
               nodes.addElement( original );

               // Create splitted string array
               String[] result = new String[ nodes.size() ];
               if( nodes.size()>0 ) {
                       for(int loop=0; loop < nodes.size(); loop++)
                               result[loop] = (String)nodes.elementAt(loop);
               }
               return result;
       }

       public void commandAction(Command c, Displayable d) {
               if (c == OKCommand) {
                       if (d == mainScr) {
                               SendPacket doIt = new SendPacket();
                               Thread myThread = new Thread( doIt );
                               myThread.start();
                       } else {
                               display.setCurrent(mainScr);
                       }
               } else if (c == ClearCommand) {
                       tfIP.setString("");
                       tfMAC.setString("");
               } else if (c == exitCommand) {
                       destroyApp(false);
                       notifyDestroyed();
               }
       }

       public void startApp() {
               Display.getDisplay(this).setCurrent(mainScr);
       }

       public void pauseApp() {
       }

       public void destroyApp(boolean unconditional) {
       }
}