// APGA example for the GFC605 autopilot
//
// default APGA parameters to override in MY_APGA class:
// this.altPreselMode = altPreselMode.manual;
// this.unarmedAltituteLockValue = 35000;
// this.altModeUpDownIncrementValue = 10;
//
// Please replace MyCompany-MyAircraft in the GFC605.html file by your own Unique aircraft ident.
//
// You may need to adjust the css file if the screen doesn't fit.


// Lateral modes
var lateralMode = {
    none: 0,
    roll: 1,
    hdg: 2,
    gps: 3,
    vor: 4,
    loc: 5,
    bc: 6,
    aprgps: 7,
    aprvor: 8,
    aprloc: 9,
    lvl: 10,
    cga: 11,
    clvl: 12
};

// Vertical modes
var verticalMode = {
    none: 0,
    pitch: 1,
    vs: 2,
    alt: 3,
    gs: 4,
    gp: 5,
    flc: 6,
    vnav: 7,
    cga: 8,
    clvl: 9
};

// Target altitude phases
var selectedAltitudePhase = {
    none: 0,    // No ALTS
    engaged: 1, // Altitude diff is greater than alert threshold.
    alert: 2,   // Altitude diff is between alert and near thresholds.
    near: 3,    // Altitude diff is less than near threshold.
    ready: 4,   // Vertical mode is ALT and Altitude diff greater than the reached threshold.
    reached: 5  // Vertical mode is ALT and Altitude diff is less than reached threshold. Phase returns to none after a time out.
};

// Workaround to a sim issue when posting H events after restarting the aircraft
function postHEvent(event) {
    let useWatcher = SimVar.g_bUseWatcher;
    if(useWatcher)
        SimVar.g_bUseWatcher = false;
    SimVar.SetSimVarValue("H:" + event, "number", 0);
    if(useWatcher)
        SimVar.g_bUseWatcher = true;
}

