const eBearingMode = {
    none : 0,
    true : 1,
    mag : 2
}


/**
 * 
 * The field data object is ordered by field id and contains the following information:
 *      -> displayName: A human-readable name for the field.
 *      -> bearing: If the field has a bearing attached to it.
 *      -> sibling: Returns the paired field, currently used for true/mag channels.
 */

let fieldData = {
    //GPS Data
    '0x0100' : {displayName: 'Latitude', bearing: eBearingMode.none, sibling: null},
    '0x0101' : {displayName: 'Longitude', bearing: eBearingMode.none, sibling: null},
    '0x0102' : {displayName: 'HDOP', bearing: eBearingMode.none, sibling: null},
    '0x0103' : {displayName: 'SoG', bearing: eBearingMode.none, sibling: null},
    '0x0104' : {displayName: 'CoG (True)', bearing: eBearingMode.true, sibling: '0x0105'},
    '0x0105' : {displayName: 'CoG (Mag)', bearing: eBearingMode.mag, sibling: '0x0104'},
    '0x0106' : {displayName: 'Time (s)', bearing: eBearingMode.none, sibling: null},
    '0x0107' : {displayName: 'Time (hhmmss)', bearing: eBearingMode.none, sibling: null},
    '0x0108' : {displayName: 'GNSS Variation', bearing: eBearingMode.none, sibling: null},
    '0x0109' : {displayName: 'SoG (km/h)', bearing: eBearingMode.none, sibling: null},
    '0x0110' : {displayName: 'Latitude (NMEA0183)', bearing: eBearingMode.none, sibling: null},
    '0x0111' : {displayName: 'Longitude (NMEA0183)', bearing: eBearingMode.none, sibling: null},
    '0x0112' : {displayName: 'North-South Position', bearing: eBearingMode.none, sibling: null},
    '0x0113' : {displayName: 'East-West Position', bearing: eBearingMode.none, sibling: null},
    '0x0120' : {displayName: 'XTE', bearing: eBearingMode.none, sibling: null},
    '0x0121' : {displayName: 'VMG', bearing: eBearingMode.none, sibling: null},
    '0x0122' : {displayName: 'Distance to Waypoint', bearing: eBearingMode.none, sibling: null},
    '0x0123' : {displayName: 'Bearing to Waypoint (True)', bearing: eBearingMode.true, sibling: '0x0124'},
    '0x0124' : {displayName: 'Bearing to Waypoint (Mag)', bearing: eBearingMode.mag, sibling: '0x0123'},
    
    // Speed Board
    '0x0200' : {displayName: 'Log Pulse Time', bearing: eBearingMode.none, sibling: null},
    '0x0201' : {displayName: 'Log Pulse Count', bearing: eBearingMode.none, sibling: null},
    '0x0202' : {displayName: 'Boat Speed (kts)', bearing: eBearingMode.none, sibling: null},
    '0x0203' : {displayName: 'Boat Speed (m/s)', bearing: eBearingMode.none, sibling: null},
 
    // Wind Board
    '0x0300' : {displayName: 'Wind Pulse Time', bearing: eBearingMode.none, sibling: null},
    '0x0301' : {displayName: 'Wind Pulse Count', bearing: eBearingMode.none, sibling: null},
    '0x0302' : {displayName: 'MAWS (kts)', bearing: eBearingMode.none, sibling: null},
    '0x0303' : {displayName: 'MAWA', bearing: eBearingMode.none, sibling: null},
    '0x0304' : {displayName: 'MAWS (m/s)', bearing: eBearingMode.none, sibling: null},
    '0x0305' : {displayName: 'Wind Pulse Frequency', bearing: eBearingMode.none, sibling: null},
    '0x0320' : {displayName: 'Red Phase', bearing: eBearingMode.none, sibling: null},
    '0x0321' : {displayName: 'Green Phase', bearing: eBearingMode.none, sibling: null},
    '0x0322' : {displayName: 'Blue Phase', bearing: eBearingMode.none, sibling: null},
    '0x0323' : {displayName: 'MHU Voltage', bearing: eBearingMode.none, sibling: null},
 
    // Depth Board
    '0x0400' : {displayName: 'Depth Time', bearing: eBearingMode.none, sibling: null},
    '0x0401' : {displayName: 'Depth (m)', bearing: eBearingMode.none, sibling: null},
    '0x0402' : {displayName: 'Depth (ft)', bearing: eBearingMode.none, sibling: null},
    '0x0403' : {displayName: 'Depth (fathoms)', bearing: eBearingMode.none, sibling: null},
    '0x0404' : {displayName: 'Depth Offset', bearing: eBearingMode.none, sibling: null},

    // Heading Data
    '0x0500' : {displayName: 'Heading (True)', bearing: eBearingMode.true, sibling: '0x0501'},
    '0x0501' : {displayName: 'Heading (Mag)', bearing: eBearingMode.mag, sibling: '0x0500'},
    '0x0502' : {displayName: 'Variation', bearing: eBearingMode.none, sibling: null},
    '0x0503' : {displayName: 'Deviation', bearing: eBearingMode.none, sibling: null},
    '0x0504' : {displayName: 'Heading Offset (True)', bearing: eBearingMode.true, sibling: '0x0505'},
    '0x0505' : {displayName: 'Heading Offset (Mag)', bearing: eBearingMode.mag, sibling: '0x0504'},
    
    //Environmental Constants
    '0x0700' : {displayName: 'Air Temperature (C)', bearing: eBearingMode.none, sibling: null},
    '0x0701' : {displayName: 'Air Temperature (F)', bearing: eBearingMode.none, sibling: null},
    '0x0702' : {displayName: 'Water Temperature (C)', bearing: eBearingMode.none, sibling: null},
    '0x0703' : {displayName: 'Water Temperature (F)', bearing: eBearingMode.none, sibling: null},
    '0x0710' : {displayName: 'Heel Angle', bearing: eBearingMode.none, sibling: null},
    '0x0711' : {displayName: 'Rudder Angle', bearing: eBearingMode.none, sibling: null},
    '0x0712' : {displayName: 'Rudder Angle (Port)', bearing: eBearingMode.none, sibling: null},
    '0x0720' : {displayName: 'Pressure', bearing: eBearingMode.none, sibling: null},
    '0x0721' : {displayName: 'Mast Rotation', bearing: eBearingMode.none, sibling: null},
    '0x0722' : {displayName: 'Trim Angle', bearing: eBearingMode.none, sibling: null},

    //Analog Data
    '0x0800' : {displayName: 'Raw Analogue Start', bearing: eBearingMode.none, sibling: null},
    '0x0801' : {displayName: 'Analogue Input 1 (Raw)', bearing: eBearingMode.none, sibling: null},
    '0x0802' : {displayName: 'Analogue Input 2 (Raw)', bearing: eBearingMode.none, sibling: null},
    '0x0803' : {displayName: 'Analogue Input 3 (Raw)', bearing: eBearingMode.none, sibling: null},
    '0x0804' : {displayName: 'Analogue Input 4 (Raw)', bearing: eBearingMode.none, sibling: null}, 
    '0x0811' : {displayName: 'Analogue Reference 1 (Raw)', bearing: eBearingMode.none, sibling: null},
    '0x0812' : {displayName: 'Analogue Reference 2 (Raw)', bearing: eBearingMode.none, sibling: null},
    '0x0813' : {displayName: 'Analogue Reference 3 (Raw)', bearing: eBearingMode.none, sibling: null},
    '0x0814' : {displayName: 'Analogue Reference 4 (Raw)', bearing: eBearingMode.none, sibling: null},
 
    // Calculated Position Data
    '0x1100' : {displayName: 'Calculated Latitude', bearing: eBearingMode.none, sibling: null},
    '0x1101' : {displayName: 'Calculated Longitude', bearing: eBearingMode.none, sibling: null},
    '0x1120' : {displayName: 'Anchor Watch Latitude', bearing: eBearingMode.none, sibling: null},
    '0x1121' : {displayName: 'Anchor Watch Longitude', bearing: eBearingMode.none, sibling: null},
    '0x1122' : {displayName: 'Anchor Watch Distance', bearing: eBearingMode.none, sibling: null},
    '0x1120' : {displayName: 'Anchor Watch Bearing', bearing: eBearingMode.none, sibling: null},
 
    // Calculated Speed data
    '0x1200' : {displayName: 'Displayed Boat Speed (kts)', bearing: eBearingMode.none, sibling: null},
    '0x1201' : {displayName: 'Displayed Boat Speed (m/s)', bearing: eBearingMode.none, sibling: null},
    '0x1202' : {displayName: 'Computed Boat Speed (kts)', bearing: eBearingMode.none, sibling: null},
    '0x1203' : {displayName: 'Computed Boat Speed (m/s)', bearing: eBearingMode.none, sibling: null},
    '0x1210' : {displayName: 'Water Log (m)', bearing: eBearingMode.none, sibling: null}, 
    '0x1211' : {displayName: 'Water Log Total (m)', bearing: eBearingMode.none, sibling: null},
    '0x1212' : {displayName: 'Water Log (nm)', bearing: eBearingMode.none, sibling: null},
    '0x1213' : {displayName: 'Water Log Total (nm)', bearing: eBearingMode.none, sibling: null},
    '0x1220' : {displayName: 'Ground Log (m)', bearing: eBearingMode.none, sibling: null},
    '0x1221' : {displayName: 'Ground Log Total (m)', bearing: eBearingMode.none, sibling: null},
    '0x1222' : {displayName: 'Ground Log (nm)', bearing: eBearingMode.none, sibling: null},
    '0x1223' : {displayName: 'Ground Log Total (nm)', bearing: eBearingMode.none, sibling: null},
    
    // Current Data
    '0x1230' : {displayName: 'Direction of Current (True)', bearing: eBearingMode.true, sibling: '0x1231'},
    '0x1231' : {displayName: 'Direction of Current (Mag)', bearing: eBearingMode.mag, sibling: '0x1230'},
    '0x1232' : {displayName: 'Speed of Current (kts)', bearing: eBearingMode.none, sibling: null},
    '0x1233' : {displayName: 'Speed of Current (m/s)', bearing: eBearingMode.none, sibling: null},
 
    // Calculated Wind Data
    '0x1300' : {displayName: 'AWS (kts)', bearing: eBearingMode.none, sibling: null},
    '0x1301' : {displayName: 'AWS (m/s)', bearing: eBearingMode.none, sibling: null},
    '0x1302' : {displayName: 'AWA', bearing: eBearingMode.true, sibling: '0x1303'},
    '0x1303' : {displayName: 'MAWA', bearing: eBearingMode.mag, sibling: '0x1302'},
    '0x1315' : {displayName: 'VMG Wind (kts)', bearing: eBearingMode.none, sibling: null},
    '0x1320' : {displayName: 'TWS (kts)', bearing: eBearingMode.none, sibling: null},
    '0x1321' : {displayName: 'TWS (m/s)', bearing: eBearingMode.none, sibling: null},
    '0x1322' : {displayName: 'TWA', bearing: eBearingMode.none, sibling: null},
    '0x1323' : {displayName: 'TWA Course', bearing: eBearingMode.none, sibling: null},
    '0x1324' : {displayName: 'TWD (Mag)', bearing: eBearingMode.mag, sibling: '0x1325'},
    '0x1325' : {displayName: 'TWD (True)', bearing: eBearingMode.true, sibling: '0x1324'},
    '0x1330' : {displayName: 'TWS Ground (kts)', bearing: eBearingMode.none, sibling: null},
    '0x1331' : {displayName: 'TWA Ground', bearing: eBearingMode.none, sibling: null},
    '0x1332' : {displayName: 'TWA Course Ground', bearing: eBearingMode.none, sibling: null},
    '0x1333' : {displayName: 'TWD Ground (Mag)', bearing: eBearingMode.mag, sibling: '0x1334'},
    '0x1334' : {displayName: 'TWD Ground (True)', bearing: eBearingMode.true, sibling: '0x1333'},
 
    '0x1340' : {displayName: 'OTWA', bearing: eBearingMode.none, sibling: null},
    '0x1341' : {displayName: 'OTWS', bearing: eBearingMode.none, sibling: null},
    '0x1342' : {displayName: 'TWS Correction', bearing: eBearingMode.none, sibling: null},
    '0x1343' : {displayName: 'TWA Correction', bearing: eBearingMode.none, sibling: null},
    '0x1344' : {displayName: 'AWS Correction', bearing: eBearingMode.none, sibling: null},
    '0x1345' : {displayName: 'AWA Correction', bearing: eBearingMode.none, sibling: null},
    '0x1346' : {displayName: 'Point of Sail', bearing: eBearingMode.none, sibling: null},
    '0x1347' : {displayName: 'Heading TWA', bearing: eBearingMode.none, sibling: null}, 
    '0x1348' : {displayName: 'Leeway', bearing: eBearingMode.none, sibling: null},
    '0x1349' : {displayName: 'Tack', bearing: eBearingMode.none, sibling: null},
    
    '0x1350' : {displayName: 'CAWS (kts)', bearing: eBearingMode.none, sibling: null},
    '0x1351' : {displayName: 'CAWS (m/s)', bearing: eBearingMode.none, sibling: null},
    '0x1352' : {displayName: 'CAWA', bearing: eBearingMode.none, sibling: null},
    '0x1353' : {displayName: 'Heel Correction (Speed)', bearing: eBearingMode.none, sibling: null},
    '0x1354' : {displayName: 'Heel Correction (Angle)', bearing: eBearingMode.none, sibling: null},
    
    // Calculated Depth Data
    '0x1401' : {displayName: 'Depth (m)', bearing: eBearingMode.none, sibling: null},
    '0x1402' : {displayName: 'Depth (ft)', bearing: eBearingMode.none, sibling: null},
    '0x1403' : {displayName: 'Depth (Fathoms)', bearing: eBearingMode.none, sibling: null},
    
    '0x14ff' : {displayName: 'System Alarm', bearing: eBearingMode.none, sibling: null},
 
    // Calculated Heading Data
    '0x1500' : {displayName: 'Heading (True)', bearing: eBearingMode.true, sibling: '0x1501'},
    '0x1501' : {displayName: 'Heading (Mag)', bearing: eBearingMode.mag, sibling: '0x1500'},
    
    '0x1520' : {displayName: 'Course (True)', bearing: eBearingMode.true, sibling: '0x1521'},
    '0x1521' : {displayName: 'Course (Mag)', bearing: eBearingMode.mag, sibling: '0x1520'},

    // Calculated Analog Data
    '0x1800' : {displayName: 'Calculated Analogue Start', bearing: eBearingMode.none, sibling: null},
    '0x1801' : {displayName: 'Analogue Input 1', bearing: eBearingMode.none, sibling: null},
    '0x1802' : {displayName: 'Analogue Input 2', bearing: eBearingMode.none, sibling: null},
    '0x1803' : {displayName: 'Analogue Input 3', bearing: eBearingMode.none, sibling: null},
    '0x1804' : {displayName: 'Analogue Input 4', bearing: eBearingMode.none, sibling: null},
    '0x1811' : {displayName: 'Analogue Reference 1', bearing: eBearingMode.none, sibling: null},
    '0x1812' : {displayName: 'Analogue Reference 2', bearing: eBearingMode.none, sibling: null},
    '0x1813' : {displayName: 'Analogue Reference 3', bearing: eBearingMode.none, sibling: null},
    '0x1814' : {displayName: 'Analogue Reference 4', bearing: eBearingMode.none, sibling: null}
};

/** Get the channels bearing mode. */
function getFieldBearingById(id) {

    if (fieldData[id])
        return fieldData[id].bearing;
    return eBearingMode.none;
}

/** Get the channels display name. */
function getFieldNameById(id) {

    if (fieldData[id])
        return fieldData[id].displayName;
    return "Unknown";
}

/** Get a channels sibling. */
function getFieldSiblingById(id) {
    
    if (fieldData[id])
        return fieldData[id].sibling;
    return null;
}

//
// Convert an int to a 4 digit hex string.
//
function toHexField(num) {
    
    let result = num.toString(16);

    while(result.length < 4) {
        result = '0' + result;
    }

    return '0x' + result;
}