// Path: jrand-core/src/main/java/me/xdrop/jrand/Generator.java
// public abstract class Generator<T> {
// 
//     private Rand randGen;
// 
//     public Generator() {
//         this.randGen = new Rand();
//     }
// 
//     public Rand random() {
//         return this.randGen;
//     }
// 
//     public abstract T gen();
// 
//     public String repeat(int times) {
//         StringBuilder sb = new StringBuilder();
//         while (times-- > 0) {
//             sb.append(gen());
//         }
//         return sb.toString();
//     }
// 
//     public String genString() {
//         return gen().toString();
//     }
// 
//     public List<T> genMany(int num) {
//         List<T> many = new ArrayList<>();
//         for (int n = 0; n < num; n++) {
//             many.add(gen());
//         }
//         return many;
//     }
// 
//     public List<T> genManyUnique(int num) {
//         List<T> many = new LinkedList<>();
//         Set<T> present = new HashSet<>();
// 
// 
//         for (int n = 0; n < num; n++) {
//             T gen;
//             do {
//                 gen = gen();
//             } while (present.contains(gen));
//             many.add(gen);
//             present.add(gen);
//         }
// 
//         return many;
//     }
// 
//     public Set<T> genManyAsSet(int num) {
//         List<T> many = new LinkedList<>();
//         for (int n = 0; n < num; n++) {
//             many.add(gen());
//         }
//         return new HashSet<>(many);
//     }
// 
// }
// 
// Path: jrand-core/src/main/java/me/xdrop/jrand/model/person/PersonType.java
// public enum PersonType {
//     CHILD(1, 12),
//     TEEN(13,17),
//     ADULT(18, 40),
//     SENIOR(41, 120),
//     GENERIC(1, 120);
// 
//     private int min;
// 
//     private int max;
//     PersonType(int min, int max) {
//         this.min = min;
//         this.max = max;
//     }
// 
//     public int getMin() {
//         return min;
//     }
// 
//     public int getMax() {
//         return max;
//     }
// 
// }


import me.xdrop.jrand.Generator;
import me.xdrop.jrand.annotation.Facade;
import me.xdrop.jrand.model.person.PersonType;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.joda.time.Period;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.util.Date;
    }

    private long getRandomTimeBetweenTwoDates (long endTime, long beginTime) {
        long diff = endTime - beginTime + 1;
        return beginTime + (long) (random().randDouble() * diff);
    }

    @Override
    public Date gen() {
        DateTime birthday = getDateTime();
        return birthday.toDate();
    }

    /**
     * Generate as Joda Time {@link DateTime}
     * @return Joda time DateTime class
     */
    public DateTime getDateTime() {
        DateTime now = new DateTime();
        int age = new AgeGenerator().personType(personType).gen();
        int dobYear = now.minusYears(age).getYear();
        DateTime yearBegin = new DateTime(dobYear, DateTimeConstants.JANUARY, 1, 0,0);

        long mills = getRandomTimeBetweenTwoDates(now.minusYears(age).getMillis(), yearBegin.getMillis());
        return new DateTime(mills);
    }

    @Override
    public String genString() {
        DateTimeFormatter format = DateTimeFormat.forPattern(this.format);
// Path: jrand-core/src/main/java/me/xdrop/jrand/Generator.java
// public abstract class Generator<T> {
// 
//     private Rand randGen;
// 
//     public Generator() {
//         this.randGen = new Rand();
//     }
// 
//     public Rand random() {
//         return this.randGen;
//     }
// 
//     public abstract T gen();
// 
//     public String repeat(int times) {
//         StringBuilder sb = new StringBuilder();
//         while (times-- > 0) {
//             sb.append(gen());
//         }
//         return sb.toString();
//     }
// 
//     public String genString() {
//         return gen().toString();
//     }
// 
//     public List<T> genMany(int num) {
//         List<T> many = new ArrayList<>();
//         for (int n = 0; n < num; n++) {
//             many.add(gen());
//         }
//         return many;
//     }
// 
//     public List<T> genManyUnique(int num) {
//         List<T> many = new LinkedList<>();
//         Set<T> present = new HashSet<>();
// 
// 
//         for (int n = 0; n < num; n++) {
//             T gen;
//             do {
//                 gen = gen();
//             } while (present.contains(gen));
//             many.add(gen);
//             present.add(gen);
//         }
// 
//         return many;
//     }
// 
//     public Set<T> genManyAsSet(int num) {
//         List<T> many = new LinkedList<>();
//         for (int n = 0; n < num; n++) {
//             many.add(gen());
//         }
//         return new HashSet<>(many);
//     }
// 
// }
// 
// Path: jrand-core/src/main/java/me/xdrop/jrand/model/person/PersonType.java
// public enum PersonType {
//     CHILD(1, 12),
//     TEEN(13,17),
//     ADULT(18, 40),
//     SENIOR(41, 120),
//     GENERIC(1, 120);
// 
//     private int min;
// 
//     private int max;
//     PersonType(int min, int max) {
//         this.min = min;
//         this.max = max;
//     }
// 
//     public int getMin() {
//         return min;
//     }
// 
//     public int getMax() {
//         return max;
//     }
// 
// }


// Path: jrand-core/src/main/java/me/xdrop/jrand/generators/person/BirthdayGenerator.java
import me.xdrop.jrand.Generator;
import me.xdrop.jrand.annotation.Facade;
import me.xdrop.jrand.model.person.PersonType;
import org.joda.time.DateTime;
import org.joda.time.DateTimeConstants;
import org.joda.time.Period;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import java.util.Date;

    }

    private long getRandomTimeBetweenTwoDates (long endTime, long beginTime) {
        long diff = endTime - beginTime + 1;
        return beginTime + (long) (random().randDouble() * diff);
    }

    @Override
    public Date gen() {
        DateTime birthday = getDateTime();
        return birthday.toDate();
    }

    /**
     * Generate as Joda Time {@link DateTime}
     * @return Joda time DateTime class
     */
    public DateTime getDateTime() {
        DateTime now = new DateTime();
        int age = new AgeGenerator().personType(personType).gen();
        int dobYear = now.minusYears(age).getYear();
        DateTime yearBegin = new DateTime(dobYear, DateTimeConstants.JANUARY, 1, 0,0);

        long mills = getRandomTimeBetweenTwoDates(now.minusYears(age).getMillis(), yearBegin.getMillis());
        return new DateTime(mills);
    }

    @Override
    public String genString() {
        DateTimeFormatter format = DateTimeFormat.forPattern(this.format);
        return format.print(getDateTime());