////////////////// NOTE TO STUDENTS //////////////////////////
// For the purposes of our course, it’s not necessary
// that you understand or even look at the code in this file.
//////////////////////////////////////////////////////////////

package o1.carsim.gui

import java.util.Locale
import java.awt.Color
import CarSim.Directions.Segment

import org.openstreetmap.gui.jmapviewer.*
import org.openstreetmap.gui.jmapviewer.interfaces.*

import o1.gui.swingops

import MapPanel.*
import CarMap.*
import CarEnhancement.StudentDriveResult
import CoordinateConversions.given
import scala.language.implicitConversions

/** The class `CarMarker` represents the markers used in CarSim to represent cars graphically.
  * These markers are linked with a destination marker and can move about, changing color as
  * the car consumes fuel.
  *
  * **NOTE TO STUDENTS: In this course, you don’t need to understand how this class works or can be used.** */
class CarMarker(val map: CarMap, val car: CarEnhancement) extends Marker(/*layer=*/ swingops.Null, /*name=*/ swingops.Null, car.coords, /*radius=*/ 5, MapMarker.STYLE.FIXED, CarMarker.fuelStyle(car)):

  val destinationMarker: Marker = Marker.Destination(car.coords)
  this.destinationMarker.visible = false
  this.refresh()

  def advanceAlongRoute(): StudentDriveResult =
    val driveResult = this.car.advance()
    this.coordinates_=(this.car.coords)
    if this.car.isAtDestination then
      this.destinationMarker.visible = false
    this.refresh()
    driveResult

  def updateDestination(segments: Iterable[Segment]) =
    if segments.nonEmpty then
      val newDestination = segments.last.destination
      this.destinationMarker.coordinates = newDestination
      this.destinationMarker.visible = true

  def refresh() =
    this.setStyle(CarMarker.fuelStyle(car))
    this.map.repaint()

  override def toString =
    "Car at (%.3f,%.3f). Fuel at %.1f%%. Driven: %.1f km".formatLocal(Locale.US, this.coordinates.lat, this.coordinates.lng, this.car.fuelRatio.abs, this.car.kmDriven)

  private def coordinates: Coordinate = this.car.coords

end CarMarker

private object CarMarker:
  import o1.gui.swingops.Null
  def fuelColor(car: CarEnhancement): Color = Color.getHSBColor(car.fuelRatio.toInt * 0.0033f, 1.0f, 1.0f)
  def fuelStyle(car: CarEnhancement): Style = Style(Color.black, fuelColor(car), /*stroke=*/ Null, /*font=*/ Null)
end CarMarker

