package com.bina.varsim.types;

import java.util.logging.Logger;

/**
 * Used to represent the chromosome name, able to useful things like determine sex
 * <p/>
 * Created by johnmu on 1/27/15.
 */
public class ChrString implements Comparable<ChrString>{
    private final static Logger log = Logger.getLogger(ChrString.class.getName());
    final String name;

    public ChrString(final String name) {
        this.name = name;
    }

    /**
     * Converts hg19 or b37 format chromosomes to b37 format
     *
     * @param chr Chromosome name as a string
     * @return chromosome name as a string in b37 format
     */
    public static String stripChr(final String chr) {
        if (chr.length() > 3 && chr.substring(0, 3).equalsIgnoreCase("chr")) {
            return chr.substring(3);
        }
        if (chr.equals("M")) {
            return "MT";
        }
        return chr;
    }

    /**
     * convert string array to ChrString array
     * @param s
     * @return
     */
    public static ChrString[] string2ChrString(final String[] s) {
        if (s == null) {
            return new ChrString[0];
        }
        ChrString[] chrStrings = new ChrString[s.length];
        for (int i = 0; i < s.length; i++) {
            chrStrings[i] = new ChrString(s[i]);
        }
        return chrStrings;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return name;
    }

    public boolean isX() {
        if (name.equals("X") || name.equals("chrX")) {
            return true;
        } else if (name.startsWith("X") || name.startsWith("chrX")) {
            //TODO: handle restricted X chromosome (say X_1_1000)
            log.warning("Prefix looks like chromosome X, but might be treated as diploid genome.");
            return false;
        }
        return false;
    }

    public boolean isY() {
        if (name.equals("Y") || name.equals("chrY")) {
            return true;
        } else if (name.startsWith("Y") || name.startsWith("chrY")) {
            //TODO: handle restricted Y chromosome (say Y_1_1000)
            log.warning("Prefix looks like chromosome Y, but might be treated as diploid genome.");
            return false;
        }
        return false;
    }

    public boolean isMT() {
        if (name.equals("MT") || name.equals("chrM")) {
            return true;
        } else if (name.startsWith("MT") || name.startsWith("chrM")) {
            //TODO: handle restricted MT chromosome (say chrM_1_1000)
            log.warning("Prefix looks like chromosome MT, but might be treated as diploid genome.");
            return false;
        }
        return false;
    }

    /**
     * Checks if the chromosome is haploid.
     * TODO ignore the alternate contigs for now
     *
     * @param gender Gender of individual
     * @return True if the chromosome is haploid given the sex
     */
    public boolean isHaploid(final GenderType gender) {
        if (isMT()) {
            return true;
        } else if (gender == GenderType.MALE) {
            return (isX() || isY());
        }
        return false;
    }

    @Override
    public boolean equals(final Object o) {
        if (this == o) return true;
        if (!(o instanceof ChrString)) return false;

        ChrString chrString = (ChrString) o;

        return name.equals(chrString.name);

    }

    @Override
    public int hashCode() {
        return name.hashCode();
    }

    @Override
    public int compareTo(final ChrString other) {
        return name.compareTo(other.getName());
    }
}

@@ -57,16 +57,48 @@
 .Logger;
+%0Aimport java.util.regex.Pattern;
 %0A%0A/**%0A *
@@ -359,24 +359,291 @@
 getName());%0A
+    private final static Pattern restrictedChrX = Pattern.compile(%22(chr)?X_%5C%5Cd+_%5C%5Cd+%22);%0A    private final static Pattern restrictedChrY = Pattern.compile(%22(chr)?Y_%5C%5Cd+_%5C%5Cd+%22);%0A    private final static Pattern restrictedChrMT = Pattern.compile(%22(MT%7CchrM)_%5C%5Cd+_%5C%5Cd+%22);%0A
     final St
@@ -1879,124 +1879,49 @@
 if (
-name.startsWith(%22X%22) %7C%7C name.startsWith(%22chrX%22)) %7B%0A            //TODO: handle restricted X chromosome (say X_1_1000)
+restrictedChrX.matcher(name).matches()) %7B
 %0A   
@@ -1946,70 +1946,42 @@
 ng(%22
-Prefix looks like chromosome X, but might be treated as diploi
+Treating %22 + name + %22 as restricte
 d ge
@@ -2000,36 +2000,35 @@
          return 
-fals
+tru
 e;%0A        %7D%0A   
@@ -2183,124 +2183,49 @@
 if (
-name.startsWith(%22Y%22) %7C%7C name.startsWith(%22chrY%22)) %7B%0A            //TODO: handle restricted Y chromosome (say Y_1_1000)
+restrictedChrY.matcher(name).matches()) %7B
 %0A   
@@ -2250,70 +2250,42 @@
 ng(%22
-Prefix looks like chromosome Y, but might be treated as diploi
+Treating %22 + name + %22 as restricte
 d ge
@@ -2304,36 +2304,35 @@
          return 
-fals
+tru
 e;%0A        %7D%0A   
@@ -2489,129 +2489,50 @@
 if (
-name.startsWith(%22MT%22) %7C%7C name.startsWith(%22chrM%22)) %7B%0A            //TODO: handle restricted MT chromosome (say chrM_1_1000)
+restrictedChrMT.matcher(name).matches()) %7B
 %0A   
@@ -2557,71 +2557,42 @@
 ng(%22
-Prefix looks like chromosome MT, but might be treated as diploi
+Treating %22 + name + %22 as restricte
 d ge
@@ -2615,28 +2615,27 @@
      return 
-fals
+tru
 e;%0A        %7D

check restricted genome