package pl.edu.pw.mini.sg.movingtargets.multi

import pl.edu.pw.mini.jk.sg.game.common.State
import pl.edu.pw.mini.jk.sg.game.immutable.Payoffs
import pl.edu.pw.mini.sg.movingtargets.{ AttackDecision, AttackerDecision, WaitDecision }
import pl.edu.pw.mini.sg.movingtargets.{ AttackStart, MovingTargetsGameConfig }


case class MovingTargetsMultiImmutableGame(
  defenderState: MovingTargetsDefenderStateMulti,
  attackerState: MovingTargetsMultiAttackerState,
  attackStarted: Option[AttackStart],
  gameConfig: MovingTargetsGameConfig
)
    extends State[MovingTargetsMultiAttackerState, MovingTargetsDefenderStateMulti]
{

  def timeStep = defenderState.getTimeStep

  def makeMoves(defenderMove: MovingTargetsDefenderMoveMulti, attackerMove: AttackerDecision) : (Payoffs, MovingTargetsMultiImmutableGame)  = {
    val newDefenderState = defenderState.advance(defenderMove)
    val newAttackerState = attackerState.advance(attackerMove)
    val newAttackStarted = attackerMove match {
      case WaitDecision => attackStarted
      case AttackDecision(target) => Some(AttackStart(timeStep+1, target))
    }

    newDefenderState match {
      case MovingTargetsDefenderStateMulti(_, Vector(), pos, _) => {
        val p = gameConfig.getRewardForAS(newAttackStarted, newDefenderState.currentPositions, newDefenderState.getTimeStep)
        (p._1, copy(defenderState = newDefenderState, attackerState = newAttackerState, attackStarted = p._2))
      }
      case _ => (Payoffs(0, 0, 0, 0), copy(defenderState = newDefenderState, attackerState = newAttackerState, attackStarted = newAttackStarted))
    }
  }

  override def getAttackerVisibleState: MovingTargetsMultiAttackerState = attackerState
  override def getDefenderVisibleState: MovingTargetsDefenderStateMulti =  defenderState

}


object MovingTargetsMultiImmutableGame {
  def initialState(gameConfig: MovingTargetsGameConfig) : MovingTargetsMultiImmutableGame =
    MovingTargetsMultiImmutableGame(
      MovingTargetsDefenderStateMulti(0, Vector(), gameConfig.defenderStartingPositions, gameConfig),
      MovingTargetsMultiAttackerState.initialState(gameConfig),
      None,
      gameConfig)

}
