/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* Licensed under the Oculus SDK License Agreement (the "License");
* you may not use the Oculus SDK except in compliance with the License,
* which is provided at the time of installation or download, or which
* otherwise accompanies this software in either electronic or hard copy form.
*
* You may obtain a copy of the License at
*
* https://developer.oculus.com/licenses/oculussdk/
*
* Unless required by applicable law or agreed to in writing, the Oculus SDK
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using UnityEngine;
using UnityEngine.UI;
using Meta.WitAi;
namespace Oculus.Voice.Demo.BuiltInDemo
{
///
/// Represents a countdown timer.
///
public class TimerController : MonoBehaviour
{
private double _time = 0; // [sec] current time of the countdown timer.
private bool _timerExist = false;
private bool _timerRunning = false;
[Tooltip("The UI text element to show app messages.")]
public Text logText;
[Tooltip("The timer ring sound.")] public AudioClip[] timesUpSounds;
// Update is called once per frame
void Update()
{
if (_timerExist && _timerRunning)
{
_time -= Time.deltaTime;
if (_time < 0)
{
// Raise a ring.
OnElapsedTime();
}
}
}
private void Log(string msg)
{
Debug.Log(msg);
logText.text = msg;
}
///
/// Buzzes and resets the timer.
///
private void OnElapsedTime()
{
_time = 0;
_timerRunning = false;
_timerExist = false;
Log("Your timer is complete.");
AudioClip timesUpSfx = timesUpSounds[UnityEngine.Random.Range(0, timesUpSounds.Length)];
AudioSource.PlayClipAtPoint(timesUpSfx, Vector3.zero);
}
///
/// Deletes the timer. It corresponds to the wit intent "wit$delete_timer"
///
public void DeleteTimer()
{
if (!_timerExist)
{
Log("Error: There is no timer to delete.");
return;
}
_timerExist = false;
_time = 0;
_timerRunning = false;
Log("Timer deleted.");
}
///
/// Creates a timer. It corresponds to the wit intent "wit$create_timer"
///
/// countdown in minutes.
public void CreateTimer(string[] entityValues)
{
if (_timerExist)
{
VLog.W("A timer already exist.");
return;
}
if (ParseTime(entityValues, out _time))
{
_timerExist = true;
_timerRunning = true;
Log($"Countdown Timer is set for {entityValues[0]} {entityValues[1]}(s).");
}
}
///
/// Displays current timer value. It corresponds to "wit$get_timer".
///
public void GetTimerIntent()
{
// Show the remaining time of the countdown timer.
var msg = GetFormattedTimeFromSeconds();
//Log(msg);
}
///
/// Pauses the timer. It corresponds to the wit intent "wit$pause_timer"
///
public void PauseTimer()
{
_timerRunning = false;
Log("Timer paused.");
}
///
/// It corresponds to the wit intent "wit$resume_timer"
///
public void ResumeTimer()
{
_timerRunning = true;
Log("Timer resumed.");
}
///
/// Subtracts time from the timer. It corresponds to the wit intent "wit$subtract_time_timer".
///
///
public void SubtractTimeTimer(string[] entityValues)
{
if (!_timerExist)
{
Log("Error: No Timer is created.");
return;
}
if (ParseTime(entityValues, out var time))
{
var msg = $"{entityValues[0]} {entityValues[1]}(s) were subtracted from the timer.";
_time -= time;
if (_time < 0)
{
_time = 0;
Log(msg);
return;
}
Log(msg);
}
else
{
Log("Error in Subtract_time_timer(): Could not parse the wit reply.");
}
}
///
/// Adds time to the timer. It corresponds to the wit intent "wit$add_time_timer".
///
///
public void AddTimeToTimer(string[] entityValues)
{
if (!_timerExist)
{
Log("Error: No Timer is created.");
return;
}
if (ParseTime(entityValues, out var time))
{
_time += time;
var msg = $"{entityValues[0]} {entityValues[1]}(s) were added to the timer.";
Log(msg);
}
else
{
Log("Error in AddTimeToTimer(): Could not parse with reply.");
}
}
///
/// Returns the remaining time (in sec) of the countdown timer.
///
///
public double GetRemainingTime()
{
return _time;
}
///
/// Returns time in the format of min:sec.
///
///
public string GetFormattedTimeFromSeconds()
{
if (_time >= TimeSpan.MaxValue.TotalSeconds)
{
_time = TimeSpan.MaxValue.TotalSeconds - 1;
Log("Error: Hit max time");
}
TimeSpan span = TimeSpan.FromSeconds(_time);
return $"{Math.Floor(span.TotalHours)}:{span.Minutes:00}:{span.Seconds:00}.{Math.Floor(span.Milliseconds/100f)}";
}
///
/// Parses entity values to get a resulting time value in seconds
///
/// The entity value results from a Response Handler
/// The parsed time
/// The parsed time in seconds or the current value of _time
///
private bool ParseTime(string[] entityValues, out double time)
{
time = _time;
if (entityValues.Length > 0 && double.TryParse(entityValues[0], out time))
{
if (entityValues.Length < 2)
{
throw new ArgumentException("Entities being parsed must include time value and unit.");
}
// If entity was not included in the result it will be empty, but the array will still be size 2
if (!string.IsNullOrEmpty(entityValues[1]))
{
switch (entityValues[1])
{
case "minute":
time *= 60;
break;
case "hour":
time *= 60 * 60;
break;
}
}
return true;
}
return false;
}
}
}