package MpmasMarket;

use strict;
use warnings;
use Exporter;
use Storable qw(dclone);
use Data::Dumper;
use MpmasInputfile;
use MpmasInputBlock;
use MpmasInputBlockImmediate;
use CtUtilities qw(is_in_list);
our @ISA = qw(MpmasInputfile);

sub filename {
	return "Market".$_[0]->file_suffix;
}


sub prepare_special {
	my $self = shift;	
	my $NumCol = $self->milpinfo("NumCol");
	my $simp = $self->config_entry("NYEARS");
	$simp += (1 + $self->config_entry("ADDITIONAL_PRICE_PERIODS")) if ($self->config_entry("MULTIPERIOD") > 0);
	my $simpinit = $simp + 1;
	my $NumFuture = 0;
	my $NumConsumptionGoods = 0;
	my $NumOtherGoods = 0;
	my $NumCprod = 0;
	my %CPActivities;
	my $NumMarketGoods = 0;
	my $firstFuture;

	my $thismarket;
	my $priceScenario;
	if ( $self->argument =~ /^(\d+)_(.*)$/) {
    	$thismarket	 = $1;  
	    $priceScenario = $2;
    }
    else {
        $thismarket	 = $self->argument();
    }
	
	
	my @years = ($self->config_entry("STARTYEAR")..$self->config_entry("STARTYEAR") + $simp - 1);
	
	if ($self->config_entry("MULTIPERIOD") == 0) {
		#count number of market goods
		for my $x (@{$self->sorted_activity_objects}){

			$NumOtherGoods += 1 if (is_in_list(lc($x->attr("type")),  [("massell","massellkind", "masbuy")]));
			$NumConsumptionGoods += 1 if(is_in_list(lc($x->attr("type")),  [("masfoodbuy","masfoodconsume")]));
		}
		$NumMarketGoods = $NumOtherGoods + $NumConsumptionGoods;
		#identify activities with changing production costs
		
		for my $x (@{$self->sorted_activity_objects}){

			next if (is_in_list(lc($x->attr("type")),  [("massell","massellkind", "masbuy", "masfoodbuy","masfoodconsume", "masfuture")]));
			my %listofcp;
			for my $py (@years) {
				if (defined $x->orow($py, sprintf("1%01d", $thismarket)) ) {
					$listofcp{$py} = $x->orow($py, sprintf("1%01d", $thismarket));
				}
				
			}
			if (keys %listofcp) {
				$CPActivities{$x->id}  = \%listofcp;
			}

		}
		$NumCprod = keys %CPActivities;

		#count number of future selling activities
		
		for my $x (@{$self->sorted_activity_objects}){

			 if (lc($x->attr("type")) eq "masfuture") {
				 $NumFuture += 1;
				$firstFuture = $x->lp_column() unless (defined $firstFuture);
			}
		}
	}
	
	
	# Prices for Selling Activities
	my $pricehead= MpmasInputBlock->new(100,20);
	if ($self->config_entry("PERIODS_PER_YEAR") > 1) {
		$pricehead->add_comment_row("","Activity","","Initial Expectation", ( 0 .. $simp -1)  );
	}
	else {
		$pricehead->add_comment_row("","Activity","","Initial Expectation", @years);
	}
	$self->add_block($pricehead);
	

	my $pricetab = MpmasInputBlock->new(2, 30);
	
	if ($self->config_entry("MULTIPERIOD") == 0) {
		for my $j (0..$NumMarketGoods -1 ) {
			my $k = $self->activity( $self->sorted_activities($j) );	
			my @row = ("",$k->attr("name"),"", $k->orow(undef, sprintf("1%01d", $thismarket)) );
			for my $l (@years){
				my $y = $k->orow($l, sprintf("1%01d", $thismarket)); 
				if (not defined $y) {
					print "Warning: missing price entry $l for ".$k->attr("name")." !\nSet to Initial Value for now!\n" ;
					$y = $k->orow(undef , sprintf("1%01d", $thismarket));
				}
				push @row, $y;
			}
			$pricetab->add_row(@row);
		}
	}
	elsif ($self->config_entry("MULTIPERIOD") > 0) {
		
		if ($self->config_entry("PERIODS_PER_YEAR") == 1) {

			my $priceData;
			if (defined $priceScenario) {
			    $priceData = $self->config_entry("CONVERTED_PRICES")->get_subtable($priceScenario);
			}
			else {
        	    $priceData = $self->config_entry("CONVERTED_PRICES");
			}
			
			my $priceExpectationData = $self->config_entry("CONVERTED_PRICE_EXPECTATIONS");
			my $itemIds = $self->config_entry("PRICE_ITEM_LOOKUP");
			$NumMarketGoods = scalar @{$self->config_entry("PRICE_ITEMS_SORTED")};
			
					
			for my $item (@{$self->config_entry("PRICE_ITEMS_SORTED")}) {
				my @row = ($item, $itemIds->{$item},"");
				my $inExp;
				if (defined $priceExpectationData) {
					$inExp = $priceExpectationData->query([$item, $thismarket], 3) ;
				}
				$inExp = $priceData->query([$item, $thismarket, $self->config_entry("STARTYEAR")],4) unless (defined $inExp);
				push @row, $inExp;
				my $prev;
				for my $l (@years){
					my $y = $priceData->query([$item, $thismarket, $l], 4); 
					if (not defined $y and defined $prev) {
						print STDERR "Warning: missing price entry $l for $item !\nSet previous price for now!\n" ;
						$y = $prev;
					}
					elsif (not defined $y ) {
						print STDERR "Error: missing price entry $l for $item !\n" ;
						exit(1);
					}
					$prev = $y;
					push @row, $y;
				}
				$pricetab->add_row(@row);
			}
			
		}
		elsif ($self->config_entry("PERIODS_PER_YEAR") > 1) {

			my $priceData = $self->config_entry("CONVERTED_PRICES_PERIODS");
			my $priceExpectationData = $self->config_entry("CONVERTED_PRICE_EXPECTATIONS");
			my $itemIds = $self->config_entry("PRICE_ITEM_LOOKUP");
			$NumMarketGoods = scalar @{$self->config_entry("PRICE_ITEMS_SORTED")};
			
					
			for my $item (@{$self->config_entry("PRICE_ITEMS_SORTED")}) {
				my @row = ($item, $itemIds->{$item},"");
				my $inExp;
				if (defined $priceExpectationData) {
					$inExp = $priceExpectationData->query([$item, $thismarket], 3) ;
				}
				$inExp = $priceData->query([$item, $thismarket, $self->config_entry("STARTYEAR"), $self->config_entry("SEASON_OF_START_PERIOD")],5) unless (defined $inExp);
				push @row, $inExp;
				my $prev;
				
				my $cYear = $self->config_entry("STARTYEAR");
				my $cSeason = $self->config_entry("SEASON_OF_START_PERIOD");
				
				
				for my $l (0 .. ($simp -1) ) {
					
					
					my $y = $priceData->query([$item, $thismarket, $cYear, $cSeason], 5); 
					if (not defined $y and defined $prev) {
						print STDERR "Warning: missing price entry $cYear, $cSeason for $item !\nSet previous price for now!\n" ;
						$y = $prev;
					}
					elsif (not defined $y ) {
						print STDERR "Error: missing price entry $cYear, $cSeason for $item !\n" ;
						exit(1);
					}
					$prev = $y;
					push @row, $y;
					
					++$cSeason;
					if ($cSeason > $self->config_entry("PERIODS_PER_YEAR") ) {
						$cSeason = 1;
						$cYear++;
					}
				}
				$pricetab->add_row(@row);
			}
			
		}
		
	}
	$self->add_block($pricetab);

	my $markethead = MpmasInputBlock->new(2,10);
	$markethead->add_row("THE MARKET (PRICE) FILE");
	$markethead->add_row("1","SELLING AND BUYING PRICES (OBJECTIVE FUNCTION VALUES)");
	$markethead->add_comment_row("1.0","Number of simulation periods:", $simp);
	$markethead->add_row("1.1","Number of simulation periods + 1","$simpinit");
	$markethead->add_row("1.2","Number of market goods","$NumMarketGoods");
	$markethead->add_row("1.3","Endogenous prices for tradables (y/n)",0);
	$self->add_block($markethead);



	if ($self->config_entry("MULTIPERIOD") == 0) {
		###Changing Production Costs
		my $cprodhead = MpmasInputBlock->new(2,40);
		$cprodhead->add_row("");
		$cprodhead->add_row("1.4", "Changing Production Costs");
		$cprodhead->add_row("","Number of production activities with changing costs over time",$NumCprod);
		$self->add_block($cprodhead);

		my $cproddesc  = MpmasInputBlock->new(100,50);
		$cproddesc->add_row("");
		$cproddesc->add_row("","Activity","LPColumn","Type of Change", "Initial Expectation", @years);
		$self->add_block($cproddesc);

		my $cprodtab = MpmasInputBlock->new(2,60);
		if ($NumCprod > 0){
			my @sortedprodcost = sort { $self->activity($a)->lp_column() <=> $self->activity($b)->lp_column()   } keys %CPActivities; #sort by LP Column
			
			for my $i (@sortedprodcost){
				my $x = $self->activity($i);
				my $n = $x->attr("name");
				my @row = ("","$n",$x->lp_column,$x->attr("cptype")|| 0,1);
				for my $l (@years){
					my $y = $x->orow($l, sprintf("1%01d", $thismarket)); 
					my $cost =  (defined $y ) ? $y : $x->orow(undef, sprintf("1%01d", $thismarket));
					print STDERR "Trying to calculate changing production cost for $n, year $l, but no initial price (orow) has been defined, or initial price is zero.\n" and exit(1) unless ($x->orow(undef,sprintf("1%01d", $thismarket)) or $y == 0);
					my $cp_coeff = 0;
					$cp_coeff = $cost / $x->orow(undef, sprintf("1%01d", $thismarket)) unless ($cost == 0);
					push @row, sprintf("%.3f", $cp_coeff);
				}
				$cprodtab->add_row(@row);	
			}				
		}
		$cprodtab->add_empty_rows(2);
		$self->add_block($cprodtab);
	}
	#types of payments (cash, kind, food etc.) for perennials, penalties or extended consumption model

	my %typhash = (
	    masxc_inc_trans => 0,
	    massell => 1,
	    masbuy => 1,
	    massellkind => 2,
	    masfoodbuy => 3,
	    masfoodconsume => 4,
	    masfuture => 6,
	    maszero => 7,
	    masnutpenalty => 7,
	    mastppenalty => 7,
	    maspenalty => 7
	);
	my $numMilps = scalar @{ $self->milplist };
	my $kind ;
	if ($self->milpinfo("NumCol") > $self->config_entry("LIMIT_FOR_IMMEDIATE") / $numMilps ) {
		$kind = MpmasInputBlockImmediate->new(2,65, $self->get_skip_comments());
	}
	else {
		$kind= MpmasInputBlock->new(2,65);
	}
	
	$kind->add_comment_row("1.12","Payments to be considered in  income statement");
	$kind->add_row("","Number of entries", $self->number_of_activities);
	$kind->add_comment_row("","Type of payment (cash or kind)");
	$kind->add_comment_row("","0: other");
	$kind->add_comment_row("","1: earningsInCash");
	$kind->add_comment_row("","2: earningsInKind");
	$kind->add_comment_row("","3: purchasedFood");
	$kind->add_comment_row("","4: consumedProducedFood");
	$kind->add_comment_row("","5: production cost");
	$kind->add_comment_row("","6: appreciation (future prices)");
	$kind->add_comment_row("","7: penalties/ (dis-utilities)");
	$kind->add_comment_row("","Good","Type:");
	for my $k (@{$self->sorted_activity_objects} ) {

	    my $t = lc($k->attr("type"));
	    my $typ = $k->attr_defined("type_of_payment", sprintf("1%01d", $thismarket)) ? $k->attr("type_of_payment", sprintf("1%01d", $thismarket)) : $k->get_default_value("type_of_payment") ;
	    $typ = $typhash{$t} if (exists $typhash{$t});
	    $kind->add_row("",$k->attr("name"),"",$typ);
	}
	$self->add_block($kind);

	


	if ($self->config_entry("MULTIPERIOD") == 0) {
		###Time preference penalties

		my $TPRegistry = $self->get_penalty_registry();
		my $penalties = MpmasInputBlock->new(2,68);
		$penalties->add_row("");
		$penalties->add_comment_row("1.13", "Time preference penalties");
		$penalties->add_row("", "Number of penalties", $TPRegistry->counter);
		$penalties->add_comment_row("","Name", "LP row penalty coefficient", "LP col penalty coefficient", "Column of penalty activity", "Payment delay (months)");
		for my $p ($TPRegistry->object_list) {  
			eval {
			local $SIG{__WARN__}=sub{};
			$penalties->add_row("", $p->attr("name"), $self->lp_row_of_constraint($p->attr("con")), $self->lp_column_of_activity($p->attr("penalized_activity")), $self->lp_column_of_activity($p->attr("act")), $p->attr("delay") || 0);
			};
			print STDERR "Error: $@\nfor time preference penalty ".$p->attr("name") and exit(1) if $@;
		}
		$self->add_block($penalties);

		###Future Prices
		my $futurehead = MpmasInputBlock->new(2,70);
		$futurehead->add_row("");
		$futurehead->add_row("2", "Expected Future Market Prices");
		$futurehead->add_row("2.1","Number of Future Prices",$NumFuture);
		$self->add_block($futurehead);
		
		my $futuredesc = MpmasInputBlock->new(100,80);
		$futuredesc->add_row("");
		$futuredesc->add_row("","Activity","LPColumn","Initial Expectation", @years);
		$self->add_block($futuredesc);
		

		my $futuretab = MpmasInputBlock->new(2,90);			
		if ($NumFuture > 0) {
			for my $j ($firstFuture..($firstFuture + $NumFuture -1) ) {
				my $k = $self->activity( $self->sorted_activities($j) );
				my @row = ("", $k->attr("name"), $k->lp_column, $k->orow(undef, sprintf("1%01d", $thismarket)));
				for my $l (@years){
					my $y = $k->orow($l, sprintf("1%01d", $thismarket)); 
					if (not defined $y) {
						print "Warning: missing future price entry $l for ". $k->attr("name")."!\nSet to Initital Value for now!\n" ;
						$y = $k->orow(undef, sprintf("1%01d", $thismarket));
					}
					push @row, $y;
				}
				$futuretab->add_row(@row);
			}
		}
		$self->add_block($futuretab);
		
	}
	#CONSUMPTIONMODEL
	CONSSWITCH:{
		#BASIC CONSUMPTION MODEL
		if ($self->config_entry("CONSTYPE") == 0) {
			my $constab = MpmasInputBlock->new(2,120);	
			$constab->add_row("");
			$constab->add_row("3","The Basic Consumption Model") ;
			$constab->add_row("3.1","Extra consumption [proportion]", $self->config_entry_or_die("SCONEXTRA") );
			$constab->add_row("3.2","Minimum consumption per head per year [value]",$self->config_entry_or_die("SCONMIN"));
			$constab->add_row("3.3", "Lowest possible consumption (relative to minimum) in case of liquidity shortage", $self->config_entry_or_die("SCONRED"));
			$self->add_block($constab);
			
		}
		##EXTENDED CONSUMPTION MODEL
		elsif ($self->config_entry("CONSTYPE") == 1) {
			my $conshead = MpmasInputBlock->new(2,120);	
			$conshead->add_empty_rows(3);
			$conshead->add_comment_row(" THE EXTENDED 3-STEP CONSUMPTION MODEL");      	
			#	$conshead->add_comment_row("Note: Using this alternative, the matrix becomes a three-stage model of investment, production, and consumption. The consumption model itself comprises three-steps that are solved simultaneously: savings, food/non-food consumption/ and the consumption of aggregate categories of food products.");
				
			$self->add_block($conshead);
			##SAVINGS
			my $savings = MpmasInputBlock->new(3,130);	
			$savings->add_comment_row("4","SAVINGS MODEL");
			# Notes: household size always in Bjoule
			# 1a) Compute the income at zero savings from the first differential of the quadratic savings function (and enter this number 2 times in the LP). Maximum income with zero savings: (-sAlfa+((sAlfa^2)-4*(sGamm*HouseholdSize+sDelt)*sBeta)^0.5)/(2*sBeta)					
			#1b) Compute expenditure coefficients: ( sAlfa + sBeta * ( Lower + Upper / 2 ) 					
			$savings->add_comment_row("4.0","Logit model for zero savings");
			$savings->add_row("","Logit model for zero savings (yes/no)","Logit",0);
				##CT! Logit savings still to be implemented!!!!
			$savings->add_empty_rows(1);				
			$savings->add_comment_row("4.1","Indices of constraints and activities");
			$savings->add_row("","Row index income balance","incR", $self->find_special_constraint("MASxc_inc_func",1));
			$savings->add_row("","Col in LP of  segment0 (=zero-savings)","sColU",$self->find_special_activity("MASxc_sav_seg0",1));
			my ($savbounds, $firstsavbound) = $self->find_special_constraints("MASxc_sav_lbound",1);
			
			$savings->add_row("","Row in LP of lower bound for segment0 (=zero-savings)",	"sRowB", $firstsavbound	);		
			$savings->add_row("","Col in LP of binary for segment0 (=zero-savings)","sColB", $self->find_special_activity("MASxc_sav_bin1",1));
			$savings->add_row("","Row in LP of savings function","sRowS", $self->find_special_constraint("MASxc_sav_func",1));
			$savings->add_row("","Col in LP of segment1","sColS", $self->find_special_activity("MASxc_sav_seg2",1));
			
			my @savsegbounds = $self->get_cfg_list("XC_SAV_INCSEGS");					
			$savings->add_comment_row("4.2","Piecewise linear segmentation");
			$savings->add_row("","Number of other segments in savings model (excl. segment0)", "sNumS",scalar @savsegbounds);
			$savings->add_row("","Vector of segment sizes (size: 1 * sNumS)","sVecS", @savsegbounds);
								
			$savings->add_comment_row("4.3","Regression coefficients");
			$savings->add_row("","Income", "sAlfa", $self->config_entry_or_die("XC_SAV_COEF_INC"));
			$savings->add_row("","Income squared","sBeta",$self->config_entry_or_die("XC_SAV_COEF_INC2"));		
			$savings->add_row("","Household size", "sGamm", $self->config_entry_or_die("XC_SAV_COEF_HH"));			
			$savings->add_row("","Constant", "sDelta", $self->config_entry_or_die("XC_SAV_COEF_CONST"));			
			$savings->add_empty_rows(2);
			$self->add_block($savings);

			my $foodexp = MpmasInputBlock->new(3,140);	
			$foodexp->add_comment_row("5","FOOD / NON-FOOD MODEL");
			$foodexp->add_comment_row("5.1","Indices of constraints and activities");
			my @fnfsegsizes = $self->get_cfg_list("XC_FNF_EXPSEGS");
			$foodexp->add_row("","number of expenditure segments","fNumS",	scalar @fnfsegsizes);
			$foodexp->add_row("","row in LP of expenditure segments","fRowS",$self->find_special_constraint("MASxc_fnf_func",1));
			$foodexp->add_row("","col in LP of expenditure segment1","fColS", $self->find_special_activity("MASxc_fnf_seg1",1));
			$foodexp->add_row("","row in LP of household size coefficient","fRowH",$self->find_special_constraint("MASxc_fnf_func",1));
			$foodexp->add_row("","row in LP of household size coefficient","fColH",$self->find_special_activity("MASxc_fnf_hhsize",1));
			
			my @fnfsegcoefs;
			my $runningsum = 0;
			for my $f (0..$#fnfsegsizes) {
			
			    $fnfsegcoefs[$f] = sprintf("%.4f",log(($runningsum + $fnfsegsizes[$f]/2) * 100));
			    $runningsum += $fnfsegsizes[$f];
			}
			$foodexp->add_comment_row("5.2","Regression coefficients");
			$foodexp->add_row("","Expenditure coefficient","fAlfa", $self->config_entry_or_die("XC_FNF_COEF_EXP"));
			$foodexp->add_row("","Betas","fBeta",@fnfsegcoefs);
			$foodexp->add_row("","Household size coefficient","fGamm",$self->config_entry_or_die("XC_FNF_COEF_HH"));
			$savings->add_empty_rows(2);
			$self->add_block($foodexp);


			my $foodcats = MpmasInputBlock->new(3,150);		
			$foodcats->add_comment_row("6", "FOOD CONSUMPTION MODEL (LA/AIDS)");
			$foodcats->add_comment_row("6.1","Indices of constraints and activities");

			my ($numfoodcats, $firstcatfunc) = $self->find_special_constraints("MASxc_foo_foodcat");
		
			$foodcats->add_row("","number of food items","iNumF", $numfoodcats); 
			my @fexsegs = $self->get_cfg_list("XC_FOO_FEXSEGS");
			my @fexmeans;
			$runningsum = 0;
			for my $f (0..$#fexsegs) {
			    $fexmeans[$f] = $runningsum + $fexsegs[$f]/2 ;
			    $runningsum += $fexsegs[$f];
			}
			$foodcats->add_row("","number of expenditure segments","iNumS", scalar @fexsegs);						
			
			$foodcats->add_row("","Constraint index in LP of household size coefficient1","iRowH",	$firstcatfunc);
			$foodcats->add_row("","Activity index in LP of household size coefficients","iColH",	$self->find_special_activity("MASxc_foo_hhsize",1));
			$foodcats->add_row("","Constraint index in LP of price coefficient1","iRowP",	$firstcatfunc);
			$foodcats->add_row("","Activity index in LP of price coefficients","iColP",	$self->find_special_activity("MASxc_foo_price",1));
			$foodcats->add_row("","Constraint index in LP of expenditure segment1","iRowS",	$firstcatfunc);	
			$foodcats->add_row("","Activity index in LP of expenditure segment1","iColS",	$self->find_special_activity("MASxc_foo_seg1",1));
			$foodcats->add_empty_rows(2);
			my $firstfoodbuy = $self->find_special_activity("MASfoodbuy");	
			
			my %foodbuy;
			for my $i ($firstfoodbuy..$firstfoodbuy + $numfoodcats - 1) {
			      my $c = $self->activity_at_col($i);
			      my $cat = $c->subelement_field("consumption", "category");
			      print STDERR "Error: Activity ".$c->name." is a ". $c->type ." activity, but has not been associated to a food category.\n" and exit(1) unless (defined $cat);
			      for my $y (0, @years){
					my $p = $c->orow($y, sprintf("1%01d", $thismarket)); 
					if ($y == 0 or not defined $p) {
						    $p = $c->orow(undef, sprintf("1%01d", $thismarket));
					}
				      $foodbuy{$cat}->{$y} = -1 * $p; 	
			      }
			}
			
			my %foocoefs;
			for my $i (0..$numfoodcats -1) {
				  my $cc = $firstcatfunc + $i;
				  my $k = $self->constraint_at_row($cc);

				  my $alpha = $k->subelement_field("consumption", "xc_foo_coeff_expsi");
				  print STDERR "Error: Constraint ".$k->id." is a ". $k->type ." constraint, but has no #consumption>xc_foo_coeff_expsi information.\n" and exit(1) unless (defined $alpha);
				  $foocoefs{alfa}->[$i] = $alpha;
				
				  my $delta = $k->subelement_field("consumption", "xc_foo_coeff_hh");
				  print STDERR "Error: Constraint ".$k->id." is a ". $k->type ." constraint, but has no #consumption>xc_foo_coeff_hh information.\n" and exit(1) unless (defined $delta);
				  $foocoefs{delta}->[$i] = $delta;

				  my $bsh = $k->subelement_field("consumption", "budget_share");
				  print STDERR "Error: Constraint ".$k->id." is a ". $k->type ." constraint, but has no #consumption>budget_share.\n" and exit(1) unless (defined $bsh);
				  $foocoefs{budget_share}->[$i] = $bsh;

				  my $cat = $k->subelement_field("consumption", "category");
				  print STDERR "Error: Constraint ".$k->id." is a ". $k->type ." constraint, but has not been associated to a food category.\n" and exit(1) unless (defined $cat);
				  $foocoefs{cat}->[$i] = $cat;

				  $foocoefs{price}->[$i] = $foodbuy{$cat};  
			}
		  

			my @lnstonepi;
			for my $y (0, @years){
				$lnstonepi[$y] = 0;
				for my $i (0..$numfoodcats -1) {
					  if ($foocoefs{price}->[$i]->{$y} != 0) {
						$lnstonepi[$y] += $foocoefs{budget_share}->[$i] * log($foocoefs{price}->[$i]->{$y});
					  }
					  else {
						warn "Warning: Price of zero for LA/AIDS Category ".$foocoefs{cat}->[$i]." in year $y\n";
					  }
					  my $pc = 0;
					  my $cc = $firstcatfunc + $i;
					  my $k = $self->constraint_at_row($cc);
					  for my $j (0..$numfoodcats -1) {	
						my $cpij =  $k->subelement_field("consumption", "xc_foo_crossprice_".$foocoefs{cat}->[$j]);
						$pc += $cpij * log($foocoefs{price}->[$j]->{$y});
					  }
					  $foocoefs{pricecoef}->[$i]->{$y} = $pc;
				}
			}
			$foodcats->add_comment_row("6.2","Regression coefficients");
			$foodcats->add_row("","Expenditure part I","iAlfa", @{$foocoefs{alfa}});
			$foodcats->add_empty_rows(1);
			$foodcats->add_comment_row("","Expenditure part II","Year", "iBetas over Segments ...");
			
			for my $y (0, @years) {
				my @row = ("","",$y);
				for my $fm (@fexmeans) {
					push @row, sprintf("%.4f", (log($fm) -$lnstonepi[$y]));
				}
				$foodcats->add_row(@row);
			}
			$foodcats->add_empty_rows(1);
			$foodcats->add_comment_row("","Price part","Year", "iGamma over Categories ...");
			for my $y (0, @years) {
				my @row = ("","",$y);
				for my $i (0..$numfoodcats -1) {
					push @row, sprintf("%.4f", $foocoefs{pricecoef}->[$i]->{$y});
				}
				$foodcats->add_row(@row);
			}
			$foodcats->add_empty_rows(1);
			$foodcats->add_row("","Household size part","iDelta", @{$foocoefs{delta}});
			$foodcats->add_empty_rows(2);
			$self->add_block($foodcats);

			my $spblock= MpmasInputBlock->new(3,160);
			$spblock->add_comment_row("7","Price coefficients consumption model");
			$spblock->add_row("7.1","Number of consumption goods","pNumG",$NumConsumptionGoods);

			my $firstfoodtransc = $self->find_special_constraint("MASxc_foo_cattrans");
			my %foodtransc;
			for my $i ($firstfoodtransc..$firstfoodtransc + $numfoodcats -1) {
			      my $k = $self->constraint_at_row($i);
			      my $cat = $k->subelement_field("consumption","category");
			      print STDERR "Error: Constraint ".$k->id." is a ". $k->type ." constraint, but has not been associated to a food category.\n" and exit(1) unless (defined $cat);
			      $foodtransc{$cat} = $i;
			}
			
			my %foodcons;
			my (@cgcons, @cgacts);
			for my $i ($NumOtherGoods..$NumOtherGoods + $NumConsumptionGoods - 1) {
			      my $k = $self->activity_at_col($i);
			      my $cat = $k->subelement_field("consumption","category");

			      print STDERR "Error: Activity ".$k->id." is a ". $k->type ." activity, but has not been associated to a food category.\n" and exit(1) unless (defined $cat);
			      print STDERR "Error in activity ".$k->id.": Food category '$cat' has not been defined.\n" and exit(1)  unless (exists $foodtransc{$cat});
			      push @cgcons, $foodtransc{$cat};
			      push @cgacts, $i;
			}
			$spblock->add_row("7.2","Constraint indices","pRows", @cgcons);
			$spblock->add_row("","Activity indices","pCols", @cgacts);
			for my $y (0,@years) {
			      my @row = ("","",$y);
			      for my $i (@cgacts) {
					my $k = $self->activity_at_col($i);
					my $p = $k->orow($y, sprintf("1%01d", $thismarket));
					  
					if ($y == 0 or not defined $p) {
						    $p = $k->orow(undef, sprintf("1%01d", $thismarket));
					}
					if (lc($k->attr("type")) eq "masfoodconsume") {
						$p *= -1;
					}
					push @row, $p;
			      }
			      $spblock->add_row(@row);
			}
			$spblock->add_empty_rows(2);
			$spblock->add_comment_row("8","Other Consumption Information");
			my @hhn = $self->get_cfg_list("HHNUTRIENTS");
			$spblock->add_row("","","Number of human food nutrients", scalar @hhn );
			$self->add_block($spblock);
		}
	}
}

1;
