// Path: src/main/java/nu/nethome/coders/decoders/ZhejiangDecoder.java
// @Plugin
// public class ZhejiangDecoder extends NexaDecoder implements ProtocolDecoder{
// 
//     // This are the pulse length constants for the protocol. The default values may
//     // be overridden by system properties
//     public static final PulseLength ZHEJ_LONG_MARK =
//             new PulseLength(ZhejiangDecoder.class, "ZHEJ_LONG_MARK", 430, 370, 550);
//     public static final PulseLength ZHEJ_SHORT_MARK =
//             new PulseLength(ZhejiangDecoder.class, "ZHEJ_SHORT_MARK", 140, 100, 220);
//     public static final PulseLength ZHEJ_LONG_SPACE =
//             new PulseLength(ZhejiangDecoder.class, "ZHEJ_LONG_SPACE", 450, 370, 550);
//     public static final PulseLength ZHEJ_SHORT_SPACE =
//             new PulseLength(ZhejiangDecoder.class, "ZHEJ_SHORT_SPACE", 170, 100, 220);
//     public static final PulseLength ZHEJ_REPEAT =
//             new PulseLength(ZhejiangDecoder.class, "ZHEJ_REPEAT", 4560, 500);
// 
//     public void setup() {
//         m_ProtocolName = "Zhejiang";
//         LONG_MARK = ZHEJ_LONG_MARK;
//         SHORT_MARK = ZHEJ_SHORT_MARK;
//         LONG_SPACE = ZHEJ_LONG_SPACE;
//         SHORT_SPACE = ZHEJ_SHORT_SPACE;
//         REPEAT = ZHEJ_REPEAT;
//     }
// 
//     protected int bytemap(int raw) {
//         return (raw & 1) + ((raw >> 1) & 2) + ((raw >> 2) & 4) + ((raw >> 3) & 8) + ((raw >> 4) & 0x10);
//     }
// 
//     protected void addBit(int b) {
//         // Shift in data
//         m_Data >>= 1;
//         m_Data |= (b << 24);
//         // Check if this is a complete message
//         if (m_BitCounter == 24) {
//             // It is, create the message
//             int command = ((m_Data >> 23) & 1) ^ 1;
//             int rawButton = bytemap(((m_Data >> 11) ^ 0x3FF) & 0x3FF);
//             int address = bytemap((m_Data ^ 0x3FF) & 0x3FF);
//             int button = bitPosToInt(rawButton);
// 
//             // Sender ends a message sequence by a signal saying "no button is pressed".
//             // We ignore that message.
//             if (rawButton == 0) {
//                 m_State = IDLE;
//                 m_RepeatCount = 0;
//                 return;
//             }
// 
//             ProtocolMessage message = new ProtocolMessage(m_ProtocolName, command, (rawButton << 8) + address, 4);
//             message.setRawMessageByteAt(0, (m_Data >> 24) & 0x1);
//             message.setRawMessageByteAt(1, (m_Data >> 16) & 0xFF);
//             message.setRawMessageByteAt(2, (m_Data >> 8) & 0xFF);
//             message.setRawMessageByteAt(3, (m_Data) & 0xFF);
// 
//             message.addField(new FieldValue("Command", command));
//             message.addField(new FieldValue("Button", button));
//             message.addField(new FieldValue("Address", address));
// 
//             // It is, check if this really is a repeat
//             if ((m_RepeatCount > 0) && (m_Data == m_LastData)) {
//                 message.setRepeat(m_RepeatCount);
//             } else {
//                 // It is not a repeat, reset counter
//                 m_RepeatCount = 0;
//             }
//             // Report the parsed message
//             m_Sink.parsedMessage(message);
//             m_State = REPEAT_SCAN;
//         }
//         m_BitCounter++;
//     }
// 
//     private int bitPosToInt(int rawButton) {
//         int shift = rawButton;
//         for (int i = 0; i < 5; i++) {
//             if ((shift & 1) == 1) {
//                 return i;
//             }
//             shift >>= 1;
//         }
//         return 5;
//     }
// }


