module Origami::StandardObject

def self.included(receiver) #:nodoc:

:nodoc:
def self.included(receiver) #:nodoc:
    receiver.instance_variable_set(:@fields, Hash.new(DEFAULT_ATTRIBUTES))
    receiver.extend(ClassMethods)
end

def do_type_check #:nodoc:

:nodoc:
def do_type_check #:nodoc:
    self.class.fields.each_pair do |field, attributes|
        next if self[field].nil? or attributes[:Type].nil?
        begin
            field_value = self[field].solve
        rescue InvalidReferenceError
            STDERR.puts "Warning: in object #{self.class}, field `#{field}' is an invalid reference (#{self[field]})"
            next
        end
        types = attributes[:Type].is_a?(::Array) ? attributes[:Type] : [ attributes[:Type] ]
        unless types.any? {|type| not type.is_a?(Class) or field_value.is_a?(type.native_type)}
            STDERR.puts "Warning: in object #{self.class}, field `#{field}' has unexpected type #{field_value.class}"
        end
        if attributes.key?(:Assert) and not (attributes[:Assert] === field_value)
            STDERR.puts "Warning: assertion failed for field `#{field}' in object #{self.class}"
        end
    end
end

def pre_build #:nodoc:

:nodoc:
def pre_build #:nodoc:
    set_default_values
    do_type_check if Origami::OPTIONS[:enable_type_checking] == true
    super
end

def set_default_value(field) #:nodoc:

:nodoc:
def set_default_value(field) #:nodoc:
    if self.class.fields[field][:Default]
        self[field] = self.class.fields[field][:Default]
        self[field].pre_build
    end
end

def set_default_values #:nodoc:

:nodoc:
def set_default_values #:nodoc:
    self.class.required_fields.each do |field|
        set_default_value(field) unless self.key?(field)
    end
end

def version_required #:nodoc:

:nodoc:

Returns the version and level required by the current Object.
def version_required #:nodoc:
    max = [ "1.0", 0 ]
    self.each_key do |field|
        attributes = self.class.fields[field.value]
        if attributes.nil?
            STDERR.puts "Warning: object #{self.class} has undocumented field #{field.value}"
            next
        end
        version = attributes[:Version] || '1.0'
        level = attributes[:ExtensionLevel] || 0
        current = [ version, level ]
        max = [ max, current, self[field.value].version_required ].max
    end
    max
end