import * as Token from 'token-types';
import * as util from '../common/Util.js';
/**
 * The picture type according to the ID3v2 APIC frame
 * Ref: http://id3.org/id3v2.3.0#Attached_picture
 */
export const AttachedPictureType = {
    0: 'Other',
    1: "32x32 pixels 'file icon' (PNG only)",
    2: 'Other file icon',
    3: 'Cover (front)',
    4: 'Cover (back)',
    5: 'Leaflet page',
    6: 'Media (e.g. label side of CD)',
    7: 'Lead artist/lead performer/soloist',
    8: 'Artist/performer',
    9: 'Conductor',
    10: 'Band/Orchestra',
    11: 'Composer',
    12: 'Lyricist/text writer',
    13: 'Recording Location',
    14: 'During recording',
    15: 'During performance',
    16: 'Movie/video screen capture',
    17: 'A bright coloured fish',
    18: 'Illustration',
    19: 'Band/artist logotype',
    20: 'Publisher/Studio logotype'
};
/**
 * https://id3.org/id3v2.3.0#Synchronised_lyrics.2Ftext
 */
export const LyricsContentType = {
    other: 0,
    lyrics: 1,
    text: 2,
    movement_part: 3,
    events: 4,
    chord: 5,
    trivia_pop: 6,
};
export const TimestampFormat = {
    notSynchronized0: 0,
    mpegFrameNumber: 1,
    milliseconds: 2
};
/**
 * 28 bits (representing up to 256MB) integer, the msb is 0 to avoid 'false syncsignals'.
 * 4 * %0xxxxxxx
 */
export const UINT32SYNCSAFE = {
    get: (buf, off) => {
        return buf[off + 3] & 0x7f | ((buf[off + 2]) << 7) |
            ((buf[off + 1]) << 14) | ((buf[off]) << 21);
    },
    len: 4
};
/**
 * ID3v2 header
 * Ref: http://id3.org/id3v2.3.0#ID3v2_header
 * ToDo
 */
export const ID3v2Header = {
    len: 10,
    get: (buf, off) => {
        return {
            // ID3v2/file identifier   "ID3"
            fileIdentifier: new Token.StringType(3, 'ascii').get(buf, off),
            // ID3v2 versionIndex
            version: {
                major: Token.INT8.get(buf, off + 3),
                revision: Token.INT8.get(buf, off + 4)
            },
            // ID3v2 flags
            flags: {
                // Unsynchronisation
                unsynchronisation: util.getBit(buf, off + 5, 7),
                // Extended header
                isExtendedHeader: util.getBit(buf, off + 5, 6),
                // Experimental indicator
                expIndicator: util.getBit(buf, off + 5, 5),
                footer: util.getBit(buf, off + 5, 4)
            },
            size: UINT32SYNCSAFE.get(buf, off + 6)
        };
    }
};
export const ExtendedHeader = {
    len: 10,
    get: (buf, off) => {
        return {
            // Extended header size
            size: Token.UINT32_BE.get(buf, off),
            // Extended Flags
            extendedFlags: Token.UINT16_BE.get(buf, off + 4),
            // Size of padding
            sizeOfPadding: Token.UINT32_BE.get(buf, off + 6),
            // CRC data present
            crcDataPresent: util.getBit(buf, off + 4, 31)
        };
    }
};
export const TextEncodingToken = {
    len: 1,
    get: (uint8Array, off) => {
        switch (uint8Array[off]) {
            case 0x00:
                return { encoding: 'latin1' }; // binary
            case 0x01:
                return { encoding: 'utf-16le', bom: true };
            case 0x02:
                return { encoding: 'utf-16le', bom: false };
            case 0x03:
                return { encoding: 'utf8', bom: false };
            default:
                return { encoding: 'utf8', bom: false };
        }
    }
};
/**
 * Used to read first portion of `SYLT` frame
 */
export const TextHeader = {
    len: 4,
    get: (uint8Array, off) => {
        return {
            encoding: TextEncodingToken.get(uint8Array, off),
            language: new Token.StringType(3, 'latin1').get(uint8Array, off + 1)
        };
    }
};
/**
 * Used to read first portion of `SYLT` frame
 */
export const SyncTextHeader = {
    len: 6,
    get: (uint8Array, off) => {
        const text = TextHeader.get(uint8Array, off);
        return {
            encoding: text.encoding,
            language: text.language,
            timeStampFormat: Token.UINT8.get(uint8Array, off + 4),
            contentType: Token.UINT8.get(uint8Array, off + 5)
        };
    }
};