import java.util.ArrayList;
import nu.nethome.coders.decoders.ZhejiangDecoder;
import nu.nethome.util.plugin.Plugin;
import nu.nethome.util.ps.*;

    public static Message buildMessage(int command, int button, int address) {
        ProtocolMessage result = new ProtocolMessage("Zhejiang", command, address, 0);
        result.addField(new FieldValue("Command", command));
        result.addField(new FieldValue("Address", address));
        result.addField(new FieldValue("Button", button));
        return result;
    }

    private int[] encode(int command, int button, int address) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        long message = 0x2003FF;
        message = copyBit(command, 0, message, 21, false);
        message = copyBit(command, 0, message, 23, true);
        int buttonBit = 1 << button;
        message = copyBit(buttonBit, 0, message, 11, true);
        message = copyBit(buttonBit, 1, message, 13, true);
        message = copyBit(buttonBit, 2, message, 15, true);
        message = copyBit(buttonBit, 3, message, 17, true);
        message = copyBit(buttonBit, 4, message, 19, true);

        message = copyBit(address, 0, message, 0, true);
        message = copyBit(address, 1, message, 2, true);
        message = copyBit(address, 2, message, 4, true);
        message = copyBit(address, 3, message, 6, true);
        message = copyBit(address, 4, message, 8, true);

        // Encode message bits
        for (int j = 0; j < (ZHEJIANG_RAW_MESSAGE_LENGTH); j++) {
            if ((message & 1) == 1) {
// Path: src/main/java/nu/nethome/coders/decoders/ZhejiangDecoder.java
// @Plugin
// public class ZhejiangDecoder extends NexaDecoder implements ProtocolDecoder{
// 
//     // This are the pulse length constants for the protocol. The default values may
//     // be overridden by system properties
//     public static final PulseLength ZHEJ_LONG_MARK =
//             new PulseLength(ZhejiangDecoder.class, "ZHEJ_LONG_MARK", 430, 370, 550);
//     public static final PulseLength ZHEJ_SHORT_MARK =
//             new PulseLength(ZhejiangDecoder.class, "ZHEJ_SHORT_MARK", 140, 100, 220);
//     public static final PulseLength ZHEJ_LONG_SPACE =
//             new PulseLength(ZhejiangDecoder.class, "ZHEJ_LONG_SPACE", 450, 370, 550);
//     public static final PulseLength ZHEJ_SHORT_SPACE =
//             new PulseLength(ZhejiangDecoder.class, "ZHEJ_SHORT_SPACE", 170, 100, 220);
//     public static final PulseLength ZHEJ_REPEAT =
//             new PulseLength(ZhejiangDecoder.class, "ZHEJ_REPEAT", 4560, 500);
// 
//     public void setup() {
//         m_ProtocolName = "Zhejiang";
//         LONG_MARK = ZHEJ_LONG_MARK;
//         SHORT_MARK = ZHEJ_SHORT_MARK;
//         LONG_SPACE = ZHEJ_LONG_SPACE;
//         SHORT_SPACE = ZHEJ_SHORT_SPACE;
//         REPEAT = ZHEJ_REPEAT;
//     }
// 
//     protected int bytemap(int raw) {
//         return (raw & 1) + ((raw >> 1) & 2) + ((raw >> 2) & 4) + ((raw >> 3) & 8) + ((raw >> 4) & 0x10);
//     }
// 
//     protected void addBit(int b) {
//         // Shift in data
//         m_Data >>= 1;
//         m_Data |= (b << 24);
//         // Check if this is a complete message
//         if (m_BitCounter == 24) {
//             // It is, create the message
//             int command = ((m_Data >> 23) & 1) ^ 1;
//             int rawButton = bytemap(((m_Data >> 11) ^ 0x3FF) & 0x3FF);
//             int address = bytemap((m_Data ^ 0x3FF) & 0x3FF);
//             int button = bitPosToInt(rawButton);
// 
//             // Sender ends a message sequence by a signal saying "no button is pressed".
//             // We ignore that message.
//             if (rawButton == 0) {
//                 m_State = IDLE;
//                 m_RepeatCount = 0;
//                 return;
//             }
// 
//             ProtocolMessage message = new ProtocolMessage(m_ProtocolName, command, (rawButton << 8) + address, 4);
//             message.setRawMessageByteAt(0, (m_Data >> 24) & 0x1);
//             message.setRawMessageByteAt(1, (m_Data >> 16) & 0xFF);
//             message.setRawMessageByteAt(2, (m_Data >> 8) & 0xFF);
//             message.setRawMessageByteAt(3, (m_Data) & 0xFF);
// 
//             message.addField(new FieldValue("Command", command));
//             message.addField(new FieldValue("Button", button));
//             message.addField(new FieldValue("Address", address));
// 
//             // It is, check if this really is a repeat
//             if ((m_RepeatCount > 0) && (m_Data == m_LastData)) {
//                 message.setRepeat(m_RepeatCount);
//             } else {
//                 // It is not a repeat, reset counter
//                 m_RepeatCount = 0;
//             }
//             // Report the parsed message
//             m_Sink.parsedMessage(message);
//             m_State = REPEAT_SCAN;
//         }
//         m_BitCounter++;
//     }
// 
//     private int bitPosToInt(int rawButton) {
//         int shift = rawButton;
//         for (int i = 0; i < 5; i++) {
//             if ((shift & 1) == 1) {
//                 return i;
//             }
//             shift >>= 1;
//         }
//         return 5;
//     }
// }


// Path: src/main/java/nu/nethome/coders/encoders/ZhejiangEncoder.java
import java.util.ArrayList;
import nu.nethome.coders.decoders.ZhejiangDecoder;
import nu.nethome.util.plugin.Plugin;
import nu.nethome.util.ps.*;


    public static Message buildMessage(int command, int button, int address) {
        ProtocolMessage result = new ProtocolMessage("Zhejiang", command, address, 0);
        result.addField(new FieldValue("Command", command));
        result.addField(new FieldValue("Address", address));
        result.addField(new FieldValue("Button", button));
        return result;
    }

    private int[] encode(int command, int button, int address) {
        ArrayList<Integer> result = new ArrayList<Integer>();
        long message = 0x2003FF;
        message = copyBit(command, 0, message, 21, false);
        message = copyBit(command, 0, message, 23, true);
        int buttonBit = 1 << button;
        message = copyBit(buttonBit, 0, message, 11, true);
        message = copyBit(buttonBit, 1, message, 13, true);
        message = copyBit(buttonBit, 2, message, 15, true);
        message = copyBit(buttonBit, 3, message, 17, true);
        message = copyBit(buttonBit, 4, message, 19, true);

        message = copyBit(address, 0, message, 0, true);
        message = copyBit(address, 1, message, 2, true);
        message = copyBit(address, 2, message, 4, true);
        message = copyBit(address, 3, message, 6, true);
        message = copyBit(address, 4, message, 8, true);

        // Encode message bits
        for (int j = 0; j < (ZHEJIANG_RAW_MESSAGE_LENGTH); j++) {
            if ((message & 1) == 1) {
                result.add(ZhejiangDecoder.ZHEJ_LONG_MARK.length());