// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/GoProMode.java
// public enum GoProMode {
//     VIDEO (0, R.string.video, GoProCommand.SET_VIDEO),
//     PHOTO (1, R.string.photo, GoProCommand.SET_PHOTO),
//     BURST (2, R.string.burst, GoProCommand.SET_BURST),
//     TIMELAPSE (3, R.string.timelapse, GoProCommand.SET_TIMELAPSE);
// 
//     int index;
//     int labelResId;
//     GoProCommand command;
// 
//     GoProMode(int index, @StringRes int labelResId, GoProCommand command) {
//         this.index = index;
//         this.labelResId = labelResId;
//         this.command = command;
//     }
// 
//     private int getIndex() {
//         return index;
//     }
// 
//     @StringRes
//     public int getLabelResId() {
//         return labelResId;
//     }
// 
//     public GoProCommand getCommand() {
//         return command;
//     }
// 
//     public static GoProMode from(int modeIndex) {
//         for (GoProMode mode : GoProMode.values()) {
//             if (modeIndex == mode.getIndex()) {
//                 return mode;
//             }
//         }
//         return VIDEO;
//     }
// }
// 
// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/GoProState.java
// @AutoValue
// public abstract class GoProState {
// 
//     public static final GoProState CAMERA_OFF = GoProStateParser.cameraOff();
// 
//     private static final int NO_SD_CARD = 255;
// 
//     public abstract byte[] rawState();
//     public abstract GoProMode currentMode();
//     public abstract GoProMode startupMode();
//     public abstract int recordingMinutes();
//     public abstract int recordingSeconds();
//     public abstract int beepVolume();
//     public abstract LedState ledState();
//     //public abstract boolean previewEnabled();
//     public abstract Orientation orientation();
//     public abstract int batteryPercent(); // 99 for 99%
//     public abstract int photosAvailable();
//     public abstract int photoCount();
//     public abstract int videoAvailableMinutes();
//     public abstract int videoCount();
//     public abstract boolean recording();
// 
//     public static Builder builder() {
//         return new AutoValue_GoProState.Builder();
//     }
// 
//     @AutoValue.Builder
//     public abstract static class Builder {
//         public abstract Builder rawState(byte[] rawState);
//         public abstract Builder currentMode(GoProMode mode);
//         public abstract Builder startupMode(GoProMode mode);
//         public abstract Builder recordingMinutes(int minutes);
//         public abstract Builder recordingSeconds(int seconds);
//         public abstract Builder beepVolume(int volume);
//         public abstract Builder ledState(LedState state);
//         //public abstract Builder previewEnabled(boolean enabled);
//         public abstract Builder orientation(Orientation orientation);
//         public abstract Builder batteryPercent(int percent); // 99 for 99%
//         public abstract Builder photosAvailable(int photos);
//         public abstract Builder photoCount(int count);
//         public abstract Builder videoAvailableMinutes(int availableMinutes);
//         public abstract Builder videoCount(int count);
//         public abstract Builder recording(boolean recording);
//         public abstract GoProState build();
//     }
// 
//     public boolean isPowerOn() {
//         return this != CAMERA_OFF;
//     }
// 
//     // TODO: confirm this or if just high-byte (of 2) must be 255
//     public boolean hasSdCard() {
//         return photosAvailable() == NO_SD_CARD;
//     }
// 
//     public String logRawState() {
//         return String.format("camera current state: " + Arrays.toString(rawState()));
//     }
// 
//     public boolean isRecordingCurrently() {
//         return recording() && currentMode() != GoProMode.BURST;
//     }
// }
// 
// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/LedState.java
// public enum LedState {
//     NONE (0),
//     HALF (1),
//     ALL (2);
// 
//     int value;
// 
//     LedState(int value) {
//         this.value = value;
//     }
// }
// 
// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/Orientation.java
// public enum Orientation {
//     UP (0),
//     DOWN (1);
// 
//     int value;
// 
//     Orientation(int value) {
//         this.value = value;
//     }
// }


import com.github.jbarr21.goproremote.common.data.GoProMode;
import com.github.jbarr21.goproremote.common.data.GoProState;
import com.github.jbarr21.goproremote.common.data.LedState;
import com.github.jbarr21.goproremote.common.data.Orientation;
package com.github.jbarr21.goproremote.common.utils;


public class GoProStateParser {
    public static GoProState from(byte[] bytes) {
        if (bytes.length > 30) {
            // Camera is On
            return GoProState.builder()
                    .rawState(bytes)
                    .currentMode(GoProMode.values()[bytes[1]])
                    .startupMode(GoProMode.values()[bytes[3]])
                    .recordingMinutes(bytes[13])
                    .recordingSeconds(bytes[14])
                    .beepVolume(bytes[16])
                    .ledState(LedState.values()[bytes[17]])
                    .orientation(Orientation.UP) // TODO: figure out how to get this
                    .batteryPercent(bytes[19])
                    .photosAvailable(toInt(bytes[21], bytes[22]))
                    .photoCount(toInt(bytes[23], bytes[24]))
                    .videoAvailableMinutes(toInt(bytes[25], bytes[26]))
                    .videoCount(toInt(bytes[27], bytes[28]))
                    .recording(bytes[29] > 0)
                    .build();
        } else {
            // Camera is OFF
            return GoProState.CAMERA_OFF;
        }
    }

