#ifndef __CosGraphs_idl__
#define __CosGraphs_idl__

#include <coss/CosObjectIdentity.idl>
#include <coss/CosRelationships.idl>

#pragma prefix "omg.org"

module CosGraphs {
  
  interface TraversalFactory;
  interface Traversal;
  interface TraversalCriteria;
  interface Node;
  interface NodeFactory;
  interface Role;
  interface EdgeIterator;
  
  struct NodeHandle {
    Node the_node;
    ::CosObjectIdentity::ObjectIdentifier
    constant_random_id;
  };
  typedef sequence<NodeHandle> NodeHandles;
  
  struct NamedRole {
    Role the_role;
    ::CosRelationships::RoleName the_name;
  };
  typedef sequence<NamedRole> NamedRoles;
  
  struct EndPoint {
    NodeHandle the_node;
    NamedRole the_role;
    
    
  };
  typedef sequence<EndPoint> EndPoints;
  
  struct Edge {
    EndPoint from;
    ::CosRelationships::RelationshipHandle
    the_relationship;
    EndPoints relatives;
  };
  typedef sequence<Edge> Edges;
  
  enum PropagationValue {deep, shallow, none,
			 inhibit};
  enum Mode {depthFirst, breadthFirst, bestFirst};
  
  interface TraversalFactory {
    Traversal create_traversal_on (
				   in NodeHandle root_node,
				   in TraversalCriteria the_criteria,
				   in Mode how);
  };
  
  interface Traversal {
    typedef unsigned long TraversalScopedId;
    struct ScopedEndPoint {
      EndPoint point;
      TraversalScopedId id;
    };
    typedef sequence<ScopedEndPoint>
      ScopedEndPoints;
    struct ScopedRelationship {
      ::CosRelationships::RelationshipHandle
      scoped_relationship;
      TraversalScopedId id;
    };
    struct ScopedEdge {
      ScopedEndPoint from;
      ScopedRelationship the_relationship;
      ScopedEndPoints relatives;
    };
    typedef sequence<ScopedEdge> ScopedEdges;
    boolean next_one (out ScopedEdge the_edge);
    boolean next_n (in short how_many,
		    out ScopedEdges the_edges);
    void destroy ();
  };
  
  interface TraversalCriteria {

    struct WeightedEdge {
      Edge the_edge;
      unsigned long weight;
      sequence<NodeHandle> next_nodes;
    };

    typedef sequence<WeightedEdge> WeightedEdges;

    void visit_node(in NodeHandle a_node,
		    in Mode search_mode);
    boolean next_one (out WeightedEdge the_edge);
    boolean next_n (in short how_many,
		    out WeightedEdges the_edges);
    void destroy();
  };
  
  interface Node:
    ::CosObjectIdentity::IdentifiableObject {
    typedef sequence<Role> Roles;
    exception NoSuchRole {};
    exception DuplicateRoleType {};
    
    readonly attribute
      ::CosRelationships::RelatedObject
      related_object;
    readonly attribute Roles roles_of_node;
    Roles roles_of_type (
			 in ::CORBA::InterfaceDef
			 role_type);
    void add_role (in Role a_role)
      raises (DuplicateRoleType);
    void remove_role (in ::CORBA::InterfaceDef
		      of_type)
      raises (NoSuchRole);
    // extension for generic node
    // void destroy ();
  };
  
  interface NodeFactory {
    Node create_node (in Object related_object);
  };
  
  interface Role : ::CosRelationships::Role {
    void get_edges ( in long how_many,
		     out Edges the_edges,
		     out EdgeIterator the_rest);
  };
  
  interface EdgeIterator {
    boolean next_one (out Edge the_edge);
    boolean next_n ( in unsigned long how_many,
		     out Edges the_edges);
    void destroy ();
  };
  
};


#endif

