package MpmasDemographySet;

use strict;
use warnings;
use Exporter;
use Storable qw(dclone);
use Data::Dumper;
use SimpleObjectRegistry;
use MpmasInputBlock;
use SimpleObject;
use IndexedTable;
use CtUtilities qw(get_unique queryhash extqueryhash strip_sql);
use MpmasDemography;

our @ISA = qw(MpmasInputfileSet);

sub class_of_files{
	return "MpmasDemography";
 }
sub filename {
	return "DemographySet";
}
sub determine_files {
	my $self = shift;
	for my $p (0..$self->config_entry("POPULATIONS") - 1) {
		my $fname = sprintf("%01d", $p);
		$self->add_file($p,$fname);
	}

}

sub prepare_shared_files {
	my $self = shift;

	#Load and transform required tables
	my $dbh = $self->get_dbh;
	my $demotab;
	if ( $self->config_entry("DEMOGRAPHY_MODEL") == 0) {
		if (defined $self->config_entry("HOUSEHOLD_DYNAMICS")) {
			$demotab = $self->config_entry("HOUSEHOLD_DYNAMICS")->transform($dbh , 3);
		}
		else {
			print STDERR "\nInfo: HOUSEHOLD_DYNAMICS [MPMAS TABLES] table not provided. Using minimal default values\n";

			$demotab = IndexedTable->create_from_array([[0	, "worker",	100 ,"farm", 1, 0, 0, 0, 0,  0, 1, 0, 0 ]], 3, "HOUSEHOLD_DYNAMICS" ,[("pop","career", "upperage", "labgrp", "labprov", "mortality", "fertility", "p_marriage","p_leave", "p_retire", "priority_hh", "mincons", "oppWage")]);
		}
	
	}
	elsif ( $self->config_entry("DEMOGRAPHY_MODEL") >= 1) {
	    print STDERR "Error: Missing HOUSEHOLD_DYNAMICS [MPMAS TABLES]\n" and exit(1) unless (defined $self->config_entry("HOUSEHOLD_DYNAMICS"));
		$demotab = $self->config_entry("HOUSEHOLD_DYNAMICS")->transform($dbh , 3);

	    print STDERR "Error: Missing HOUSEHOLD_SWITCHING [MPMAS TABLES]\n" and exit(1) unless (defined $self->config_entry("HOUSEHOLD_SWITCHING"));
	    
	    my $career_switching = $self->config_entry("HOUSEHOLD_SWITCHING")->transform($dbh , 4);
	    my $succession_control = $self->config_entry("SUCCESSION_CONTROL")->transform($dbh , 2) if (defined $self->config_entry("SUCCESSION_CONTROL"));
	    my $invhorizon = $self->config_entry("INVESTMENT_HORIZON")->transform($dbh , 2) if (defined $self->config_entry("INVESTMENT_HORIZON"));
	    my $invhorizon_constraints = $self->config_entry("INVESTMENT_HORIZON_CONSTRAINTS")->transform($dbh , 2) if (defined $self->config_entry("INVESTMENT_HORIZON_CONSTRAINTS"));
	    my $extraIncBalance = $self->config_entry("SUC_INCOME_BALANCE")->transform($dbh , 2) if (defined $self->config_entry("SUC_INCOME_BALANCE"));
	    my $migrationInfo = $self->config_entry("MIGRATION")->transform($dbh , 2) if (defined $self->config_entry("MIGRATION"));


	    $self->set_config_entry("CONVERTED_HOUSEHOLD_SWITCHING", $career_switching);
	    $self->set_config_entry("CONVERTED_SUCCESSION_CONTROL", $succession_control);
	    $self->set_config_entry("CONVERTED_INVESTMENT_HORIZON", $invhorizon);
	    $self->set_config_entry("CONVERTED_INVESTMENT_HORIZON_CONSTRAINTS", $invhorizon_constraints);
	    $self->set_config_entry("CONVERTED_SUC_INCOME_BALANCE", $extraIncBalance);
	    $self->set_config_entry("CONVERTED_MIGRATION", $migrationInfo);
		if ( $self->config_entry("DEMOGRAPHY_MODEL") >= 2) {
			my $career_switching2 ;
			$career_switching2  = $self->config_entry("HOUSEHOLD_SWITCHING_UDEF")->transform($dbh , 4) if (defined $self->config_entry("HOUSEHOLD_SWITCHING_UDEF"));
			$self->set_config_entry("CONVERTED_HOUSEHOLD_SWITCHING_UDEF", $career_switching2) ;	
			my $career_info;
			$career_info = $self->config_entry("HOUSEHOLD_CAREER_INFO")->transform($dbh , 3) if (defined $self->config_entry("HOUSEHOLD_CAREER_INFO"));
			$self->set_config_entry("CONVERTED_HOUSEHOLD_CAREER_INFO", $career_info) ;	

		}
	}


	#Labour groups and ObjectIDs for Careers
	#find different careers
	my @dtmp;
	for my $r3 ($demotab->query([],0 )) {
	    push @dtmp, $demotab->query([$r3],0) ;
	}
	my @careers = get_unique(@dtmp);
	
	@careers = sort {$a cmp $b} @careers;
	#distribute object ids
	my $carcnt = 1;
	my $CAREERS;
	for my $j (@careers){
		$CAREERS->{$j} = $self->config_entry("SPECOBJS")->[7] + $carcnt;
		$carcnt += 1;
	}
	$self->set_config_entry("CAREERS",$CAREERS);

	# find all different labourgroups
	my %ltmp;

	for my $r3 ($demotab->query([],0)) {
	      for my $r4 ($demotab->query([$r3],0)) {
			  for my $r5 ($demotab->query([$r3,$r4],0)) {
				  $ltmp{ $demotab->query([$r3,$r4, $r5],4) } = 1;
			  }
	      }
	}

	my $LBGRP;
	my @ltmp2 = sort {$a cmp $b } keys %ltmp;


	
	if ($self->config_entry("MULTIPERIOD") ) {
		my $dcnt = 0;
		foreach my $h (@ltmp2 ) {
			 $LBGRP->{$h}->{lid} = $dcnt++;
		}
	}
	else {

		my $labcnt = 0;
		my $through = 0;
		my $dcnt = 0;
	
		do {
			my $curRow = $self->config_entry("FIRSTLAB") +$dcnt;
			my $curCon = $self->constraint_at_row($curRow);
			if (lc($curCon->type) eq "maslab") {
				print STDERR "Error: Constraint ".$curCon->id." is of type 'MASlab', but no labgrp specified!\n"  and exit(1) unless (defined $curCon->get_attribute("labgrp") );
				my $h = $curCon->get_attribute("labgrp") ;
				
				$LBGRP->{$h}->{lid} = $dcnt;
				$dcnt += 1;	

				
			}
			else {
				print STDERR "Error: Number of Labour endowment constraints in Matrix is smaller than the number of labor groups used in HOUSEHOLD_DYNAMICS\n
				Did you forget to specify constraints of type 'maslab'?\nOr have typos in HOUSEHOLD_DYNAMICS?\n" unless ($dcnt >= $#ltmp2 + 1);
				$through = 1;
			}
		} until $through;	
	}
	
	$self->set_config_entry("LABGRPS", $LBGRP);
	$self->set_config_entry("CONVERTED_DEMOTAB", $demotab);
	$self->set_config_entry("LBGcount", $#ltmp2 +1);


	if ( $self->config_entry("MULTIPERIOD") == 0 and !MpmasMILPActivity->has_coeffWithConstraints()
				and (defined $self->config_entry("INCOME_BALANCE_ROW") and $self->config_entry("INCOME_BALANCE_ROW") ne "-1" and $self->config_entry("INCOME_BALANCE_ROW") ne "0" ) 
					)
				{

		my $icrow = $self->config_entry("INCOME_BALANCE_ROW");
	    my $dao = $self->constraint($icrow);
		unless (defined $dao) {
			print STDERR "Error for INCOME_BALANCE_ROW: Constraint ". $icrow ."  has not been defined in the model\n" and exit(1);
		}
		
		if (defined $icrow and $icrow ne "-1" and $icrow ne "0" ) {
			
			for my $i ( $self->activities) {
				$i->set_coeff($icrow, 0) unless (defined $i->coeff($icrow)) ;
				
			}
			

		}
	}
}	

sub prepare_special_files {
	my $self = shift;
	for my $f ($self->files) {
		#$f->prepare_special($self->{DEMOHASH}, $self->{LBGcount},$self->{HHNutrients});
		$f->prepare_special();
	}
}
