package me.msoucy.ptures.model

import com.badlogic.gdx.math.MathUtils.clamp
import com.badlogic.gdx.math.MathUtils.random

class Stats(var atk : Int, var def : Int, var spd : Int, var hp : Int)

class Creature {
    val genes = Stats(5,5,5,5)
    val growth = Stats(5,5,5,5)
    val attributes = mutableMapOf<Attribute, Int>()
    var level = 1
    var currentHp = 1
    val skills = mutableListOf<Skill>()
    val statuses = mutableListOf<Status>()

    val atk : Int get() = statFormula(genes.atk, growth.atk)
    val def : Int get() = statFormula(genes.atk, growth.atk)
    val spd : Int get() = statFormula(genes.atk, growth.atk)
    val maxHp : Int get() = statFormula(genes.atk, growth.atk)

    fun apply(dmg : Damage, attacker : Creature) {
        val critical = if (random(32) < attacker.genes.spd) { 1.5 } else { 1.0 }
        val randVal = random(0.85f, 1.0f)
        val effectiveness = 1.0
        val modifier = critical * randVal * effectiveness
        val power = (((0.4 * attacker.level) + 2) * dmg.power * (attacker.atk / def)) / 50 + 2
        val total : Int = (power * modifier).toInt()
        currentHp = clamp(currentHp - total, 0, maxHp)

        if(currentHp == 0) {
            statuses.clear()
            addStatus(KnockedOut)
        }
    }

    fun addStatus(status : Status) {
        if(status !in statuses)
        {
            statuses.add(status)
            status.onAdd(this)
        }
    }

    fun removeStatus(status : Status) {
        statuses.remove(status)
    }

    fun fullHeal() {
        currentHp = maxHp
        statuses.clear()
    }

    fun hits(creature : Creature, damage : Damage) =
            random(100) < damage.accuracy + spd - creature.spd

    inline fun <reified S : Status> hasStatus() = statuses.filter { it is S }.isNotEmpty()

    private fun statFormula(gene : Int, growth : Int) = (2 * gene + growth) * level / 100 + 5
}