package net.sourcewalker.olv.messages;

import java.nio.ByteBuffer;

import net.sourcewalker.olv.messages.events.CapsResponse;
import net.sourcewalker.olv.messages.events.DeviceStatus;
import net.sourcewalker.olv.messages.events.GetTime;
import net.sourcewalker.olv.messages.events.GetMenuItems;
import net.sourcewalker.olv.messages.events.Navigation;
import net.sourcewalker.olv.messages.events.ResultEvent;

public final class MessageDecoder {

    private static LiveViewEvent newInstanceForId(byte id)
            throws DecodeException {
        switch (id) {
        case MessageConstants.MSG_GETCAPS_RESP:
            return new CapsResponse();
        case MessageConstants.MSG_SETVIBRATE_ACK:
        case MessageConstants.MSG_SETLED_ACK:
            return new ResultEvent(id);
        case MessageConstants.MSG_GETTIME:
            return new GetTime();
        case MessageConstants.MSG_GETMENUITEMS:
            return new GetMenuItems();
        case MessageConstants.MSG_DEVICESTATUS:
            return new DeviceStatus();
        case MessageConstants.MSG_NAVIGATION:
            return new Navigation();
        default:
            throw new DecodeException("No message found matching ID: " + id);
        }
    }

    public static final LiveViewEvent decode(byte[] message, int length)
            throws DecodeException {
        ByteBuffer buffer = ByteBuffer.wrap(message, 0, length);
        byte msgId = buffer.get();
        buffer.get();
        int payloadLen = buffer.getInt();
        if (payloadLen + 6 == length) {
            LiveViewEvent result = newInstanceForId(msgId);
            result.readData(buffer);
            return result;
        } else {
            throw new DecodeException("Invalid message length: "
                    + message.length + " (should be " + (payloadLen + 6) + ")");
        }
    }

}

@@ -225,20 +225,25 @@
 ents.Get
-Time
+MenuItems
 ;%0Aimport
@@ -279,33 +279,28 @@
 s.events.Get
-MenuItems
+Time
 ;%0Aimport net
@@ -401,16 +401,41 @@
 ltEvent;
+%0Aimport android.util.Log;
 %0A%0Apublic
@@ -465,16 +465,73 @@
 oder %7B%0A%0A
+    private static final String TAG = %22MessageDecoder%22;%0A%0A
     priv
@@ -1411,32 +1411,195 @@
 codeException %7B%0A
+        if (length %3C 4) %7B%0A            Log.w(TAG, %22Got empty message!%22);%0A            throw new DecodeException(%22Can't decode empty message!%22);%0A        %7D else %7B%0A    
         ByteBuff
@@ -1655,16 +1655,20 @@
         
+   
+ 
 byte msg
@@ -1694,16 +1694,20 @@
         
+    
 buffer.g
@@ -1720,16 +1720,20 @@
         
+   
+ 
 int payl
@@ -1762,24 +1762,28 @@
 ();%0A        
+    
 if (payloadL
@@ -1814,16 +1814,20 @@
         
+  
+  
 LiveView
@@ -1878,16 +1878,20 @@
         
+    
 result.r
@@ -1915,24 +1915,28 @@
             
+  
+  
 return resul
@@ -1938,32 +1938,36 @@
 result;%0A        
+    
 %7D else %7B%0A       
@@ -1963,32 +1963,36 @@
 e %7B%0A            
+ 
+   
 throw new Decode
@@ -2048,16 +2048,20 @@
         
+    
 + messag
@@ -2108,16 +2108,54 @@
 + 6)
- + %22)%22);
+%0A                        + %22)%22);%0A            %7D
 %0A   

Throw exception on short messages.