package Mud::Obj;
use strict;
use Mud::CoreTools;

=head1 Description

Mud::Obj is a module implementing the basic interface for
possibly-persistent objects.

As this class provides no data or method storage, you will 
probably want to use Mud::Obj::Attributed instead.

=head1 Methods

=cut

### creation/destruction #####################################

=item CM new()

Creates a new object. It is not automatically registered with
a storage.

=cut

sub new {
  my ($class) = @_;
  my $self = bless {}, $class;
  return $self;
}

=item IM register(TAG[, KEY])

Registers the object with the storage of the specified TAG, with the
specified access key hint.

Returns self for convenience.

=cut

sub register {
  my ($self, $tag, $key) = @_;
  my $store = Mud::Storage->storage($tag) or croak "Invalid storage tag: $tag";
  $store->object_register($self, $key);
  $self->{_storage} = $store;
  return $self;
}

=item IM unregister()

Unregisters the object from its storage.

=cut

sub unregister {
  my ($self) = @_;
  $self->{_storage}->object_unregister($self);
  delete $self->{_storage};
  return;
}

=item IM storage()

Returns the storage object.

=cut

sub storage {
  my ($self) = @_;
  return $self->{_storage};
}

=item IM po_proxy()

Returns a proxy for this object.

=cut

sub po_proxy {
  my ($self) = @_;
  my $st = $self->storage;
  $st or croak "Object " . $self->identity_text . " has no storage, therefore cannot have a proxy.";
  return $st->obj($st->object_get_key($self));
}

=item IM identity_text()

Returns a string describing this object.

=cut

sub identity_text {
  my ($self) = @_;
  my $st = $self->storage;
  return "<" . ($st ? ref($self) . " " . $st->storage_tag . " " . $st->object_get_key($self) : $self) . ">";
}


### internal utility methods ############################

=item IM changed()

Should only be called from a subclass; informs the object's
store that the object has been changed.

=cut

sub changed {
  my ($self) = @_;
  ($self->{_storage} or return)->object_changed($self);
  return;
}

### internal storage interface ###########################

# FIXME: document this

# Note that this preserves the object's blessing

# IM
sub storage_get_data {
  my ($self, $type) = @_;
  my $data = Mud::Freezer->freeze($self);
  return bless \$data, ref $self;
}

# IM
sub storage_create_from_data {
  my ($data, $type) = @_;
  return bless Mud::Freezer->thaw($$data), ref $data;
}

# IM
sub storage_set_cookie {
  my ($self, $cookie) = @_;
  $self->{_storage_cookie} = $cookie;
  return;
}

# IM
sub storage_get_cookie {
  my ($self) = @_;
  return $self->{_storage_cookie};
}

1;
__END__
