import java.awt.Color
import java.util.concurrent.{Executors, TimeUnit}

import scala.swing.{Graphics2D, MainFrame, Panel, SimpleSwingApplication}
import scala.swing.Swing.pair2Dimension

object Pendulum extends SimpleSwingApplication {
  val length = 100

  lazy val ui = new Panel {
    import scala.math.{cos, Pi, sin}

    background = Color.white
    preferredSize = (2 * length + 50, length / 2 * 3)
    peer.setDoubleBuffered(true)

    var angle: Double = Pi / 2

    override def paintComponent(g: Graphics2D): Unit = {
      super.paintComponent(g)

      val (anchorX, anchorY) = (size.width / 2, size.height / 4)
      val (ballX, ballY) =
        (anchorX + (sin(angle) * length).toInt, anchorY + (cos(angle) * length).toInt)
      g.setColor(Color.lightGray)
      g.drawLine(anchorX - 2 * length, anchorY, anchorX + 2 * length, anchorY)
      g.setColor(Color.black)
      g.drawLine(anchorX, anchorY, ballX, ballY)
      g.fillOval(anchorX - 3, anchorY - 4, 7, 7)
      g.drawOval(ballX - 7, ballY - 7, 14, 14)
      g.setColor(Color.yellow)
      g.fillOval(ballX - 7, ballY - 7, 14, 14)
    }

    val animate: Runnable = new Runnable {
      var angleVelocity = 0.0
      var dt = 0.1

      override def run(): Unit = {
        angleVelocity += -9.81 / length * Math.sin(angle) * dt
        angle += angleVelocity * dt
        repaint()
      }
    }
  }

  override def top = new MainFrame {
    title = "Rosetta Code >>> Task: Animate a pendulum | Language: Scala"
    contents = ui
    centerOnScreen()
    Executors.
      newSingleThreadScheduledExecutor().
      scheduleAtFixedRate(ui.animate, 0, 15, TimeUnit.MILLISECONDS)
  }
}