'''
### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###
                   308-304 - Object-Oriented Software Design
                                 ASSIGNMENT  1

   CData.py ---
      class CellData implementation.

   last modified: 01/24/02
                       ===============================
                             Copyright (c)  2002
                            Jean-Sébastien BOLDUC
                             (jseb@cs.mcgill.ca)

                        McGill University  (Montréal)
                       ===============================

### ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ###
'''

import types

class CellData:
  '''
  Encapsulated Integer data.
  '''
  # __validTypes is a private class attribute that describes which types can be
  # stored in a CellData object (useful for future prototypes). An object x can
  # be stored in a CellData object if:
  #       type(x) == t        for a type t in __validTypes,
  #   or
  #       x.__class__ == c    for a class c in __validTypes.
  # Note that the latter wouldn't work in a language such as C++, where classes
  # are not "first class" objects...
  __validTypes = (types.IntType,)

  ### -------------------------------------------------------------  API -- ###

  def __init__(self, value = 0):
    ''' value:Integer ->    --  CellData constructor.

    A TypeError is raised on bad argument.
    '''
    # Explicitly declare private variable to hold data
    self.__data = None

    self.setValue(value)

  def getValue(self):
    ''' -> :Integer

    Return the object's (Integer) value.
    '''
    return self.__data # (or a copy thereof)

  def setValue(self, value = 0):
    ''' value:Integer ->

    Set the object's (Integer) value.
    A TypeError is raised on bad argument.
    '''
    # Validate argument:
    if not self.__validateData(value):
      raise TypeError, 'illegal type for value'
    # Store the value (or a copy) in private variable __data
    self.__data = value

  def __str__(self):
    ''' -> :String

    Return the string representation of the object value (Integer).
    '''
    return str(self.__data)

  ### -------------------------------------------------  PRIVATE METHODS -- ###

  def __validateData(self, value):
    ''' value: -> :Boolean

    Return true if value's type complies with those specified by the class
    variable __validTypes; false otherwise. This goes beyond the first
    protoype, where only Integers are accepted.
    '''
    try:                   # Assume value is an object...
      # Incomplete, as will reject an object that is an instance of a subclass
      # of a valid class (no support for inheritance).
      if value.__class__ in CellData.__validTypes:
        return 1
    except AttributeError: # ...no, it was not.
      if type(value) in CellData.__validTypes:
        return 1
    return 0 # all failed.


