package me.xdrop.jrand.generators.person;

import me.xdrop.jrand.Generator;
import me.xdrop.jrand.annotation.Facade;
import me.xdrop.jrand.data.AssetLoader;
import me.xdrop.jrand.model.person.Gender;
import me.xdrop.jrand.model.person.Prefix;
import me.xdrop.jrand.model.person.PrefixMapper;
import me.xdrop.jrand.utils.Choose;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;


@Facade(accessor = "prefix")
public class PrefixGenerator extends Generator<String> {
    private List<Prefix> prefixPool;
    private List<Prefix> malePrefixes;
    private List<Prefix> femalePrefixes;
    private List<Prefix> neutralPrefixes;

    private boolean isLong;
    private boolean all;


    public PrefixGenerator() {
        this.prefixPool = new ArrayList<>();
        malePrefixes = AssetLoader.loadList("male/prefixes.txt", new PrefixMapper());
        femalePrefixes = AssetLoader.loadList("female/prefixes.txt", new PrefixMapper());
        neutralPrefixes = AssetLoader.loadList("neutral/prefixes.txt", new PrefixMapper());
        prefixPool.addAll(malePrefixes);
        prefixPool.addAll(femalePrefixes);
    }

    /**
     * Set whether to return prefixes are returned in a non-abreviated form
     * For example Misses instead of Mrs
     * @param isLong True for long,
     *               False otherwise
     * @return The same generator
     */
    public PrefixGenerator full(boolean isLong) {
        this.isLong = isLong;
        return this;
    }

    /**
     * Set whether to return prefixes are returned in a non-abreviated form
     * For example Misses instead of Mrs
     * @return The same generator
     */
    public PrefixGenerator full() {
        return full(true);
    }
    /**
     * Include all male, female and neutral genders
     * @return The same generator
     */
    public PrefixGenerator all() {
        return all(true);
    }

    /**
     * Include all male, female and neutral genders
     * @param enabled True for enabled,
     *                False otherwise
     * @return The same generator
     */
    public PrefixGenerator all(boolean enabled) {
        if (enabled){
            prefixPool.clear();
            prefixPool.addAll(malePrefixes);
            prefixPool.addAll(femalePrefixes);
            prefixPool.addAll(neutralPrefixes);
        } else {
            prefixPool.removeAll(neutralPrefixes);
        }
        return this;
    }

    /**
     * Set the gender of the prefixes to be returned in.
     *
     * @param gender Gender to generate
     * @return The same generator
     */
    public PrefixGenerator gender(Gender gender) {
        prefixPool.clear();
        if (gender == Gender.MALE) {
            prefixPool.addAll(malePrefixes);
        } else if (gender == Gender.FEMALE) {
            prefixPool.addAll(femalePrefixes);
        } else if (gender == Gender.NEUTRAL) {
            prefixPool.addAll(neutralPrefixes);
        } else {
            prefixPool.addAll(malePrefixes);
            prefixPool.addAll(femalePrefixes);
        }
        return this;
    }


    /**
     * Set the gender of the prefixes to be returned in.
     * "male" or "m" for male, "female" or "f" for female,
     * "n" for neutral, "all" for all, anything else to include only
     * male and female
     *
     * @param gender Set to "m"/"male" for male and "f"/"female" for female
     * @return The same generator
     */
    public PrefixGenerator gender(String gender) {
        prefixPool.clear();
        if (gender.equalsIgnoreCase("male") || gender.equalsIgnoreCase("m")) {
            prefixPool.addAll(malePrefixes);
        } else if (gender.equalsIgnoreCase("female") || gender.equalsIgnoreCase("f")) {
            prefixPool.addAll(femalePrefixes);
        } else if (gender.equalsIgnoreCase("neutral") || gender.equalsIgnoreCase("n")) {
            prefixPool.addAll(neutralPrefixes);
        } else if (gender.equalsIgnoreCase("all")) {
            prefixPool.addAll(malePrefixes);
            prefixPool.addAll(femalePrefixes);
            prefixPool.addAll(neutralPrefixes);
        } else {
            prefixPool.addAll(malePrefixes);
            prefixPool.addAll(femalePrefixes);
        }
        return this;
    }

    public Prefix genAsPrefix() {
        return Choose.one(prefixPool);
    }

    public String gen() {
        Prefix prefix = Choose.one(prefixPool);
        return isLong ? prefix.getFull() : prefix.getAbbreviation();
    }
}

@@ -699,16 +699,45 @@
 an all;%0A
+    private boolean withDot;%0A
 %0A%0A    pu
@@ -1745,24 +1745,25 @@
 rue);%0A    %7D%0A
+%0A
     /**%0A    
@@ -1912,32 +1912,484 @@
 l(true);%0A    %7D%0A%0A
+    /**%0A     * Add a dot at the end of the prefix%0A     * @param enabled True for enabled,%0A     *                False otherwise%0A     * @return The same generator%0A     */%0A    public PrefixGenerator withDot(boolean enabled) %7B%0A        this.withDot = enabled;%0A        return this;%0A    %7D%0A%0A    /**%0A     * Add a dot at the end of the prefix%0A     * @return The same generator%0A     */%0A    public PrefixGenerator withDot() %7B%0A        return withDot(true);%0A    %7D%0A%0A
     /**%0A     * I
@@ -4871,22 +4871,32 @@
         
-return
+String _prefix =
  isLong 
@@ -4938,20 +4938,106 @@
 eviation();%0A
+        if (withDot) %7B%0A            _prefix += '.';%0A        %7D%0A%0A        return _prefix;%0A
     %7D%0A%7D%0A

Add withDot to prefix generator