package org.unipept.xml;

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

/**
 * @author Bart Mesuere
 * 
 */
public class UniprotEntry {

    // peptide settings
    private static final int MIN_PEPT_SIZE = 5;
    private static final int MAX_PEPT_SIZE = 50;

    private String uniprotAccessionNumber;
    private int version;
    private int taxonId;
    private String type;
    private String recommendedName;
    private String submittedName;
    private String sequence;
    private List<UniprotDbRef> dbReferences;
    private List<UniprotGORef> goReferences;
    private List<UniprotECRef> ecReferences;
    private List<UniprotProteomeRef> protReferences;

    public UniprotEntry(String type) {
        this.type = type;
        dbReferences = new ArrayList<UniprotDbRef>();
        goReferences = new ArrayList<UniprotGORef>();
        ecReferences = new ArrayList<UniprotECRef>();
        protReferences = new ArrayList<UniprotProteomeRef>();
    }

    public void reset(String type) {
        uniprotAccessionNumber = null;
        version = 0;
        taxonId = 0;
        this.type = type;
        recommendedName = null;
        submittedName = null;
        sequence = null;
        dbReferences.clear();
        goReferences.clear();
        ecReferences.clear();
        protReferences.clear();
    }

    public String getUniprotAccessionNumber() {
        return uniprotAccessionNumber;
    }

    public void setUniprotAccessionNumber(String uniprotAccessionNumber) {
        if(this.uniprotAccessionNumber == null) {
            this.uniprotAccessionNumber = uniprotAccessionNumber;
        }
    }

    public int getVersion() {
        return version;
    }

    public void setVersion(int version) {
        this.version = version;
    }

    public int getTaxonId() {
        return taxonId;
    }

    public void setTaxonId(int taxonId) {
        this.taxonId = taxonId;
    }

    public String getType() {
        return type;
    }

    public String getName() {
        if(recommendedName != null) return recommendedName;
        return submittedName;
    }

    public void setRecommendedName(String name) {
        recommendedName = name;
    }

    public void setSubmittedName(String name) {
        submittedName = name;
    }

    public String getSequence() {
        return sequence;
    }

    public void setSequence(String sequence) {
        this.sequence = sequence;
    }

    public void addDbRef(UniprotDbRef ref) {
        dbReferences.add(ref);
    }

    public void addGORef(UniprotGORef ref) {
        goReferences.add(ref);
    }

    public void addECRef(UniprotECRef ref) {
        ecReferences.add(ref);
    }

    public void addProtRef(UniprotProteomeRef ref) {
        for (UniprotProteomeRef r : protReferences) {
            if (ref.equals(r)) {
                return;
            }
        }
        protReferences.add(ref);
    }

    public Stream<String> digest() {
        String[] splitArray = sequence.replaceAll("([RK])([^P])", "$1,$2")
                                      .replaceAll("([RK])([^P,])", "$1,$2")
                                      .split(",");
        return Arrays.stream(splitArray)
                     .filter(seq -> seq.length() >= MIN_PEPT_SIZE
                                 && seq.length() <= MAX_PEPT_SIZE);
    }

    public List<UniprotDbRef> getDbReferences() {
        return dbReferences;
    }

    public List<UniprotGORef> getGOReferences() {
        return goReferences;
    }

    public List<UniprotECRef> getECReferences() {
        return ecReferences;
    }

    public List<UniprotProteomeRef> getProtReferences() {
        return protReferences;
    }


    @Override
    public String toString() {
        return uniprotAccessionNumber + ", " + version + ", " + taxonId + ", " + type + ", "
                + sequence;
    }

}

@@ -719,16 +719,52 @@
 erences;
+%0A    private List%3CString%3E sequences;
 %0A%0A    pu
@@ -1042,24 +1042,69 @@
 eomeRef%3E();%0A
+        sequences = new ArrayList%3CString%3E();%0A
     %7D%0A%0A    p
@@ -1411,32 +1411,32 @@
 rences.clear();%0A
-
         protRefe
@@ -1447,24 +1447,51 @@
 es.clear();%0A
+        sequences.clear();%0A
     %7D%0A%0A    p
@@ -3072,22 +3072,20 @@
  public 
-Stream
+List
 %3CString%3E
@@ -3108,242 +3108,425 @@
     
-String%5B%5D splitArray = sequence.replaceAll(%22(%5BRK%5D)(%5B%5EP%5D)%22, %22$1,$2%22)%0A                                      .replaceAll(%22(%5BRK%5D)(%5B%5EP,%5D)%22, %22$1,$2%22)%0A                                      .split(%22,%22);%0A        return Arrays.stream(splitArray)
+sequences.clear();%0A        int start = 0;%0A        int length = sequence.length();%0A        for (int i = 0; i %3C length; i++) %7B%0A            char x = sequence.charAt(i);%0A            if ((x == 'K' %7C%7C x == 'R') && (i + 1 %3C length && sequence.charAt(i + 1) != 'P')) %7B%0A                if (i + 1 - start %3E= MIN_PEPT_SIZE && i + 1 - start %3C= MAX_PEPT_SIZE) %7B%0A                    sequences.add(sequence.substring(start, i + 1));
 %0A   
@@ -3542,57 +3542,40 @@
     
+%7D%0A
      
-.filter(seq -%3E seq.length() %3E= MIN_PEPT_SIZE
+           start = i + 1;
 %0A   
@@ -3579,32 +3579,34 @@
             
+%7D%0A
         
             
@@ -3589,32 +3589,34 @@
   %7D%0A        
+%7D%0A
         
      && seq.
@@ -3607,46 +3607,178 @@
     
-     && seq.length() %3C= MAX_PEPT_SIZE)
+if (length - start %3E= MIN_PEPT_SIZE && length - start %3C= MAX_PEPT_SIZE) %7B%0A            sequences.add(sequence.substring(start, length));%0A        %7D%0A        return sequences
 ;%0A  

apply @bmesuere's speedup for the digest