package MpmasMILPActivity;
use strict;
use warnings;
use Exporter;
use Storable qw(dclone);
use Data::Dumper;
use MpmasQLModelElementAbstract;
use CtUtilities qw(is_in_list is_in_string_list stub_in_list);

our @ISA = qw(MpmasQLModelElementAbstract);



##class variables
my $lazy_activity = 0;

sub defaultclass {"activity"};
sub list_of_default_fields { 
	
	my @array;
	if ($_[0]->is_multiperiod()) {
		#@array = qw(name unit type integ lbound ubound orow priority pseudo_down pseudo_up account type_of_payment quadratic);
		@array = qw(name unit type );
		
	}
	else { 
		#@array = qw(name unit type integ lbound ubound orow consfix marketfix landfix priority pseudo_down pseudo_up account type_of_payment quadratic);
		@array = qw(name unit type integ lbound ubound orow consfix marketfix landfix priority pseudo_down pseudo_up account type_of_payment quadratic);
	}
	return \@array;
}
sub list_of_attribute_fields{
	my @array;
	if ($_[0]->is_multiperiod()) {
		@array = qw(othermilp othermilp_subelements name description unit type integ lbound ubound orow empty priority pseudo_down pseudo_up LPColumn solution solution_pool grouping  thiscomp cptype sos sos_position sex account type_of_payment quadratic mperiod solution_to_script_pre_investment ubound_pre_investment);
	}
	else { 
		@array = qw(othermilp othermilp_subelements name description unit type integ lbound ubound orow consfix marketfix empty landfix xnproduct xnlink priority pseudo_down pseudo_up LPColumn solution solution_pool grouping labgrp thiscomp cptype sos sos_position sex account type_of_payment quadratic mperiod solution_to_script_pre_investment ubound_pre_investment);
	}
	
	return \@array;
}
sub list_of_attribute_stubs {
	my @array = qw(orow_);
	return \@array;
}

my %defaults = (
	name	=> "N/A",
	unit    => "N/A",
	integ	=> 0,
	quadratic	=> 0,
	lbound	=> 0,
	ubound  => 10**31,
	type 	=> "none",
	orow	=> 0,
	consfix	=> 0,
	marketfix	=> 0,
	landfix	=> 0,
	priority 	=> 1000,
	pseudo_down 	=> 0.01,
	pseudo_up	=> 0.01,
	cptype	=> 0,
	sos	=>	-1,
	sos_position	=> 0,
	account	=>	"not_specified",
	type_of_payment	=>	5,
	mperiod => 0
);
sub get_default_value {
	return $defaults{$_[1]};
}
sub set_default_value {
	$defaults{$_[1]} = $_[2] ;
}
##specific accessor classes
sub orow {
	my ($self,$year,$milpid) = @_;
	if (defined $year) {		
		return $self->{othermilp}->{$milpid}->{"orow_$year"}  if (defined $milpid and $milpid != $self->standard_milp() and defined $self->{othermilp}->{$milpid}->{"orow_$year"});
		return $self->{orow_}->{$year};
	}
	else {
		return $self->{othermilp}->{$milpid}->{orow} if (defined $milpid and $milpid != $self->standard_milp() and defined $self->{othermilp}->{$milpid}->{orow});
		return (exists ($self->{orow}) && defined( $self->{orow}) )? $self->{orow} : $self->get_default_value("orow") ;
	}
}
sub discounted_orow {
	my ($self, $year, $milpid, $dRate) = @_;
	use warnings FATAL => qw/uninitialized numeric/;
	return $self->orow($year, $milpid) / (1+ $dRate) ** $self->attr("mperiod");
}



sub coeff {
	my ($self,$constraint,$milpid) = @_;
	return $self->{othermilp}->{$milpid}->{$constraint} if (defined $milpid and $milpid != $self->standard_milp() and defined $self->{othermilp}->{$milpid}->{$constraint});
	return $self->{others}->{$constraint};
}
sub set_coeff {
	my ($self,$constraint,$value, $milpid) = @_;
	if (defined $milpid and $milpid != $self->standard_milp() and defined $self->{othermilp}->{$milpid}->{$constraint}) {
	    $self->{othermilp}->{$milpid}->{$constraint} = $value ;
	}
	else {
	    $self->{others}->{$constraint} = $value;
	}
}
sub coefficients {
	return keys %{$_[0]->{others}};
}
sub get_pooled_solution {
	return $_[0]->{solution_pool}[$_[1] ];
}
sub set_pooled_solution {
	$_[0]->{solution_pool}[$_[1] ] = $_[2];
}
sub clear_pooled_solutions {
	$_[0]->{solution_pool} = undef ;
}


sub lp_column {
	return $_[0]->{LPColumn};
}
sub set_lp_column {
	$_[0]->{LPColumn} = $_[1];
}
sub empty {
      return $_[0]->{empty};
}
sub set_empty {
      $_[0]->{empty} = $_[1];
}

#Probably obsolete, remnant from earliest Multiperiod implementation
sub multiperiodMIP_set_correct_period {
	my ($self) = @_;
	for my $k (keys %{$self->{others} }) {
		unless ( $k =~ /:\d+$/) {
			my $fullname = $k .":".$self->attr("mperiod");
			$self->{others}->{$fullname} = $self->{others}->{$k};
			delete ($self->{others}->{$k}); 
		}
	}
	for my $k (keys %{$self->{subelements}->{mpmas_insert_value}}) {
		next if (is_in_string_list($k,$self->list_of_attribute_fields));
		unless ( $k =~ /:\d+$/) {
			my $fullname = $k.":".$self->attr("mperiod") ;
			$self->{subelements}->{mpmas_insert_value}->{$fullname} = $self->{subelements}->{mpmas_insert_value}->{$k};
			delete ($self->{subelements}->{mpmas_insert_value}->{$k}); 
		}
	}
	for my $k (keys %{$self->{subelements}->{exchange}}) {
		next if (is_in_string_list($k,$self->list_of_attribute_fields));
		
		unless ( $k =~ /:\d+/) {
			$k =~ /(\w+)_(\d+)$/;
			my $fullname = $1.":".$self->attr("mperiod")."_".$2 ;
			$self->{subelements}->{exchange}->{$fullname} = $self->{subelements}->{exchange}->{$k};
			delete ($self->{subelements}->{exchange}->{$k}); 
		}
	}
}
sub lazy_activity {
    return $lazy_activity;
}
sub be_lazy {
    $lazy_activity = 1 ;
}
sub dont_be_lazy {
    $lazy_activity = 0 ;
}
1;
