#
# $Id: object.icn,v 1.2 2004-02-12 17:07:56 rparlett Exp $
#
# This file is in the public domain.
#
# Author: Robert Parlett (parlett@dial.pipex.com)
#

package lang

class Object()
   #
   # Clone the object.
   #
   method clone(seen)
      return lang::object_clone(self, seen)
   end

   #
   # Return a string representation of the oject.
   #
   method to_string(depth, seen)
      return lang::object_to_string(self, depth, seen)
   end

   #
   # Test equality of this object with another
   #
   method equals(other, seen)
      return lang::object_equals(self, other, seen)
   end

   #
   # Return a hash code for the object
   #
   method hash_code(depth, seen)
      return lang::object_hash_code(self, depth, seen)
   end

   #
   # Return the class name as a string, e.g. lang__Object.
   # This method is deprecated. Consider using method className().
   #
   method get_class_name()
      return lang::get_class_name(self)
   end

   #
   # Return the class instance number
   #
   method get_id()
      return lang::get_id(self)
   end

   #
   # Get the Class object for this object
   #
   method get_class()
      return lang::get_class(self)
   end

   #
   # Succeed if and only if this object is an instance of class with the
   # given name.
   # This method is deprecated. Consider using method instanceOf().
   #
   method is_instance(name)
      return lang::is_instance(self, name)
   end

   # UniLib annexation of 2017.

   # <p>
   # <[Generates the name of the current class followed by all classes
   #    that it inherits from.]>
   # </p>
   method Type()
      suspend lang::Type(self)
   end

   # <p>
   # Is this class a subclass of another one?
   # <[returns the class if it's an instance of <tt>superClassname</tt>]>
   # <[fails otherwise]>
   # </p>
   method instanceOf(superClassname) # class name to check as superclass
      return lang::instanceof(self, superClassname)
   end

   # <p>
   # <[returns the classname for the current class in package::class format]>
   # </p>
   method className()
      return lang::mapPackageInt2Ext(::classname(self))
   end

   # <p>
   # Invoke a class method by name.
   # <[returns the outcome of the invocation]>
   # <[fails if no method exists with that name]>
   # </p>
   method invoke(mName,    # Name of method to call
                 args[])   # Remaining arguments are arguments to call
      if hasMethod(mName) then {
         suspend (self.__m[mName]) ! ::push(args, self)
         }
   end

   #<p>
   #   Produce the value of the named field.  Fails if no such field.
   #   <[returns the value of the <tt>fName</tt> field]>
   #</p>
   method getField(fName)    # name of field
      if hasField(fName) then {
         return self[fName]
         }
   end

   #<p>
   #   Set the value of the named field.
   #   <[returns <tt>value</tt>]>
   #   <[fails if no field <tt>fName</tt>]>
   #</p>
   method setField(fName,   # name of field
                   value)   # value to set field to
      if hasField(fName) then {
         return .(self[fName] := value)
         }
   end

   #<p>
   #   Does this class have a specific field?
   #   <[returns <tt>fName</tt>]>
   #   <[fails if no field <tt>fName</tt>]>
   #</p>
   method hasField(fName)   # name of possible field
      return \fName == fieldNames()
   end

   #<p>
   #   <[generates the names of all fieldsmof an object]>
   #   This now depends on lang::generate_member_names procedure which is no
   #   longer dependent on the implementation details, but uses one of the
   #   Unicon functions membernames().
   #</p>
   method fieldNames()
      suspend lang::generate_member_names(self)
   end

   # <p>
   # What methods are available for this class?
   #    <[generates the names of all methods]>
   #    reverts "remove implementation dependency and instead use Unicon function for this
   #    information." since methodnames doesn't (yet) traverse superclasses to
   #    produce the names of methods.  (Revert back if methodnames fixed!)
   # </p>
   method genMethods()
#      suspend !::methodnames(self)
#     This all replaces the above line until methodnames is fixed:
      local mname

      every mname := key(self.__m) ? {
         suspend ("procedure" == type(self.__m[mname]), mname)
         }
   end

   # <p>
   # Does this class have a specific method?
   #    <[returns <tt>mName</tt>]>
   #    <[fails if no method <tt>mName</tt> exists]>
   # </p>
   method hasMethod(mName) # Method name to check for.
      return mName == genMethods()
   end
end
