package Bot::BasicBot::Pluggable::Module::ObjectSchema;

use strict;
use Parse::RecDescent;

sub new {
    my $class = shift;
    my $self = $class->SUPER::new(@_);
    return $self;
}

# instantiate, set name, set property, has-a and has-many delete, destroy
    
our %values = (
    has_a => 'a',
    has_many => 'several',
    might_have => 'possible',
    ); 

sub has_some {
    my ($self,$v) = @_;
    my %vs = reverse %values;
    return $vs{$v}; 
}

sub parser {
    my ($self,$commands) = @_;
    my $parser = Parse::RecDescent->new(q~
        start   : ( Command | Query ) /\??\Z/
            { $return = [ grep(!ref($_), @{$item[1]}) ] }
        Command : "create"  { $return = [ @item[1..$#item] ] } | 
		  "add" { $return = [ @item[1..$#item] ] } |
		  "help" { $return = [ @item[1,2,4] ] } |
		  "set" {   $return = [ @item[1,2,4,6] ] } 
	Query   : "fetch" { $return = [ @item[1..$#item] ] }
    ~);
    # e.g. 'create User'
    # 'add first to User'
    # 'set name to User on User'
    #  
    return $parser;
}

sub init {
    my $self = shift;
    $self->{parser} = $self->parser();
}

sub said {
    my ($self,$said,$prio) = @_;
    return undef unless $said->{address} and $prio eq 1;
    my $who = $said->{who};
    $self->{$who}->{history} ||= [];
    push @{ $self->{$who}->{history} }, $said;
    $self->{current} = $said;
    # ...
    my $args = $self->{parser}->start( $said->{body} );
    my $call = shift @$args;
    if ($self->can($call)) {
	$self->$call(@$args);
    }
    else {
	# incomprehension
    }
}

sub set {
    my ($self,$key,$value,$classname) = @_;
    my $who = $self->{current}->{who};
    # set Key to Value on Class

    my $object = $self->{objects}->{$classname};
}

sub create {
    my ($self,@args) = @_;
    my $who = $self->{current}->{who};
    my $class = $args[0];
    my $object = Indyvoter::Store->create('Class',{name =>$class});
    $self->{objects} ||= {};
    $self->{objects}->{$class} = $object;
    $self->{$who}->{current} = $object; 
}

sub add {
    my ($self,@args) = @_;
    my $who = $self->{current}->{who};
    my $value = shift @args;
    my $p = shift @args;
    my $prop = Indyvoter::Store->create('Property',{name => $p}); 
    my $objects = $self->{objects} || {};
    $objects->{$p} = $prop;
    my $classname = $args[1];
    if (not $objects->{$classname}) {
	$objects->{$classname} = Indyvoter::Store->search('Class',name => $classname);
    } 
    my $has = $self->has_some($value);
    $objects->{$classname}->$has($p,ref($prop));
    $self->{objects} = $objects;
}

1;


