+util = require 'util'
 nextId = 0
 
 module.exports = (makeId = -> nextId++) ->
-  behaviorFinder = (obj) ->
-    (info) ->
-      (info = {looseMatch: info}) if typeof info is 'string'
-
-      return undefined unless typeof info is 'object'
-
-      {looseMatch, name, id} = info
-
-      lookupBehavior = obj.db.lookupBehavior.bind obj
-
-      return o if id and o = obj.db.o[id]
-      return o if name and o = obj.db.names[name]
-      return o if o = lookupBehavior looseMatch
-      return undefined
-
-      return  (id and obj.db.o[id]) or
-              (name and obj.db.names[name]) or
-              (lookupBehavior looseMatch)
-
   class Referent
     constructor: (@db) ->
       @id = makeId()
       @behaviors = {}
+      @as = {}
+
       @db.registerRef this
 
-    addBehavior: (behavior) ->
-      self = {}
+    addBehavior: (behavior, name = behavior.name) ->
+      if util.isFunction name
+        name = name()
+
+      self = euclidic: this
       Object.setPrototypeOf self, behavior
       @behaviors[behavior.id] = self
+
+      if name
+        @as[behavior.name] = self
+
+      behavior.as.behavior.init self
+
+    delBehavior: (behavior) -> delete @behaviors[behavior.id]
 
     withBehavior: (behavior, methodName, args) ->
       self = @behaviors[behavior.id]

      if name
        @addName o, name

    addName: (o, name) ->
      ns = @names
      [path..., name] = name.split '.'


      for part in path
        ns = (ns[part] or= {})

      ns[name] = o

    util:
      findOrCreate: ({name}) ->
        if not name
          throw new Error 'Can not look for empty (or falsy) name'

        @names[name] or @create arguments[0]

  return {
      Referent: Referent


    relate: (subject, object, @params = {}) ->
      new Relation
        @rel = this
        @sub = subject
        @obj = object

    toString: ->
      "#{@subj.name} #{} #{@obj.name}"


  class Db
    constructor: (@namespace, @prefix = '$') ->
      @names = {}
      @o = {}
      @rel =
        bySub: {}
        byRel: {}
        byObj: {}
      @initDb()

    registerRef: (ref) ->
      @o[ref.id] = ref

    registerRel: (rel) ->
      @rel.bySub[rel.sub.id] = rel
      @rel.byRel[rel.rel.id] = rel
      @rel.byObj[rel.obj.id] = rel

    initDb: ->
      @create 'sys'
      @create 'root'
      @create 'behavior', Behavior
      @create 'relation', Relation

    relate: (subj, rel, obj) ->
      rel.relate subj, obj
