/*
  # NCBI Taxonomy

  Taxon vertices, with a *parent* edge corresponding to the tree structure. for an up-to-date description of the data see

  - [The NCBI Taxonomy database](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3245000/)
  - [FTP dump readme](ftp://ftp.ncbi.nih.gov/pub/taxonomy/taxdump_readme.txt)
*/
package com.bio4j.model;

import com.bio4j.angulillos.*;
import com.bio4j.angulillos.Arity.*;

public final class NCBITaxonomyGraph<V,E> extends TypedGraph<NCBITaxonomyGraph<V,E>,V,E> {

  public NCBITaxonomyGraph(UntypedGraph<V,E> graph) { super(graph); }
  @Override public final NCBITaxonomyGraph<V,E> self() { return this; }

  /*
    ## Taxon

  */
  public final class Taxon extends Vertex<Taxon> {

    private Taxon(V vertex) { super(vertex, taxon); }

    @Override public final Taxon self() { return this; }
  }

  public final TaxonType taxon = new TaxonType();
  public final class TaxonType extends VertexType<Taxon> {

    @Override public final Taxon fromRaw(V vertex) { return new Taxon(vertex); }

    /*
      ### ID

      Indexed for unique matches.
    */
    public final ID id = new ID();
    public final class ID extends Property<String> implements FromAtMostOne, ToOne {

      private ID() { super(String.class); }

      public final Index index = new Index();
      public final class Index extends UniqueIndex<ID, String> {

        private Index() { super(id); }
      }
    }

    /*
      ### Name

      This is the standard name of the taxon, like *Escherichia coli* or *Bacteria*. Corresponds the the (non-unique) *scientific name* in NCBI taxonomy data.
    */
    public final Name name = new Name();
    public final class Name extends Property<String> implements FromAny, ToOne {

      private Name() { super(String.class); }
    }

    /*
      ### Taxonomic rank

      Values are, among others, *species*, *genus*, or *no rank*; see the enum below.
    */
    public final TaxonomicRank taxonomicRank = new TaxonomicRank();
    public final class TaxonomicRank extends Property<TaxonomicRanks> implements FromAny, ToOne {

      private TaxonomicRank() { super(TaxonomicRanks.class); }
    }
  }

  public static enum TaxonomicRanks {

    noRank,
    superkingdom,
    kingdom,
    superphylum,
    phylum,
    subphylum,
    clazz, // reserved word
    subclass,
    order,
    suborder,
    family,
    subfamily,
    tribe,
    subtribe,
    genus,
    subgenus,
    speciesGroup,
    speciesSubgroup,
    species,
    subspecies;
  }

  /*
    ### Parent taxon

    Every taxon *but* the root has *exactly one* parent.
  */
  public final class Parent extends Edge<Taxon, Parent, Taxon> {

    private Parent(E edge) { super(edge, parent); }

    @Override public final Parent self() { return this; }
  }

  public final ParentType parent = new ParentType();
  public final class ParentType extends EdgeType<Taxon, Parent, Taxon> implements FromAny, ToAtMostOne {

    private ParentType() { super(taxon, taxon); }
    @Override public final Parent fromRaw(E edge) { return new Parent(edge); }
  }
}

@@ -2140,32 +2140,123 @@
 ); %7D%0A    %7D%0A  %7D%0A%0A
+  /*%0A    The set of valid ranks is nowhere documented; this is just an approximation.%0A  */%0A
   public static 
@@ -2415,22 +2415,85 @@
     
-order,%0A    sub
+superclass,%0A    infraclass,%0A    order,%0A    parvorder,%0A    suborder,%0A    infra
 orde
@@ -2518,24 +2518,41 @@
  subfamily,%0A
+    superfamily,%0A
     tribe,%0A 
@@ -2655,16 +2655,152 @@
 bspecies
+,%0A    varietas,%0A    forma,%0A    thereIsAnIndeterminateNumberOfRanksAsATaxonomistMayInventANewRankAtWillAtAnyTimeIfTheyFeelThisIsNecessary
 ;%0A  %7D%0A%0A 

add moar taxonomic ranks