class GFC605 extends BaseInstrument {
    constructor() {
        super();
        this.activeLateralMode = lateralMode.none;
        this.activeVerticalMode = verticalMode.none;
        this.armedLateralMode = lateralMode.none;
        this.armedAltitudeMode = verticalMode.none;
        this.armedApproachMode = verticalMode.none;
        this.selectedAltitude = 0;
        this.capturedAltitude = 0;
        this.capturedAltitudeValid = false;
        this.selectedVS = 0;
        this.selectedAirspeed = 0;
        this.selectedAltitudePhase = selectedAltitudePhase.none;
        this.needTrimIndicator = false;
        this.needTrimUpIndicator = false;
        this.needTrimDownIndicator = false;
        this.needTrimValue = 0;
    }
    get templateID() { return "GFC605"; }
    get instrumentAlias() { return "APGA"; }
    connectedCallback() {
        super.connectedCallback();
        RegisterViewListener("JS_LISTENER_KEYEVENT");
        this.displayActiveLateralMode = this.getChildById("activeLateralMode");
        this.displayArmedLateralMode = this.getChildById("armedLateralMode");
        this.displayActiveVerticalMode = this.getChildById("activeVerticalMode");
        this.displayArmedVerticalModeAltBlock = this.getChildById("armedVerticalModeAltBlock");
        this.displayArmedVerticalModeAltMode = this.getChildById("armedVerticalModeAltMode");
        this.displayArmedVerticalModeAltAlt = this.getChildById("armedVerticalModeAltAlt");
        this.displayArmedVerticalModeAltAltValue = this.getChildById("armedVerticalModeAltAltValue");
        this.displayArmedVerticalModeApr = this.getChildById("armedVerticalModeApr");
        this.displayModeReferenceBlock = this.getChildById("modeReferenceBlock");
        this.displayModeReference = this.getChildById("modeReference");
        this.displayModeReferenceValue = this.getChildById("modeReferenceValue");
        this.displayModeReferenceUpArrow = this.getChildById("modeReferenceUpArrow");
        this.displayModeReferenceDownArrow = this.getChildById("modeReferenceDownArrow");
        this.displayModeReferenceUnit = this.getChildById("modeReferenceUnit");
        this.displayMessage = this.getChildById("message");
    }
    disconnectedCallback() {
        super.disconnectedCallback();
    }
    Update() {
        super.Update();
        if (!this.isElectricityAvailable())
            return;

        // Update the state
        this.updateStateFormAPGA();

        // Display active and armed modes
        diffAndSetText(this.displayActiveLateralMode, this.getActiveLateralModeForDisplay());
        diffAndSetText(this.displayArmedLateralMode, this.getArmedLateralModeForDisplay());
        diffAndSetText(this.displayActiveVerticalMode, this.getActiveVerticalModeForDisplay());
        diffAndSetText(this.displayArmedVerticalModeAltMode, this.getArmedAltitudeModeForDisplay());
        diffAndSetText(this.displayArmedVerticalModeApr, this.getArmedApproachModeForDisplay());

        // Update reference
        if(this.selectedAltitudePhase == selectedAltitudePhase.near) {
            diffAndSetText(this.displayModeReferenceValue, fastToFixed(this.selectedAltitude, 0));
            diffAndSetText(this.displayModeReferenceUnit, "FT");
            diffAndSetAttribute(this.displayModeReferenceUpArrow, "style", "display: none;");
            diffAndSetAttribute(this.displayModeReferenceDownArrow, "style", "display: none;");
        }
        else if(this.activeVerticalMode == verticalMode.alt) {
            diffAndSetText(this.displayModeReferenceValue, this.capturedAltitudeValid ? fastToFixed(this.capturedAltitude, 0) : " ");
            diffAndSetText(this.displayModeReferenceUnit, "FT");
            diffAndSetAttribute(this.displayModeReferenceUpArrow, "style", "display: none;");
            diffAndSetAttribute(this.displayModeReferenceDownArrow, "style", "display: none;");
        }
        else if(this.activeVerticalMode == verticalMode.vs) {
            diffAndSetText(this.displayModeReferenceValue, fastToFixed(Math.abs(this.selectedVS), 0));
            diffAndSetText(this.displayModeReferenceUnit, "FPM");
            diffAndSetAttribute(this.displayModeReferenceUpArrow, "style", this.activeVerticalMode == verticalMode.vs && this.selectedVS > 0 ? "display: inline;" : "display: none;");
            diffAndSetAttribute(this.displayModeReferenceDownArrow, "style", this.activeVerticalMode == verticalMode.vs && this.selectedVS < 0 ? "display: inline;" : "display: none;");
        }
        else if(this.activeVerticalMode == verticalMode.flc) {
            diffAndSetText(this.displayModeReferenceValue, fastToFixed(this.selectedAirspeed, 0));
            diffAndSetText(this.displayModeReferenceUnit, "KTS");
            diffAndSetAttribute(this.displayModeReferenceUpArrow, "style", "display: none;");
            diffAndSetAttribute(this.displayModeReferenceDownArrow, "style", "display: none;");
        }
        else {
            diffAndSetText(this.displayModeReferenceValue, "");
            diffAndSetText(this.displayModeReferenceUnit, "");
            diffAndSetAttribute(this.displayModeReferenceUpArrow, "style", "display: none;");
            diffAndSetAttribute(this.displayModeReferenceDownArrow, "style", "display: none;");
        }
        diffAndSetText(this.displayArmedVerticalModeAltAltValue, this.selectedAltitudePhase == selectedAltitudePhase.engaged || this.selectedAltitudePhase == selectedAltitudePhase.alert ? fastToFixed(this.selectedAltitude, 0) : "");
        diffAndSetAttribute(this.displayArmedVerticalModeAltAlt, "style", this.selectedAltitudePhase == selectedAltitudePhase.engaged || this.selectedAltitudePhase == selectedAltitudePhase.alert ? "display: block;" : "display: none;");
        diffAndSetAttribute(this.displayMessage, "style", "display: none;");
    }
    onInteractionEvent(_args) {
        if(!this.isElectricityAvailable())
            return;

        switch (_args[0]) {
            case "GFC605_AP":
            case "APGA_AP":
                this.sendOrderToAGPA("AP_AP");
                break;
            case "GFC605_FD":
            case "APGA_FD":
                this.sendOrderToAGPA("AP_FD");
                break;
            case "GFC605_YD":
            case "APGA_YD":
                this.sendOrderToAGPA("AP_YD");
                break;
            case "GFC605_HDG":
            case "APGA_HDG":
                this.sendOrderToAGPA("AP_HDG");
                break;
            case "GFC605_NAV":
            case "APGA_NAV":
                this.sendOrderToAGPA("AP_NAV");
                break;
            case "GFC605_APR":
            case "APGA_APR":
                this.sendOrderToAGPA("AP_APR");
                break;
            case "GFC605_BC":
            case "APGA_REV":
                this.sendOrderToAGPA("AP_REV");
                break;
            case "GFC605_VNV":
                    break;
            case "GFC605_IAS":
            case "APGA_FLC":
                this.sendOrderToAGPA("AP_FLC");
                break;
            case "GFC605_VS":
            case "APGA_VS":
                this.sendOrderToAGPA("AP_VS");
                break;
            case "GFC605_ALT":
            case "APGA_ALT":
                this.sendOrderToAGPA("AP_ALT");
                break;
            case "GFC605_LVL":
            case "APGA_CLVL":
                this.sendOrderToAGPA("AP_CLVL");
                break;
            case "GFC605_UP":
            case "APGA_UP":
                this.sendOrderToAGPA("AP_UP");
                break;
            case "GFC605_DN":
            case "APGA_DOWN":
                this.sendOrderToAGPA("AP_DOWN");
                break;
            case "GFC605_CGA":
            case "APGA_CGA":
                this.sendOrderToAGPA("AP_CGA");
                break;
           }
    }
    updateStateFormAPGA() {
        this.activeLateralMode = SimVar.GetSimVarValue("L:PMS50_APGA_ACTIVE_LATERAL_MODE", "number");
        this.activeVerticalMode = SimVar.GetSimVarValue("L:PMS50_APGA_ACTIVE_VERTICAL_MODE", "number");
        this.armedLateralMode = SimVar.GetSimVarValue("L:PMS50_APGA_ARMED_LATERAL_MODE", "number");
        this.armedAltitudeMode = SimVar.GetSimVarValue("L:PMS50_APGA_ARMED_ALTITUDE_MODE", "number");
        this.armedApproachMode = SimVar.GetSimVarValue("L:PMS50_APGA_ARMED_APPROACH_MODE", "number");
        this.selectedAltitude = SimVar.GetSimVarValue("L:PMS50_APGA_SELECTED_ALTITUDE", "feet");
        this.capturedAltitude = SimVar.GetSimVarValue("L:PMS50_APGA_CAPTURED_ALTITUDE", "feet");
        this.capturedAltitudeValid = SimVar.GetSimVarValue("L:PMS50_APGA_CAPTURED_ALTITUDE_VALID", "bool");
        this.selectedVS = SimVar.GetSimVarValue("L:PMS50_APGA_SELECTED_VS", "feet/minute");
        this.selectedAirspeed = SimVar.GetSimVarValue("L:PMS50_APGA_SELECTED_AIRSPEED", "knots");
        this.selectedAltitudePhase = SimVar.GetSimVarValue("L:PMS50_APGA_SELECTED_ALTITUDE_PHASE", "number");
        this.needTrimIndicator = SimVar.GetSimVarValue("L:PMS50_APGA_NEED_TRIM_INDICATOR", "bool");
        this.needTrimUpIndicator = SimVar.GetSimVarValue("L:PMS50_APGA_NEED_TRIM_UP_INDICATOR", "bool");
        this.needTrimDownIndicator = SimVar.GetSimVarValue("L:PMS50_APGA_NEED_TRIM_DOWN_INDICATOR", "bool");
        this.needTrimValue = SimVar.GetSimVarValue("L:PMS50_APGA_NEED_TRIM_VALUE", "feet per minute");
    }

