# Copyright: Copyright 2009 Topic Maps Lab, University of Leipzig.
# License:   Apache License, Version 2.0

module RTM
  module Navigation
    module Topic
      
      # Returns the topics this topic is an instance of.
      #
      # The result may be empty.
      #
      # :call-seq:
      #   types -> Set of Topics
      #
      def types
        # NO SUPERISE IN Axes/NAVIGATION
        raise "This method (types) should never be executed because the corresponding TMAPI function should be called"
        getTypes
      end
      
      # Returns the topic this topic is an instance of. It must have
      # exactly one type, else an error is raised.
      #
      # Returns nil if this Topic has no type.
      #
      # :call-seq:
      #   type -> Topic or nil
      #
      def type
        raise "Topic must have exactly one type to call the type-method. Use the types-method instead." unless types.size < 2
        types.size == 1 ? types.to_a.first : nil
      end
      
      # Returns the topics which are instances of this topic.
      # This method uses the TMAPI TypeInstanceIndex.
      #
      # The result may be empty.
      #
      # :call-seq:
      #   instances -> Set of Topics
      #
      def instances
        type_instance_index.getTopics(self)
      end
      
      # Returns the instance of this Topic. It must have exactly one
      # instance, else an error is raised.
      #
      # Returns nil if this Topic has no instance.
      #
      # :call-seq:
      #   instance -> Topic
      #
      def instance
        raise "Topic must have exactly one instance to call the instance-method. Use the instances-method instead." unless instances.size < 2
        instances.size == 1 ?  instances.to_a.first : nil
      end
      
      alias :reverse_types :instances
      
      # Returns the types this topic is an instance of. Calls
      # the TMAPI getTypes method.
      #
      # The result may be empty.
      #
      # :call-seq:
      #   reverse_instances -> Set of Topics
      #
      def reverse_instances
        types
      end

      # Returns the types and all transitive supertypes of the types of
      # this topic. No duplicates are returned.
      #
      # The result may be empty.
      #
      # :call-seq:
      #   transitive_types -> Array of Topics
      #
      def transitive_types
        trans_types = types.to_a #may be empty
        types.each do |type|
          trans_types.concat(type.transitive_supertypes)
        end
        trans_types = trans_types.uniq #no duplicates outside of tmql mode
      end

      # Returns instances and the instances of all transitive subtypes
      # of this topic. No duplicates are returned.
      #
      # The result may be empty.
      #
      # :call-seq:
      #   transitive_instances -> Array of Topics
      #
      def transitive_instances
        trans_instances = instances.to_a #may be empty
        transitive_subtypes.each do |subtype|
          trans_instances.concat(subtype.instances.to_a)
        end
        trans_instances = trans_instances.uniq #no duplicates outside of tmql mode
      end

    end
  end
end