#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <math.h>

#include "aos/actions/actions.h"
#include "aos/init.h"
#include "aos/input/action_joystick_input.h"
#include "aos/input/driver_station_data.h"
#include "aos/logging/logging.h"
#include "aos/time/time.h"
#include "aos/util/log_interval.h"

#include "frc971/autonomous/auto.q.h"
#include "frc971/control_loops/drivetrain/drivetrain.q.h"
#include "frc971/queues/gyro.q.h"
#include "y2014/actors/shoot_actor.h"
#include "y2014/constants.h"
#include "y2014/control_loops/claw/claw.q.h"
#include "y2014/control_loops/drivetrain/drivetrain_base.h"
#include "y2014/control_loops/shooter/shooter.q.h"

using ::frc971::control_loops::drivetrain_queue;

using ::aos::input::driver_station::ButtonLocation;
using ::aos::input::driver_station::JoystickAxis;
using ::aos::input::driver_station::ControlBit;

#define OLD_DS 0

namespace y2014 {
namespace input {
namespace joysticks {

const ButtonLocation kDriveControlLoopEnable1(1, 7),
                     kDriveControlLoopEnable2(1, 11);
const JoystickAxis kSteeringWheel(1, 1), kDriveThrottle(2, 2);
const ButtonLocation kShiftHigh(2, 3), kShiftLow(2, 1);
const ButtonLocation kQuickTurn(1, 5);

const ButtonLocation kCatch(3, 10);

#if OLD_DS
const ButtonLocation kFire(3, 11);
const ButtonLocation kUnload(1, 4);
const ButtonLocation kReload(1, 2);

const ButtonLocation kRollersOut(3, 12);
const ButtonLocation kRollersIn(3, 7);

const ButtonLocation kTuck(3, 9);
const ButtonLocation kIntakePosition(3, 8);
const ButtonLocation kIntakeOpenPosition(3, 10);
const ButtonLocation kVerticalTuck(3, 1);
const JoystickAxis kFlipRobot(3, 3);

const ButtonLocation kLongShot(3, 5);
const ButtonLocation kCloseShot(3, 2);
const ButtonLocation kFenderShot(3, 3);
const ButtonLocation kTrussShot(2, 11);
const ButtonLocation kHumanPlayerShot(3, 2);
#else
const ButtonLocation kFire(3, 9);
const ButtonLocation kUnload(1, 4);
const ButtonLocation kReload(1, 2);

const ButtonLocation kRollersOut(3, 8);
const ButtonLocation kRollersIn(3, 3);

const ButtonLocation kTuck(3, 4);
const ButtonLocation kIntakePosition(3, 5);
const ButtonLocation kIntakeOpenPosition(3, 11);
const ButtonLocation kVerticalTuck(2, 6);
const JoystickAxis kFlipRobot(3, 3);

const ButtonLocation kLongShot(3, 7);
const ButtonLocation kCloseShot(3, 6);
const ButtonLocation kFenderShot(3, 2);
const ButtonLocation kTrussShot(2, 11);
const ButtonLocation kHumanPlayerShot(3, 1);
#endif

const ButtonLocation kUserLeft(2, 7);
const ButtonLocation kUserRight(2, 10);

const JoystickAxis kAdjustClawGoal(3, 2);
const JoystickAxis kAdjustClawSeparation(3, 1);

struct ClawGoal {
  double angle;
  double separation;
};

struct ShotGoal {
  ClawGoal claw;
  double shot_power;
  double velocity_compensation;
  double intake_power;
};

const double kIntakePower = 4.0;
// In case we have to quickly adjust it.
const double kGrabSeparation = 0;
const double kShootSeparation = 0.11 + kGrabSeparation;

const ClawGoal kTuckGoal = {-2.273474, -0.749484};
const ClawGoal kVerticalTuckGoal = {0, kGrabSeparation};
const ClawGoal kIntakeGoal = {-2.24, kGrabSeparation};
const ClawGoal kIntakeOpenGoal = {-2.0, 1.1};

// TODO(austin): Tune these by hand...
const ClawGoal kFlippedTuckGoal = {2.733474, -0.75};
const ClawGoal kFlippedIntakeGoal = {2.0, kGrabSeparation};
const ClawGoal kFlippedIntakeOpenGoal = {0.95, 1.0};

// 34" between near edge of colored line and rear edge of bumper.
// Only works running?
const ShotGoal kLongShotGoal = {
    {-1.08, kShootSeparation}, 145, 0.04, kIntakePower};
// old 34" {-1.06, kShootSeparation}, 140, 0.04, kIntakePower};
const ShotGoal kFlippedLongShotGoal = {
    {0.96, kShootSeparation}, 145, 0.09, kIntakePower};
// old 34" {0.96, kShootSeparation}, 140, 0.09, kIntakePower};

// 78" between near edge of colored line and rear edge of bumper.
const ShotGoal kCloseShotGoal = {
    {-0.95, kShootSeparation}, 105, 0.2, kIntakePower};
// 3/4" plunger {-0.90, kShootSeparation}, 105, 0.2, kIntakePower};
const ShotGoal kFlippedMediumShotGoal = {
    {0.865, kShootSeparation}, 120, 0.2, kIntakePower};
// 3/4" plunger {0.80, kShootSeparation}, 105, 0.2, kIntakePower};

// Shot from the fender.
const ShotGoal kFenderShotGoal = {
    {-0.68, kShootSeparation}, 115.0, 0.0, kIntakePower};
const ShotGoal kFlippedShortShotGoal = {
    {0.63, kShootSeparation}, 115.0, 0.0, kIntakePower};

const ShotGoal kHumanShotGoal = {
    {-0.90, kShootSeparation}, 140, 0.04, kIntakePower};
const ShotGoal kFlippedHumanShotGoal = {
    {0.90, kShootSeparation}, 140, 0, kIntakePower};
const ShotGoal kTrussShotGoal = {
    {-0.68, kShootSeparation}, 88.0, 0.4, kIntakePower};
const ShotGoal kFlippedTrussShotGoal = {
    {0.68, kShootSeparation}, 92.0, 0.4, kIntakePower};

const ShotGoal kFlippedDemoShotGoal = {
    {1.0, kShootSeparation}, 65.0, 0.0, kIntakePower};
const ShotGoal kDemoShotGoal = {
    {-1.0, kShootSeparation}, 50.0, 0.0, kIntakePower};

const ClawGoal k254PassGoal = {-1.95, kGrabSeparation};
const ClawGoal kFlipped254PassGoal = {1.96, kGrabSeparation};

class Reader : public ::aos::input::ActionJoystickInput {
 public:
  Reader(::aos::EventLoop *event_loop)
      : ::aos::input::ActionJoystickInput(
            event_loop, control_loops::GetDrivetrainConfig(),
            ::aos::input::DrivetrainInputReader::InputType::kSteeringWheel, {}),
        shot_power_(80.0),
        goal_angle_(0.0),
        separation_angle_(kGrabSeparation),
        velocity_compensation_(0.0),
        intake_power_(0.0),
        shoot_action_factory_(actors::ShootActor::MakeFactory(event_loop)) {}

