Files
GetGoing/ProjectClock/AlarmActivationViewController.swift
T
2021-01-27 20:28:31 -05:00

193 lines
4.7 KiB
Swift

//
// AlarmActivationViewController.swift
// ProjectClock
//
// Created by Hykilpikonna on 1/17/21.
//
import UIKit
import AVFoundation
import CoreMotion
var motion = CMMotionManager()
var alarmStarted = false
/**
View controlling alarm activation and dismissal
*/
class AlarmActivationViewController: EndEditingOnReturn
{
var currentAlarm: Alarm
// Puzzle outlets
@IBOutlet weak var puzzleView: UIView!
@IBOutlet weak var puzzleQuestionLabel: UILabel!
@IBOutlet weak var puzzleAnswerInput: UITextField!
var puzzleAnswers: [Int] = []
// RPS Outlets
@IBOutlet weak var rpsView: UIView!
@IBOutlet weak var rpsResult: UILabel!
// Shake Outlets
@IBOutlet weak var shakeView: UIView!
// Other Outlets
@IBOutlet weak var timeLabel: UILabel!
@IBOutlet weak var dateLabel: UILabel!
var solved = false
/**
Constructor to receive alarm data from segue
*/
init?(coder: NSCoder, currentAlarm: Alarm)
{
self.currentAlarm = currentAlarm
super.init(coder: coder)
}
/**
Unused init
*/
required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
/**
Called when the alarm activates
*/
override func viewDidLoad()
{
super.viewDidLoad()
// Set the time and date
dateLabel.text = Date().str("MMM d, Y")
timeLabel.text = currentAlarm.timeText
// Hide all inactive wakemethods
puzzleView.hide()
rpsView.hide()
shakeView.hide()
// Play sound
playSound()
vibrate()
// Run alarm
runAlarm()
// End edit on return
puzzleAnswerInput.delegate = self
}
/**
Play alarm sound
*/
func playSound()
{
AudioServicesPlayAlertSoundWithCompletion(currentAlarm.alarmTone) {
if alarmStarted { self.playSound() }
}
}
func vibrate()
{
AudioServicesPlayAlertSoundWithCompletion(kSystemSoundID_Vibrate) {
if alarmStarted { self.vibrate() }
}
}
/**
Run alarm dismissal logic
*/
func runAlarm()
{
// Check if the device has accelerometer
var wvm = currentAlarm.wakeMethod.name
if wvm == "Shake" && !motion.isDeviceMotionAvailable
{
msg("Error", "Accelerometer is not available on your device, so shaking your phone wouldn't work.")
wvm = "Factor"
}
// Initialize alarm
switch wvm
{
case "Math 1", "Math 2", "Math 3":
let q = MathExpProblem(size: Int(wvm[5...5])!)
puzzleQuestionLabel.text = "Solve: \(q.prob.replacingOccurrences(of: "**", with: "^"))"
puzzleAnswers = [q.ans]
puzzleView.show()
case "Factor":
initFactorProblem()
puzzleView.show()
case "RPS":
rpsView.show()
case "Shake":
shakeView.show()
// Start motion detection
let q = OperationQueue()
motion.deviceMotionUpdateInterval = 0.2
motion.startDeviceMotionUpdates(to: q) { data, error in
if let a = data?.userAcceleration, sqrt(pow(a.x, 2) + pow(a.y, 2) + pow(a.z, 2)) > 4
{
ui { self.endAlarm() }
motion.stopDeviceMotionUpdates()
q.cancelAllOperations()
}
}
default:
print("Invalid alarm type")
}
alarmStarted = true
}
func initFactorProblem()
{
let problem = QuadraticProb()
puzzleAnswers = problem.getAnswer()
puzzleQuestionLabel.text = "Solve: \(problem.getProblem())"
print("Answer: \(puzzleAnswers)")
}
/**
Verfies and ends factoring WVM
*/
@IBAction func checkBinomialSolution(_ sender: Any)
{
if let input = puzzleAnswerInput.text,
let numericalInput = Int(input),
puzzleAnswers.contains(numericalInput)
{
endAlarm()
}
}
/**
Gets RPS choice
*/
@IBAction func rpsChoice(_ sender: UIButton)
{
if RPS.playRPS(you: [.rock, .paper, .scissors][sender.tag], computer: RPS.choices.randomElement()!)
{
endAlarm()
}
else
{
rpsResult.text = "\(["Paper", "Scissors", "Rock"][sender.tag]): You lost, try again"
}
}
/**
Standard way to turn off and close the alarm
*/
func endAlarm()
{
alarmStarted = false
print("Alarm solved")
dismiss(animated: true, completion: nil)
}
}