    public static GoProState cameraOff() {
        return GoProState.builder()
                .rawState(new byte[0])
                .currentMode(GoProMode.VIDEO)
// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/GoProMode.java
// public enum GoProMode {
//     VIDEO (0, R.string.video, GoProCommand.SET_VIDEO),
//     PHOTO (1, R.string.photo, GoProCommand.SET_PHOTO),
//     BURST (2, R.string.burst, GoProCommand.SET_BURST),
//     TIMELAPSE (3, R.string.timelapse, GoProCommand.SET_TIMELAPSE);
// 
//     int index;
//     int labelResId;
//     GoProCommand command;
// 
//     GoProMode(int index, @StringRes int labelResId, GoProCommand command) {
//         this.index = index;
//         this.labelResId = labelResId;
//         this.command = command;
//     }
// 
//     private int getIndex() {
//         return index;
//     }
// 
//     @StringRes
//     public int getLabelResId() {
//         return labelResId;
//     }
// 
//     public GoProCommand getCommand() {
//         return command;
//     }
// 
//     public static GoProMode from(int modeIndex) {
//         for (GoProMode mode : GoProMode.values()) {
//             if (modeIndex == mode.getIndex()) {
//                 return mode;
//             }
//         }
//         return VIDEO;
//     }
// }
// 
// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/GoProState.java
// @AutoValue
// public abstract class GoProState {
// 
//     public static final GoProState CAMERA_OFF = GoProStateParser.cameraOff();
// 
//     private static final int NO_SD_CARD = 255;
// 
//     public abstract byte[] rawState();
//     public abstract GoProMode currentMode();
//     public abstract GoProMode startupMode();
//     public abstract int recordingMinutes();
//     public abstract int recordingSeconds();
//     public abstract int beepVolume();
//     public abstract LedState ledState();
//     //public abstract boolean previewEnabled();
//     public abstract Orientation orientation();
//     public abstract int batteryPercent(); // 99 for 99%
//     public abstract int photosAvailable();
//     public abstract int photoCount();
//     public abstract int videoAvailableMinutes();
//     public abstract int videoCount();
//     public abstract boolean recording();
// 
//     public static Builder builder() {
//         return new AutoValue_GoProState.Builder();
//     }
// 
//     @AutoValue.Builder
//     public abstract static class Builder {
//         public abstract Builder rawState(byte[] rawState);
//         public abstract Builder currentMode(GoProMode mode);
//         public abstract Builder startupMode(GoProMode mode);
//         public abstract Builder recordingMinutes(int minutes);
//         public abstract Builder recordingSeconds(int seconds);
//         public abstract Builder beepVolume(int volume);
//         public abstract Builder ledState(LedState state);
//         //public abstract Builder previewEnabled(boolean enabled);
//         public abstract Builder orientation(Orientation orientation);
//         public abstract Builder batteryPercent(int percent); // 99 for 99%
//         public abstract Builder photosAvailable(int photos);
//         public abstract Builder photoCount(int count);
//         public abstract Builder videoAvailableMinutes(int availableMinutes);
//         public abstract Builder videoCount(int count);
//         public abstract Builder recording(boolean recording);
//         public abstract GoProState build();
//     }
// 
//     public boolean isPowerOn() {
//         return this != CAMERA_OFF;
//     }
// 
//     // TODO: confirm this or if just high-byte (of 2) must be 255
//     public boolean hasSdCard() {
//         return photosAvailable() == NO_SD_CARD;
//     }
// 
//     public String logRawState() {
//         return String.format("camera current state: " + Arrays.toString(rawState()));
//     }
// 
//     public boolean isRecordingCurrently() {
//         return recording() && currentMode() != GoProMode.BURST;
//     }
// }
// 
// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/LedState.java
// public enum LedState {
//     NONE (0),
//     HALF (1),
//     ALL (2);
// 
//     int value;
// 
//     LedState(int value) {
//         this.value = value;
//     }
// }
// 
// Path: common/src/main/java/com/github/jbarr21/goproremote/common/data/Orientation.java
// public enum Orientation {
//     UP (0),
//     DOWN (1);
// 
//     int value;
// 
//     Orientation(int value) {
//         this.value = value;
//     }
// }


// Path: common/src/main/java/com/github/jbarr21/goproremote/common/utils/GoProStateParser.java
import com.github.jbarr21.goproremote.common.data.GoProMode;
import com.github.jbarr21.goproremote.common.data.GoProState;
import com.github.jbarr21.goproremote.common.data.LedState;
import com.github.jbarr21.goproremote.common.data.Orientation;

package com.github.jbarr21.goproremote.common.utils;


public class GoProStateParser {
    public static GoProState from(byte[] bytes) {
        if (bytes.length > 30) {
            // Camera is On
            return GoProState.builder()
                    .rawState(bytes)
                    .currentMode(GoProMode.values()[bytes[1]])
                    .startupMode(GoProMode.values()[bytes[3]])
                    .recordingMinutes(bytes[13])
                    .recordingSeconds(bytes[14])
                    .beepVolume(bytes[16])
                    .ledState(LedState.values()[bytes[17]])
                    .orientation(Orientation.UP) // TODO: figure out how to get this
                    .batteryPercent(bytes[19])
                    .photosAvailable(toInt(bytes[21], bytes[22]))
                    .photoCount(toInt(bytes[23], bytes[24]))
                    .videoAvailableMinutes(toInt(bytes[25], bytes[26]))
                    .videoCount(toInt(bytes[27], bytes[28]))
                    .recording(bytes[29] > 0)
                    .build();
        } else {
            // Camera is OFF
            return GoProState.CAMERA_OFF;
        }
    }

    public static GoProState cameraOff() {
        return GoProState.builder()
                .rawState(new byte[0])
                .currentMode(GoProMode.VIDEO)
                .startupMode(GoProMode.VIDEO)