using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using AGXUnity;


/// <summary>
/// This class will spawn cans with a specified frequency at a specified conveyor lane.
/// When a can is spawned, it will get the speed of the conveyor lane.
/// </summary>
public class CanSpawner : ScriptComponent
{
  // Reference to the prefab (can) that will be instantiated
  public GameObject canPrefab;
  
  /// <summary>
  /// Specifies the frequency of the can emitter
  /// </summary>
  [SerializeField, Range(0, 20)]
  public float Frequency = 0;

  /// <summary>
  /// Specifies the conveyor belt lane in which cans will be spawned
  /// </summary>
  [SerializeField, Range(0, 2)] int Lane=0;

  // Width of the lane as read from the CAD model
  private float m_laneWidth = 0.100f;
  private float m_lastSpawned = -1f;

  private ConveyorBeltSystem m_system;

  override protected void OnEnable()
  {
    // Register a callback that will be called before collision detection is executed.
    Simulation.Instance.StepCallbacks.PreStepForward += OnPreCollideForward;

    m_system = GetComponentInParent<ConveyorBeltSystem>();
  }

  override protected bool  Initialize()
  {
    return true;
  }

  /// <summary>
  /// Called before simulation performs collision detection.
  /// Here we will check if it is time to create another can depending on the frequency
  /// </summary>
  private void OnPreCollideForward()
  {
    var t = Time.time;
    var delta = t - m_lastSpawned;
    var interval = 1E10f;
    
    if (Frequency > 0)
      interval = 1 / Frequency;

    // Is it time to spawn?
    if (delta > interval)
    {
      // Save this time for the next check. Wait interval seconds.
      m_lastSpawned = t;

      // What is the speed of the conveyor where we want to spawn a can?
      var speed = m_system.Speed[Lane];

      // Calculate where the can should be spawned (in local coordinates)
      var pos = new Vector3(0, -0.001f, m_laneWidth * 0.5f + Lane * m_laneWidth);
      var rot = Quaternion.Euler(new Vector3(-90, 0, 0));

      // Create a new can
      var can = Instantiate(canPrefab);

      // Make sure the can is created relative to its parent
      can.transform.parent = transform;
      can.transform.localPosition = pos;
      can.transform.rotation = rot;

      // Also, set the linear velocity to be the same as the conveyor belt.
      can.GetComponentInChildren<AGXUnity.RigidBody>().LinearVelocity = gameObject.transform.TransformVector(new Vector3(-speed, 0, 0));
    }
  }
}
