package common.entity.npc;

import java.util.List;

import common.collect.BiMap;
import common.collect.HashBiMap;
import common.collect.Lists;
import common.init.SpeciesRegistry;
import common.init.SpeciesRegistry.ModelType;
import common.rng.Random;
import common.util.Identifyable;

public class SpeciesInfo {
	public final BiMap<String, Enum> classnames;
	public final Class<? extends EntityNPC> clazz;
	public final Class<? extends Enum> classEnum;
	public final ModelType renderer;
	public final boolean prefix;
	public final String id;
	public final String origin;
	public final String name;
	public final int color1;
	public final int color2;
	public final CharacterInfo[] chars;
	private final int[] alignment = new int[Alignment.values().length];
	private final int[] energies = new int[Energy.values().length];
	private final int[] baseEnergy = new int[Energy.values().length];
	
	public SpeciesInfo(String id, Class<? extends EntityNPC> clazz, Class<? extends Enum> classEnum, boolean prefix, String origin, String name, ModelType renderer, int color1, int color2, 
			Object ... names) {
		this.classnames = classEnum == null ? null : HashBiMap.create();
		this.clazz = clazz;
		this.classEnum = classEnum;
		this.renderer = renderer;
		this.prefix = prefix;
		this.id = id;
		this.origin = origin;
		this.name = name;
		this.color1 = color1;
		this.color2 = color2;
		List<CharacterInfo> chars = Lists.<CharacterInfo>newArrayList();
		Enum ctype = null;
		Alignment align = null;
		float height = 0.0f;
		for(int z = 0; z < names.length; z++) {
			if(names[z] == null) {
				ctype = null;
				align = null;
				height = 0.0f;
				continue;
			}
			if(names[z] instanceof Enum) {
				ctype = (Enum)names[z];
				continue;
			}
			if(names[z] instanceof Alignment) {
				align = (Alignment)names[z];
				continue;
			}
			if(names[z] instanceof Float) {
				height = (Float)names[z];
				continue;
			}
			String[] tok = ((String)names[z]).split(":", 3);
			int scolor1 = color1;
			int scolor2 = color2;
			if(z < names.length - 1 && names[z+1].getClass() == Integer.class)
				scolor2 = ((Integer)names[++z]).intValue();
			if(z < names.length - 1 && names[z+1].getClass() == Integer.class) {
				scolor1 = scolor2;
				scolor2 = ((Integer)names[++z]).intValue();
			}
			chars.add(new CharacterInfo(this, ctype, tok[0], tok.length > 1 && !tok[1].isEmpty() ? tok[1] : (tok[0].isEmpty() ? this.id : tok[0]).toLowerCase().replace(' ', '_'), 
					tok.length > 2 ? tok[2] : "", align, height, scolor1, scolor2, names.length > 1));
		}
		this.chars = chars.toArray(new CharacterInfo[chars.size()]);
		SpeciesRegistry.CLASSES.put(this.clazz, this);
		if(this.classEnum != null) {
			for(Enum type : this.classEnum.getEnumConstants()) {
				this.classnames.put(((Identifyable)type).getName(), type);
			}
		}
	}
	
	public CharacterInfo pickCharacter(Random rand) {
		return rand.pick(this.chars);
	}
	
	public SpeciesInfo setEnergy(Energy type, int affinity, int base) {
		this.energies[type.ordinal()] = affinity;
		this.baseEnergy[type.ordinal()] = base;
		return this;
	}
	
	public int getEnergyAffinity(Energy type) {
		return this.energies[type.ordinal()];
	}
	
	public int getEnergyBase(Energy type) {
		return this.baseEnergy[type.ordinal()];
	}
	
	public SpeciesInfo setAlignAffinity(Alignment type, int value) {
		this.alignment[type.ordinal()] = value;
		return this;
	}
	
	public int getAlignAffinity(Alignment type) {
		return this.alignment[type.ordinal()];
	}
}
