import jspack from 'jspack';
import Mavlink20Header from './mavlink20_header';

class Mavlink20 {

    header;
    payload;

    static HEADER_LEN = 10;

    static x25Crc(buffer, crcIN) {
        let bytes = buffer;
        let crcOUT = crcIN || 0xffff;
        bytes.forEach(e => {
            let tmp = e ^ (crcOUT & 0xff);
            tmp = (tmp ^ (tmp << 4)) & 0xff;
            crcOUT = (crcOUT >> 8) ^ (tmp << 8) ^ (tmp << 3) ^ (tmp >> 4);
            crcOUT = crcOUT & 0xffff;
        })
        return crcOUT
    }

    pack(mav, crc_extra, payload) {

        this.payload = payload;
        let plen = this.payload.length;

        //in MAVLink2 we can strip trailing zeros off payloads. This allows for simple
        // variable length arrays and smaller packets
        while (plen > 1 && this.payload[plen - 1] == 0) {
            plen = plen - 1;
        }
        this.payload = this.payload.slice(0, plen);
        let incompat_flags = 0;
        this.header = new Mavlink20Header(this.msg_id, this.payload.length, mav.seq, mav.srcSystem, mav.srcComponent, incompat_flags, 0);

        this.msgbuf = this.header.pack().concat(this.payload);
        let crc = Mavlink20.x25Crc(this.msgbuf.slice(1));

        // For now, assume always using crc_extra = True.  TODO: check/fix this.
        crc = Mavlink20.x25Crc([crc_extra], crc);
        this.msgbuf = this.msgbuf.concat(jspack.Pack('<H', [crc]));
        return this.msgbuf;
    }

}

export default Mavlink20;