#!/usr/bin/perl -w
#
# $Id: EventCondition.pm,v 1.1 2002/04/03 12:43:40 fpmip Exp $
#
# EventCondition : a way of specifying events
#
# Author : Tycho Fruru <tycho@fruru.com>
#
# Copyright (C) 2001 Tycho Fruru <tycho@fruru.com>
# Copyright (C) 2001 Conostix S.A. Luxembourg - Tycho Fruru <tycho@conostix.com>
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by the
# Free Software Foundation; either version 2 of the License, or (at your
# option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
# for more details.
#
package IPFC::EventCondition;

use strict;
use warnings;

use Storable;

our @ISA = ("Exporter");
our @EXPORT = ("attr","const","plus","minus","infix");

sub new($) {
	my $proto = shift;
	my $class = ref($proto) || $proto;
	my $var = shift;
	my $self = {};
	if (defined($var)) {
		$self = $var
	} 
	bless ($self,$class);
	return $self;
}

sub clone() {
	my $self = shift;
	my $class = ref($self);
	my $new;
	
	$new = Storable::dclone($self);
	bless ($new,$class);
	return $new;
}

sub attr($) {
	my $attr = shift;
	
	my $result = { 'op' => 'attribute',
		       'attribute' => $attr } ;

	bless ($result,"IPFC::EventCondition");
	return $result;	
}

sub const($) {
	my $value = shift;

	my $result = { 'op' => 'constant',
		       'constant' => $value } ;
	
	bless ($result,"IPFC::EventCondition");
	return $result;
}

sub pre($$$) {
	my $op = shift;
	my $term1 = shift;
	my $term2 = shift;
	
	my $result = { 'op' => $op,
		       't1' => $term1,
		       't2' => $term2 } ;
		       
	bless ($result,ref($term1));
	return $result;
}

sub infix($$$) {
	my $term1 = shift;
	my $op = shift;
	my $term2 = shift;
	
	return pre($op,$term1,$term2);
}

sub plus($$) {
	my $term1 = shift;
	my $term2 = shift;
	
	return pre('+',$term1,$term2);
}

sub minus($$) {
	my $term1 = shift;
	my $term2 = shift;
	
	return pre('-',$term1,$term2);
}


sub evaluate($) {
	my $self = shift;
	my $event = shift;
	
	if (! $event->isa("IPFC::Event")) {
		die "IPFC::EventCondition::evaluate called without IPFC::Event parameter !";
	}

	if ($self->{'op'} eq 'constant') {
		return $self->{'constant'};
	} elsif ($self->{'op'} eq 'attribute') {
		my $name = $self->{'attribute'};
		return $event->{$name}->[0]; # we do not handle multi-valued attributes right now (will do later)
	} elsif ($self->{'op'} eq '+') {
		return $self->{'t1'}->evaluate($event) +  $self->{'t2'}->evaluate($event);
	} elsif ($self->{'op'} eq '-') {
		return $self->{'t1'}->evaluate($event) -  $self->{'t2'}->evaluate($event);
	} elsif ($self->{'op'} eq '==') {
		return $self->{'t1'}->evaluate($event) eq $self->{'t2'}->evaluate($event);
	} elsif ($self->{'op'} eq '>') {
		return $self->{'t1'}->evaluate($event) >  $self->{'t2'}->evaluate($event);
	} elsif ($self->{'op'} eq '>=') {
		return $self->{'t1'}->evaluate($event) >= $self->{'t2'}->evaluate($event);
	} elsif ($self->{'op'} eq '<') {
		return $self->{'t1'}->evaluate($event) <  $self->{'t2'}->evaluate($event);
	} elsif ($self->{'op'} eq '<=') {
		return $self->{'t1'}->evaluate($event) <= $self->{'t2'}->evaluate($event);
	} elsif ($self->{'op'} eq '=~') {
		return $self->{'t1'}->evaluate($event) =~ $self->{'t2'}->evaluate($event);
	} else { die "this type of evaluation is not yet implemented"; }
	
}

return 1;
