package com.ohnosequences.typedGraphs.titan.test;

import com.ohnosequences.typedGraphs.*;
import com.ohnosequences.typedGraphs.titan.*;

import com.thinkaurelius.titan.core.TitanLabel;
import com.thinkaurelius.titan.core.TitanKey;
import com.thinkaurelius.titan.core.TitanVertex;
import com.thinkaurelius.titan.core.TitanEdge;

public interface TitanSchemaDef {


  // define a term
  interface Term <
    N extends Term<N,NT>, NT extends Term.Type<N,NT>
  >
    extends Node<N,NT>
  {
    interface Type <
      N extends Term<N,NT>, NT extends Term.Type<N,NT>
    > 
      extends Node.Type<N,NT>
    {}

    // properties

    interface id <
      N extends Term<N,NT>,
      NT extends Term.Type<N,NT>,
      P extends id<N,NT,P>
    > 
      extends Property<N,NT,P,String> 
    {
      @Override public default String name() { return "id"; } 
      @Override public default Class<String> valueClass() { return String.class; }
    }
  } 

  // a term implementation
  abstract class TitanTerm extends TitanNode <
    TitanTerm, TitanTerm.Type
  > 
    implements Term<TitanTerm, TitanTerm.Type> 
  {

    public TitanTerm(TitanVertex vertex) { super(vertex); }

    abstract class Type implements TitanNode.Type<TitanTerm, TitanTerm.Type>, Term.Type<TitanTerm, TitanTerm.Type> {

      // implement this through the graph
      @Override public TitanKey titanKey() { return null; }
    }

    abstract class id implements 
      TitanProperty<TitanTerm,TitanTerm.Type, id, String>,
      Term.id<TitanTerm, TitanTerm.Type, id>
    {}

  }

  interface PartOf <
    S extends Term<S,ST>, ST extends Term.Type<S,ST>,
    R extends PartOf<S,ST,R,RT,T,TT>, RT extends PartOf.Type<S,ST,R,RT,T,TT>,
    T extends Term<T,TT>, TT extends Term.Type<T,TT>
  >
    extends Relationship<S,ST,R,RT,T,TT>
  {

    interface Type <
      S extends Term<S,ST>, ST extends Term.Type<S,ST>,
      R extends PartOf<S,ST,R,RT,T,TT>, RT extends PartOf.Type<S,ST,R,RT,T,TT>,
      T extends Term<T,TT>, TT extends Term.Type<T,TT>
    >
      extends Relationship.Type<S,ST,R,RT,T,TT>
    {}
  }

  abstract class TitanPartOf extends TitanRelationship <
    TitanTerm, TitanTerm.Type,
    TitanPartOf, TitanPartOf.Type,
    TitanTerm, TitanTerm.Type    
  > 
    implements PartOf <
      TitanTerm, TitanTerm.Type,
      TitanPartOf, TitanPartOf.Type,
      TitanTerm, TitanTerm.Type
    >
  {

    public TitanPartOf(TitanEdge edge) { super(edge); }

    abstract class Type implements TitanRelationship.Type < 
        TitanTerm, TitanTerm.Type,
        TitanPartOf, TitanPartOf.Type,
        TitanTerm, TitanTerm.Type    
      >,
      PartOf.Type <
        TitanTerm, TitanTerm.Type,
        TitanPartOf, TitanPartOf.Type,
        TitanTerm, TitanTerm.Type    
      >
      {

        // TODO implement through a graph where you define this
        @Override public TitanLabel label() { return null; } 
      }
  }
}
@@ -326,622 +326,97 @@
 e;%0A%0A
-public interface TitanSchemaDef %7B%0A%0A%0A  // define a term%0A  interface Term %3C%0A    N extends Term%3CN,NT%3E, NT extends Term.Type%3CN,NT%3E%0A  %3E%0A    extends Node%3CN,NT%3E%0A  %7B%0A    interface Type %3C%0A      N extends Term%3CN,NT%3E, NT extends Term.Type%3CN,NT%3E%0A    %3E %0A      extends Node.Type%3CN,NT%3E%0A    %7B%7D%0A%0A    // properties%0A%0A    interface id %3C%0A      N extends Term%3CN,NT%3E,%0A      NT extends Term.Type%3CN,NT%3E,%0A      P extends id%3CN,NT,P%3E%0A    %3E %0A      extends Property%3CN,NT,P,String%3E %0A    %7B%0A      @Override public default String name() %7B return %22id%22; %7D %0A      @Override public default Class%3CString%3E valueClass() %7B return String.class; %7D%0A    %7D%0A  %7D 
+import com.ohnosequences.typedGraphs.test.SchemaDef.*;%0A%0Apublic interface TitanSchemaDef %7B
 %0A%0A  
@@ -1018,542 +1018,8 @@
  %7D%0A%0A
-  interface PartOf %3C%0A    S extends Term%3CS,ST%3E, ST extends Term.Type%3CS,ST%3E,%0A    R extends PartOf%3CS,ST,R,RT,T,TT%3E, RT extends PartOf.Type%3CS,ST,R,RT,T,TT%3E,%0A    T extends Term%3CT,TT%3E, TT extends Term.Type%3CT,TT%3E%0A  %3E%0A    extends Relationship%3CS,ST,R,RT,T,TT%3E%0A  %7B%0A%0A    interface Type %3C%0A      S extends Term%3CS,ST%3E, ST extends Term.Type%3CS,ST%3E,%0A      R extends PartOf%3CS,ST,R,RT,T,TT%3E, RT extends PartOf.Type%3CS,ST,R,RT,T,TT%3E,%0A      T extends Term%3CT,TT%3E, TT extends Term.Type%3CT,TT%3E%0A    %3E%0A      extends Relationship.Type%3CS,ST,R,RT,T,TT%3E%0A    %7B%7D%0A  %7D%0A%0A
   ab

split schema def and impl in the tests