require 'superhash/superhash'

class AttributedNode

attr_reader :attributes, :parents, :children

# creates a node and gives it a first parent
def initialize(parent = nil)
  @attributes = SuperHash.new(parent && parent.attributes)
  @parents = parent ? [parent] : []
  @children = []
end

# adds more parents, which will also contribute attributes
def add_parent(parent)
  unless @parents.include? parent
    @parents << parent
    @attributes.parents << parent.attributes
  end
  self
end
protected :add_parent

def add_child(child)
  @children << child
  child.add_parent(self)
  self
end

end

root = AttributedNode.new

root.attributes[:type]        = :top_window
root.attributes[:name]        = "Feature request window"
root.attributes[:bg_color]    = "gray"
root.attributes[:font_face]   = "Courier"
root.attributes[:font_size]   = 10

user_field = AttributedNode.new

root.add_child(user_field)
user_field.attributes[:type]      = :text_box
user_field.attributes[:name]      = "Username box"
user_field.attributes[:label]     = "Name:"

feature_field = AttributedNode.new

root.add_child(feature_field)
feature_field.attributes[:type]      = :text_box
feature_field.attributes[:name]      = "Feature description box"
feature_field.attributes[:bg_color]  = "white"
feature_field.attributes[:label]     = "Please enter your request below:"
feature_field.attributes[:font_face] = "Times"
feature_field.attributes[:font_size] = 12

p user_field.attributes[:bg_color] # ==> "gray" p feature_field.attributes[:bg_color] # ==> "white"

p user_field.attributes[:font_size] # ==> 10 p feature_field.attributes[:font_size] # ==> 12

form_entry = AttributedNode.new

form_entry.attributes[:default_contents]    = "enter text here"
form_entry.attributes[:reject_condition]    = /[^\w,.;:?!]/

form_entry.add_child(user_field)
user_field.attributes[:default_contents]    = "fred"

form_entry.add_child(feature_field)
feature_field.attributes[:reject_condition] = /more like Microsoft/

p feature_field p feature_field.attributes[:default_contents] # ==> "enter text here"