  void SetGoal(ClawGoal goal) {
    goal_angle_ = goal.angle;
    separation_angle_ = goal.separation;
    moving_for_shot_ = false;
    velocity_compensation_ = 0.0;
    intake_power_ = 0.0;
  }

  void SetGoal(ShotGoal goal) {
    goal_angle_ = goal.claw.angle;
    shot_separation_angle_ = goal.claw.separation;
    separation_angle_ = kGrabSeparation;
    moving_for_shot_ = true;
    shot_power_ = goal.shot_power;
    velocity_compensation_ = goal.velocity_compensation;
    intake_power_ = goal.intake_power;
  }

  void HandleTeleop(const ::aos::input::driver_station::Data &data) override {
    if (data.IsPressed(kRollersIn) || data.IsPressed(kRollersOut)) {
      intake_power_ = 0.0;
      separation_angle_ = kGrabSeparation;
      moving_for_shot_ = false;
    }

    static const double kAdjustClawGoalDeadband = 0.08;
    double claw_goal_adjust = data.GetAxis(kAdjustClawGoal);
    if (OLD_DS || ::std::abs(claw_goal_adjust) < kAdjustClawGoalDeadband) {
      claw_goal_adjust = 0;
    } else {
      claw_goal_adjust = (claw_goal_adjust -
                          ((claw_goal_adjust < 0) ? -kAdjustClawGoalDeadband
                                                  : kAdjustClawGoalDeadband)) *
                         0.035;
    }
    double claw_separation_adjust = data.GetAxis(kAdjustClawSeparation);
    if (OLD_DS ||
        ::std::abs(claw_separation_adjust) < kAdjustClawGoalDeadband) {
      claw_separation_adjust = 0;
    } else {
      claw_separation_adjust =
          (claw_separation_adjust -
           ((claw_separation_adjust < 0) ? -kAdjustClawGoalDeadband
                                         : kAdjustClawGoalDeadband)) *
          -0.035;
    }

#if OLD_DS
    if (data.IsPressed(kFenderShot)) {
#else
    if (data.GetAxis(kFlipRobot) > 0.9) {
#endif
      claw_goal_adjust += claw_separation_adjust;
      claw_goal_adjust *= -1;

      if (data.IsPressed(kIntakeOpenPosition)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kFlippedIntakeOpenGoal);
      } else if (data.IsPressed(kIntakePosition)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kFlippedIntakeGoal);
      } else if (data.IsPressed(kVerticalTuck)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kVerticalTuckGoal);
      } else if (data.IsPressed(kTuck)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kFlippedTuckGoal);
      } else if (data.PosEdge(kLongShot)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kFlippedLongShotGoal);
      } else if (data.PosEdge(kCloseShot)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kFlippedMediumShotGoal);
      } else if (data.PosEdge(kFenderShot)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kFlippedShortShotGoal);
      } else if (data.PosEdge(kHumanPlayerShot)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kFlippedHumanShotGoal);
      } else if (data.PosEdge(kUserLeft)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kFlipped254PassGoal);
      } else if (data.PosEdge(kUserRight)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kFlippedDemoShotGoal);
      } else if (data.PosEdge(kTrussShot)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kFlippedTrussShotGoal);
      }
    } else {
      if (data.IsPressed(kIntakeOpenPosition)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kIntakeOpenGoal);
      } else if (data.IsPressed(kIntakePosition)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kIntakeGoal);
      } else if (data.IsPressed(kVerticalTuck)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kVerticalTuckGoal);
      } else if (data.IsPressed(kTuck)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kTuckGoal);
      } else if (data.PosEdge(kLongShot)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kLongShotGoal);
      } else if (data.PosEdge(kCloseShot)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kCloseShotGoal);
      } else if (data.PosEdge(kFenderShot)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kFenderShotGoal);
      } else if (data.PosEdge(kHumanPlayerShot)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kHumanShotGoal);
      } else if (data.PosEdge(kUserLeft)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(k254PassGoal);
      } else if (data.PosEdge(kUserRight)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kDemoShotGoal);
      } else if (data.PosEdge(kTrussShot)) {
        CancelAllActions();
        LOG(DEBUG, "Canceling\n");
        SetGoal(kTrussShotGoal);
      }
    }

    if (data.PosEdge(kFire)) {
      EnqueueAction(shoot_action_factory_.Make(0.0));
    } else if (data.NegEdge(kFire)) {
      CancelCurrentAction();
    }

    if (data.IsPressed(kUnload) || data.IsPressed(kReload)) {
      CancelAllActions();
        LOG(DEBUG, "Canceling\n");
      intake_power_ = 0.0;
      velocity_compensation_ = 0.0;
    }

    // Send out the claw and shooter goals if no actions are running.
    if (!ActionRunning()) {
      goal_angle_ += claw_goal_adjust;
      separation_angle_ += claw_separation_adjust;

      // If the action just ended, turn the intake off and stop velocity
      // compensating.
      if (was_running_action()) {
        intake_power_ = 0.0;
        velocity_compensation_ = 0.0;
      }

      ::frc971::control_loops::drivetrain_queue.status.FetchLatest();
      double goal_angle = goal_angle_;
      if (::frc971::control_loops::drivetrain_queue.status.get()) {
        goal_angle += SpeedToAngleOffset(
            ::frc971::control_loops::drivetrain_queue.status->robot_speed);
      } else {
        LOG_INTERVAL(no_drivetrain_status_);
      }

      if (moving_for_shot_) {
        auto &claw_status = control_loops::claw_queue.status;
        claw_status.FetchLatest();
        if (claw_status.get()) {
          if (::std::abs(claw_status->bottom - goal_angle) < 0.2) {
            moving_for_shot_ = false;
            separation_angle_ = shot_separation_angle_;
          }
        }
      }

      double separation_angle = separation_angle_;

      if (data.IsPressed(kCatch)) {
        const double kCatchSeparation = 1.0;
        goal_angle -= kCatchSeparation / 2.0;
        separation_angle = kCatchSeparation;
      }

      bool intaking =
          data.IsPressed(kRollersIn) || data.IsPressed(kIntakePosition) ||
          data.IsPressed(kIntakeOpenPosition) || data.IsPressed(kCatch);
      if (!control_loops::claw_queue.goal.MakeWithBuilder()
               .bottom_angle(goal_angle)
               .separation_angle(separation_angle)
               .intake(intaking ? 12.0
                                : (data.IsPressed(kRollersOut) ? -12.0
                                                               : intake_power_))
               .centering(intaking ? 12.0 : 0.0)
               .Send()) {
        LOG(WARNING, "sending claw goal failed\n");
      }

      if (!control_loops::shooter_queue.goal.MakeWithBuilder()
               .shot_power(shot_power_)
               .shot_requested(data.IsPressed(kFire))
               .unload_requested(data.IsPressed(kUnload))
               .load_requested(data.IsPressed(kReload))
               .Send()) {
        LOG(WARNING, "sending shooter goal failed\n");
      }
    }
  }

  double SpeedToAngleOffset(double speed) {
    const ::y2014::constants::Values &values = ::y2014::constants::GetValues();
    // scale speed to a [0.0-1.0] on something close to the max
    // TODO(austin): Change the scale factor for different shots.
    return (speed / values.drivetrain_max_speed) * velocity_compensation_;
  }

 private:
  double shot_power_;
  double goal_angle_;
  double separation_angle_, shot_separation_angle_;
  double velocity_compensation_;
  double intake_power_;
  bool moving_for_shot_ = false;

  actors::ShootActor::Factory shoot_action_factory_;

  ::aos::util::SimpleLogInterval no_drivetrain_status_ =
      ::aos::util::SimpleLogInterval(::std::chrono::milliseconds(200), WARNING,
                                     "no drivetrain status");
};

}  // namespace joysticks
}  // namespace input
}  // namespace y2014

int main() {
  ::aos::Init(-1);
  ::aos::ShmEventLoop event_loop;
  ::y2014::input::joysticks::Reader reader(&event_loop);
  reader.Run();
  ::aos::Cleanup();
}
