-- Interface with a TWO_WAY_SORTED_SET of LINK instances used in the Design Room.


class
	LINKS

creation
	make

feature -- Access

  iter_link_start is
  do
    links.start
  end

  iter_link_next is
  do
    links.forth
  end

  iter_link_done : BOOLEAN is
  do
    Result := links.after
  end

  iter_link_lhs : DESIGN_PORTAL is
  do
    Result := links.item.a
  end

  iter_link_rhs : DESIGN_PORTAL is
  do
    Result := links.item.b
  end

  add_link ( a, b :DESIGN_PORTAL ) : INTEGER is
  require
    not_already_linked: not is_already_linked (a)
    not_already_linked: not is_already_linked (b)
  local
    lk : LINK
    link_id : INTEGER
  do
    link_id := get_next_free_link_id
    create lk.make( a, b, link_id )
    links.extend ( lk )
    Result := link_id
  ensure
    has_a:  is_already_linked( a )
    has_b:  is_already_linked( b )
    linked: a = get_partner( b )
    id_ok:  Result = get_link_that_has( a ).id
  end

  drop_link( x : DESIGN_PORTAL ) is
  require
    already_linked: is_already_linked( x )
  do
    links.prune ( get_link_that_has( x ) )
  ensure
    not_linked: not is_already_linked( x )	
  end
		
  get_partner( x : DESIGN_PORTAL ) : DESIGN_PORTAL is
  require
    already_linked: is_already_linked( x )
  do
    Result := get_link_that_has( x ).get_other( x )
  ensure
    something: Result /= Void
    ok1: Result /= x
    matches: get_link_that_has( x ) = get_link_that_has( Result )
  end

  get_id( x : DESIGN_PORTAL ) : INTEGER is
  require
    already_linked: is_already_linked( x )
  do
    Result := get_link_that_has( x ).id
  end

  is_already_linked( x : DESIGN_PORTAL ) : BOOLEAN is
  -- we don't use get_link_that_has here to avoid infinite recursion.
  do
    from links.start until links.after or Result = TRUE loop
    if links.item.has_piece( x ) then	
      Result := TRUE      		
    end
    links.forth
  end
  ensure
    good_result: Result implies links.item /= Void
  end

feature{NONE}

  make is
  do
    create links.make
  end

  links : TWO_WAY_SORTED_SET [ LINK ]

  get_link_that_has( x : DESIGN_PORTAL ) : LINK is
  require
    is_already_linked: is_already_linked( x )
  do
    from links.start until links.after or Result /= Void loop
      if links.item.has_piece( x ) then
        Result := links.item
      end
      links.forth
    end
  ensure
    piece_found: Result.has_piece( x )
  end

  get_next_free_link_id : INTEGER is
  do
    Result := 1
    from links.start until links.after or Result /= links.item.id loop
      Result := Result + 1
      links.forth
    end
  end

end -- class LINKS

