package theorycrafter.ui.fiteditor

import eve.data.*
import theorycrafter.TheorycrafterContext


/**
 * Returns a short name of the mutaplasmid.
 */
val Mutaplasmid.shortName: String
    get() = when (type) {
        Mutaplasmid.Type.Decayed -> "Decayed"
        Mutaplasmid.Type.Gravid -> "Gravid"
        Mutaplasmid.Type.Unstable -> "Unstable"
        Mutaplasmid.Type.Radical -> "Radical"
        Mutaplasmid.Type.GlorifiedDecayed -> "Gl. Decayed"
        Mutaplasmid.Type.GlorifiedGravid -> "Gl. Gravid"
        Mutaplasmid.Type.GlorifiedUnstable -> "Gl. Unstable"
        Mutaplasmid.Type.GlorifiedRadical -> "Gl. Radical"
        Mutaplasmid.Type.ExigentNavigation -> "Exigent Navigation"
        Mutaplasmid.Type.ExigentFirepower -> "Exigent Firepower"
        Mutaplasmid.Type.ExigentDurability -> "Exigent Durability"
        Mutaplasmid.Type.ExigentProjection -> "Exigent Projection"
        Mutaplasmid.Type.ExigentPrecision -> "Exigent Precision"
        Mutaplasmid.Type.GlorifiedExigentNavigation -> "Gl. Exigent Navigation"
        Mutaplasmid.Type.GlorifiedExigentFirepower -> "Gl. Exigent Firepower"
        Mutaplasmid.Type.GlorifiedExigentDurability -> "Gl. Exigent Durability"
        Mutaplasmid.Type.GlorifiedExigentProjection -> "Gl. Exigent Projection"
        Mutaplasmid.Type.GlorifiedExigentPrecision -> "Gl. Exigent Precision"
    }


/**
 * Returns a medium name of the mutaplasmid.
 */
val Mutaplasmid.mediumName: String
    get() = when (type) {
        Mutaplasmid.Type.Decayed -> "Decayed"
        Mutaplasmid.Type.Gravid -> "Gravid"
        Mutaplasmid.Type.Unstable -> "Unstable"
        Mutaplasmid.Type.Radical -> "Radical"
        Mutaplasmid.Type.GlorifiedDecayed -> "Glorified Decayed"
        Mutaplasmid.Type.GlorifiedGravid -> "Glorified Gravid"
        Mutaplasmid.Type.GlorifiedUnstable -> "Glorified Unstable"
        Mutaplasmid.Type.GlorifiedRadical -> "Glorified Radical"
        Mutaplasmid.Type.ExigentNavigation -> "Exigent Navigation"
        Mutaplasmid.Type.ExigentFirepower -> "Exigent Firepower"
        Mutaplasmid.Type.ExigentDurability -> "Exigent Durability"
        Mutaplasmid.Type.ExigentProjection -> "Exigent Projection"
        Mutaplasmid.Type.ExigentPrecision -> "Exigent Precision"
        Mutaplasmid.Type.GlorifiedExigentNavigation -> "Glorified Exigent Navigation"
        Mutaplasmid.Type.GlorifiedExigentFirepower -> "Glorified Exigent Firepower"
        Mutaplasmid.Type.GlorifiedExigentDurability -> "Glorified Exigent Durability"
        Mutaplasmid.Type.GlorifiedExigentProjection -> "Glorified Exigent Projection"
        Mutaplasmid.Type.GlorifiedExigentPrecision -> "Glorified Exigent Precision"
    }


/**
 * Returns the default name of a newly mutated module type.
 */
fun ModuleType.defaultMutatedName(mutaplasmid: Mutaplasmid) = "${mutaplasmid.shortName} $name"


/**
 * Returns the initial mutation of the given module with the given mutaplasmid.
 */
fun ModuleType.initiallyMutatedWith(mutaplasmid: Mutaplasmid): ModuleType {
    with(TheorycrafterContext.eveData) {
        return mutated(
            mutaplasmid = mutaplasmid,
            name = defaultMutatedName(mutaplasmid),
            valueByAttribute = attributeValuesForInitialMutationWith(mutaplasmid)
        )
    }
}


/**
 * Returns the default name of a newly mutated drone type.
 */
fun DroneType.defaultMutatedName(mutaplasmid: Mutaplasmid) = "${mutaplasmid.shortName} $name"


/**
 * Returns the initial mutation of the given module with the given mutaplasmid.
 */
fun DroneType.initiallyMutatedWith(mutaplasmid: Mutaplasmid): DroneType {
    with(TheorycrafterContext.eveData) {
        return mutated(
            mutaplasmid = mutaplasmid,
            name = defaultMutatedName(mutaplasmid),
            valueByAttribute = attributeValuesForInitialMutationWith(mutaplasmid)
        )
    }
}


/**
 * Returns the attribute values (mapped by attribute id) for the initial item type mutation.
 */
private fun EveItemType.attributeValuesForInitialMutationWith(mutaplasmid: Mutaplasmid): Map<Attribute<*>, Double> {
    val attributes = TheorycrafterContext.eveData.attributes
    return mutaplasmid.attributeMutations.entries.associate { (attrId, attrMutation) ->
        val attribute = attributes[attrId]
        val baseValue = attributeValues.getDoubleValue(attrId)
        val attrValueRange = attrMutation.attributeValueRange(baseValue)
        attribute to baseValue.coerceIn(attrValueRange)
    }
}