    sendOrderToAGPA(_order, _variableName, _value, _valueType = "number") {
        if(_variableName != undefined &&_value != undefined) {
            SimVar.SetSimVarValue("L:PMS50_APGA_" + _variableName, _valueType, _value);
            postHEvent("PMS50_APGA_" + _order);
        }
        else
            postHEvent("PMS50_APGA_" + _order);
    }

    getActiveLateralModeForDisplay() {
        if(this.activeLateralMode == lateralMode.roll)
            return "ROL";
        if(this.activeLateralMode == lateralMode.hdg)
            return "HDG";
        if(this.activeLateralMode == lateralMode.gps)
            return "GPS";
        if(this.activeLateralMode == lateralMode.aprgps)
            return "GPS";
        if(this.activeLateralMode == lateralMode.vor)
            return "VOR";
        if(this.activeLateralMode == lateralMode.aprvor)
            return "VAPP";
        if(this.activeLateralMode == lateralMode.loc)
            return "LOC";
        if(this.activeLateralMode == lateralMode.aprloc)
            return "LOC";
        if(this.activeLateralMode == lateralMode.bc)
            return "REV";
        if(this.activeLateralMode == lateralMode.lvl)
            return "LVL";
        if(this.activeLateralMode == lateralMode.cga)
            return "GA";
        if(this.activeLateralMode == lateralMode.clvl)
            return "LVL";
        return "";
    }
    getActiveVerticalModeForDisplay() {
        if(this.activeVerticalMode == verticalMode.pitch)
            return this.selectedAltitudePhase == selectedAltitudePhase.near ? "ALTS" : "PIT";
        if(this.activeVerticalMode == verticalMode.vs)
            return this.selectedAltitudePhase == selectedAltitudePhase.near ? "ALTS" : "VS";
        if(this.activeVerticalMode == verticalMode.alt)
            return "ALT";
        if(this.activeVerticalMode == verticalMode.gs)
            return "GS";
        if(this.activeVerticalMode == verticalMode.gp)
            return "GP";
        if(this.activeVerticalMode == verticalMode.flc)
            return this.selectedAltitudePhase == selectedAltitudePhase.near ? "ALTS" : "IAS";
        if(this.activeVerticalMode == verticalMode.vnav)
            return "VNV";
        if(this.activeVerticalMode == verticalMode.cga)
            return this.selectedAltitudePhase == selectedAltitudePhase.near ? "ALTS" : "GA";
        if(this.activeVerticalMode == verticalMode.clvl)
            return "LVL";
        return "";
    }
    getArmedLateralModeForDisplay() {
        if(this.armedLateralMode == lateralMode.bc)
            return "REV";
        if(this.armedLateralMode == lateralMode.gps || this.armedLateralMode == lateralMode.aprgps)
            return "GPS";
        if(this.armedLateralMode == lateralMode.vor)
            return "VOR";
        if(this.armedLateralMode == lateralMode.aprvor)
            return "VAPP";
        if(this.armedLateralMode == lateralMode.loc || this.armedLateralMode == lateralMode.aprloc)
            return "LOC";
        return "";
    }
    getArmedAltitudeModeForDisplay() {
        if(this.selectedAltitudePhase == selectedAltitudePhase.near || this.selectedAltitudePhase == selectedAltitudePhase.ready)
            return "ALT";
        if(this.selectedAltitudePhase == selectedAltitudePhase.engaged || this.selectedAltitudePhase == selectedAltitudePhase.alert)
            return "ALTS";
        return "";
    }
    getArmedApproachModeForDisplay() {
        if(this.armedApproachMode == verticalMode.gs)
            return "GS";
        if(this.armedApproachMode == verticalMode.gp)
            return "GP";
        return "";
    }
}
registerInstrument("gfc605-element", GFC605);
//# sourceMappingURL=GFC605.js.map