001/************************* PROJECT RON *************************/
002/* Copyright (c) 2026 StuyPulse Robotics. All rights reserved. */
003/* Use of this source code is governed by an MIT-style license */
004/* that can be found in the repository LICENSE file.           */
005/***************************************************************/
006package com.stuypulse.robot.subsystems.handoff;
007
008import com.stuypulse.robot.Robot;
009import com.stuypulse.robot.constants.Settings;
010import dev.doglog.DogLog;
011import edu.wpi.first.units.measure.Voltage;
012import edu.wpi.first.wpilibj2.command.SubsystemBase;
013
014public abstract class Handoff extends SubsystemBase {
015    private static final Handoff instance;
016
017    private HandoffState state;
018
019    static {
020        if (Robot.isReal()) {
021            instance = new HandoffImpl();
022        } else {
023            instance = new HandoffSim();
024        }
025    }
026
027    public static Handoff getInstance() {
028        return instance;
029    }
030
031    protected Handoff() {
032        this.state = HandoffState.IDLE;
033    }
034
035    public void setState(HandoffState state) {
036        this.state = state;
037    }
038
039    public HandoffState getState() {
040        return this.state;
041    }
042
043    /** Enum representing the different possible states of the handoff. */
044    public enum HandoffState {
045        /** Handoff is stopped. */
046        IDLE(Settings.Handoff.IDLE_VOLTAGE),
047        /** The handoff runs forward. */
048        FORWARD(Settings.Handoff.FORWARD_VOLTAGE),
049        /** The handoff runs backward. */
050        REVERSE(Settings.Handoff.REVERSE_VOLTAGE);
051
052        /** The target voltage of the handoff motor. */
053        private Voltage targetVoltage;
054
055        /**
056         * Constructs a HandoffState with the given target voltage.
057         * @param targetVoltage the target voltage of the handoff motor in the corresponding state.
058         */
059        private HandoffState(Voltage targetVoltage) {
060            this.targetVoltage = targetVoltage;
061        }
062
063        /**
064         * Gets the target voltage of the handoff motor in the corresponding state.
065         * @return the target voltage of the handoff motor
066         */
067        public Voltage getTargetVoltage() {
068            return targetVoltage;
069        }
070    }
071
072    protected abstract void stopMotors();
073    protected abstract boolean handoffStalling();
074
075    @Override
076    public void periodic() {
077        final HandoffState currentState = getState();
078        DogLog.log("Handoff/State", currentState.name());
079        DogLog.forceNt.log("States/Handoff", currentState.name());
080        DogLog.log("Handoff/Handoff Target Voltage", currentState.getTargetVoltage());
081        DogLog.forceNt.log("Handoff/Stalling", handoffStalling());
082    }
083}