require "qt2"
include Qt2

class ClassTree
   def initialize modary
   @underClass = Hash.new
   @const_list = []
   clslist = modary.select { |c| veval(c).is_a? Class}
   modlist = modary - clslist
   @modary = clslist + modlist
   @modary.uniq!
   @modary.each do  |module_name|
      module_int = veval (module_name)
      if(module_int.is_a? Class)
         flag_module = false
      else
         flag_module =true
      end
      if(!flag_module)
         module_index = ""
      else
         module_index = module_name + "::"
      end
      const_list = module_int.constants
      if(flag_module)
          @const_list -= const_list
      end
      const_list = const_list.collect { |c| module_index + c }
      @const_list += const_list
   end
   @const_list_mod = @const_list.dup
#setup @underModule when module is target
#   if(@flag_module)
      underModule = @const_list.select {|c| veval(c).is_a? Module}
      underModule = underModule.reject {|c| veval(c).is_a? Class}
#   end
#
   underModule -= @modary
   @modary += underModule
   @modary.uniq!
   if(underModule.size > 0)
      underModule.each do  |m|
      uconst_list = veval(m).constants
      @const_list -= uconst_list
      uconst_list = uconst_list.collect{ |c| m + "::" + c}
      @const_list += uconst_list
      end
   end
#   @underModule.uniq!
#   @underModule.sort!
#   @modary.uniq!
   @const_list.uniq!
   @const_list.sort!
# make class tree
   superclasses = []
   underclasses = []
   @const_list.each do |c|
      begin
         c_int = veval( c  )
      rescue  NameError
         true
      end
      if c_int.is_a? Class
          underclasses.push(c_int)
          key = c_int.superclass
          superclasses.push(key)
         ary = @underClass[key]
            if ary.nil?
               ary = []
               @underClass[key] = ary
           end
          ary << c
      end
     end
#     superclasses.uniq!
#     underclasses.uniq!
     superclasses -= underclasses
     superclasses -= [nil]
     superclasses_names = superclasses.collect { |c| c.name }
     @modary = superclasses_names | @modary
   end
   def underClass
      @underClass
   end
   def createTree listView
      @modary.each do  |mod_name|
         i = QListViewItem.new(listView,mod_name)
         underItem = @underClass[veval(mod_name)]
         if(!underItem.nil?)
            underItem.sort.each do | cls_name |
               addItem(cls_name,i)
            end
          end
      end
   end
   def addItem(cls,vitem)
      i = QListViewItem.new(vitem,cls)
      cls_int = veval (cls )
      childList = @underClass[cls_int]
      if (!childList.nil?)
         childList.sort.each do |ccls|
            addItem(ccls,i)
         end
      end
   end

   def changeConstants( vlist, cls)
      vlist.clear
         cls_int = veval (cls )
         cls_consts = cls_int.constants

         if (cls_int.is_a? Class and cls != "Object" )
            cls_consts -= cls_int.superclass.constants
         end
         cls_consts = cls_consts.reject do |c|
            begin
               veval(cls + "::" + c).is_a? Module
            rescue NameError
               true
            end
         end
         cls_consts.sort.each do |c|
            vlist.insertItem(c)
      end
   end

   def changeMethods ( mlist, cls)
     mlist.clear
        methods = getSingletonMethod(cls)
        if (!methods.nil?)
            mlist.insertItem("-singleton method-")
            methods.sort.each do |m|
               mlist.insertItem(m)
            end
        end
        methods = getMethod(cls)
        if (!methods.nil?)
            mlist.insertItem("-class method-")
            methods.sort.each do |m|
               mlist.insertItem(m)
            end
        end
        methods = getInstanceMethod(cls)
        if (!methods.nil?)
            mlist.insertItem("-instance method-")
            methods.sort.each do |m|
               mlist.insertItem(m)
            end
        end
   end
   def getSingletonMethod(cls)
      cls_int = veval (cls )
      methods = cls_int.singleton_methods
      if((cls_int.is_a? Class) and ( cls != "Object"))
         methods -= cls_int.superclass.singleton_methods
         #methods -= @module_int.methods
      elsif( cls != "Object")
         methods -= Object.singleton_methods
      end
      methods.sort
   end
   def getMethod(cls)
      cls_int = veval (cls)
      methods = cls_int.methods
      if((cls_int.is_a? Class) and ( cls != "Object"))
         methods -= cls_int.superclass.methods
         #methods -= @module_int.methods
      elsif( cls != "Object")
         methods -= Object.methods
      end
      methods.sort
   end
   def getInstanceMethod(cls)
      cls_int = veval (cls)
      methods = cls_int.instance_methods
      if((cls_int.is_a? Class) and ( cls != "Object"))
        methods -= @module_int.methods
      elsif( cls != "Object")
         methods -= Object.instance_methods
      end
      methods.sort
   end
   def veval( str )
      begin
         result = Object.const_get(str)
      rescue NameError
         result = eval ("Qt2::" + str)

      rescue TypeError
         result = eval(str)

     rescue LoadError
     print "LoadError!: #{$!} \n"
      end
      result
   end

end


