package MpmasBData;

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

sub filename {
	return "BData";
}


sub prepare_special {
	my $self = shift;	
	#####Consistency checks
	print "Inconsistent setting of CONTROL switches: OFFINVDELAY > 0 and OFFINV > 0. \n" if ($self->config_entry("OFFINVDELAY") > 0 and $self->config_entry("OFFINV") > 0);
	

	####Prepare Input Blocks
	##General Parameters Block		
	my $block1 = MpmasInputBlock->new(3, 10);  # number of commentary columns, priority
	
	$block1->add_row("THE BASIC DATA FILE");
	$block1->add_row("1","GENERAL PARAMETERS","","");
	$block1->add_row("","1.01","Maximum number of sub-basins (or districts)",$self->config_entry("DISTRICTS"));
	$block1->add_row("","1.02","Maximum number of micro-basins (or villages)",$self->config_entry("VILLAGES"));
	$block1->add_row("","1.03","Number of innovation networks",$self->config_entry("NETWORKS"));
	$block1->add_row("","1.04","Number of segments per network",$self->config_entry("SEGMENTS"));
	$block1->add_row("","1.05","Number of agent populations",$self->config_entry("POPULATIONS"));
	$block1->add_row("","1.06","Number of clusters per population",$self->config_entry("CLUSTERS"));
	$block1->add_row("","1.07","Number of loops before lottery is stopped",$self->config_entry("LOTTERYLOOPS"));
	$block1->add_row("","1.08","Minimum share of water demand to be met in lottery",$self->config_entry("MINWATER"));
	$block1->add_row("","1.09","Number of producer organizations",$self->config_entry("PRODUCER_ORGS")|| 0);
	$block1->add_row("","1.10","Number of regional markets",$self->config_entry("MARKETS") || 1);
	$block1->add_row("","","","");
	$block1->add_row("2","SWITCHES FOR VARIOUS SUB-MODELS","","");
	$block1->add_row("","2.01","Type of consumption model",$self->config_entry("CONSTYPE"));
	$block1->add_row("","2.02","Type of crop growth model",$self->config_entry("CROP_MODEL"));
	$block1->add_row("","2.03","Type of hydrology model",$self->config_entry("LANDSCAPE_MODEL"));
	$block1->add_row("","2.04","Livestock model",$self->config_entry("LIVESTOCK_MODEL"));
	$block1->add_row("","2.05","Permanent crops model",$self->config_entry("PERMCROP_MODEL"));
	$block1->add_row("","2.06","Internal land market",$self->config_entry("LANDMARKET_MODEL"));# 0 = landNoTransfer,1 = landToOtherFarms,	2 = landRentalMarket,	3 = landLongTermMarket
	$block1->add_row("","2.07","Type of lottery input",$self->config_entry("ASSETDISTTYPE")||0);
	$block1->add_row("","2.08","Country specific module",$self->config_entry("COUNTRY"));
	$block1->add_row("","2.09","Use of intermediate products",$self->config_entry("HARVEST_DECISION"));
	$block1->add_row("","2.10","Subversion of biophysical modules",$self->config_entry("BIOVERSION")||0);# 0 -default , 1 - FAO56 for EDIC Chile, 2 - FAO56 with flood factor, 3 - External yields from file, 4 - Internally passed in array, 5 - Internally passed in map, 6 - recieved as map via TCP/IP
	$block1->add_row("","2.11","Policy intervention",$self->config_entry("POLICY_MODEL")||0); #bitstring: 0 - none; 1 - Chile perennial bonus; 2 - irrigation infrastructure projects; 4 - EUCAP2003, 8 - External script preinvestment , 16 - external script end of year
	$block1->add_row("","2.12","Irrigation",$self->config_entry("IRRIGATION")||0); #0 - no; 1 - yes
	
	my $demobitset =   0;
	if ($self->config_entry("DEMOGRAPHY_MODEL") == 1 ) {
		$demobitset += 1;
	
	}
	elsif ($self->config_entry("DEMOGRAPHY_MODEL") == 2 ) {
		$demobitset += 5;
	}
	if ( defined $self->get_cfg_list_empty_ok("EXTRA_HHMEMBER_CHARACTERISTICS") and scalar(@{[$self->get_cfg_list_empty_ok("EXTRA_HHMEMBER_CHARACTERISTICS")]}) > 0)	{
		$demobitset += 2;
	}
    $block1->add_row("","2.13","Demography model", $demobitset); #bitset: bit 1: advanced demography model yes/no?, bit 2: extra_household_members_characteristics, bit 3 : Advanced demography model 2
	$block1->add_row("","2.14","Exogenous yield expectations",$self->config_entry("EXO_YIELD_EXPECTATIONS")||0); #0 - no; 1 - yes
	if ($self->config_entry("MULTIPERIOD")) {
		$block1->add_row("","2.13","Multiperiod LP", $self->config_entry("MULTIPERIOD") > 0);	
		
		my $x = defined ($self->get_cfg_list_empty_ok("EXTRA_AGENT_ATTRIBUTES")) && scalar (@{[$self->get_cfg_list_empty_ok("EXTRA_AGENT_ATTRIBUTES")]}) ? 1 : 0;
		$block1->add_row("","2.14","Extra agent attributes",  $x);
		
	}
	

	$block1->add_row("","","","");
	$block1->add_row("3","SOIL INFORMATION","","");
	$block1->add_row("","3.01","Size of 1 grid cell (=parcel)",$self->config_entry("CELLSIZE"));
	$block1->add_row("","3.02","Unit transport costs",$self->config_entry("TCOST"));
	$block1->add_row("","3.03","Number of soil types",$self->config_entry("NSOIL"));
	$block1->add_row("","3.04","Number of nutrient response units (NRUs)",$self->config_entry("NNRU"));
	$block1->add_row("","3.05","Static assignment of NRUs",$self->config_entry("STATICNRU"));
	
	if ( $self->config_entry("STATICNRU") == 1  and $self->config_entry("NNRU") != $self->config_entry("NSOIL") )
	{
		if ($self->config_entry("NNRU") == 0) {
			$self->set_config_entry("NNRU", $self->config_entry("NSOIL"));
		}
		else {
			print STDERR "Error: STATICNRU = 1, but NNRU != NSOIL\n";
			exit(1);
		}
	}
	$block1->add_row("","3.05","Number of user defined landscape parameters", $self->config_entry("NUDEF") || 0); 
	
	if (  $self->config_entry("MULTIPERIOD")) {
		if ($self->config_entry("DYNAMIC_SOIL_TRANSITIONS") != 0 && ($self->config_entry("CROP_MODEL") != 3) ) {
				print STDERR "Error: DYNAMIC_SOIL_TRANSITIONS are only possible with MULTIPERIOD > 0 and CROP_MODEL = 3\n";
				exit(1);
		}
		$block1->add_row("","3.06","Changing soil types depending on crop growth", $self->config_entry("DYNAMIC_SOIL_TRANSITIONS") || 0); 
    }
	$block1->add_row("","","","");


	$block1->add_row("4","INNOVATION PARAMETERS","","");
	$block1->add_row("","4.01","Tentative number of farm assets",$self->config_entry("NFARMASSETS"));
	$block1->add_row("","4.02","Constraints on the random asset assignment","");
	$block1->add_row("","4.03","Maximum age of assets in period 0",$self->config_entry("ASSETMAXAGE"));
	$block1->add_row("","4.04","Minimum age of assets in period 0",$self->config_entry("ASSETMINAGE"));
	$block1->add_row("","","Diffusion model","");
	$block1->add_row("","4.05","Type of communication process",$self->config_entry("COMTYPE"));
	$block1->add_row("","4.06","Cumulative adoption  (\"classical\" diffusion curve)",$self->config_entry("CUMADOPT"));
	$block1->add_row("","4.07","Parameter for expectations, see Brandes et al. (1997: 382)",$self->config_entry("PAREX"));
	$block1->add_row("","","Fine-tuning of innovation diffusion","");
	$block1->add_row("","4.08","Safe rounding factor for indivisible assets",$self->config_entry("SAFEROUND"));
	$block1->add_row("","4.09","Minimum investment in permanent crops [ha]",$self->config_entry("MINPERM"));
	$block1->add_row("","4.10","Overlap of network thresholds",$self->config_entry("OVERLAP"));
	$block1->add_row("","4.11","Liquidity reserve factor",$self->config_entry("LIQRESERVE"));
	$block1->add_row("","4.12","Number of \"symbolic\" investment objects",$self->config_entry("SYMBOLICS"));
	$block1->add_row("","4.13","Currency units",$self->config_entry("CURRENCYSCALE"));
	$block1->add_row("","","","");


#	if ($self->config_entry("POLICY") == 1) {
#
#		$block1->add_row("6","POLICY PARAMETERS","","");
#		$block1->add_row("","6.01","Maximum age of subsidized permanent crops",$self->config_entry("MAXAGEPERM"));
#		$block1->add_row("","6.02","Duration of policy measure",$self->config_entry("DURPOLICY"));
#		$block1->add_row("","6.03","Initial number of irrigation infrastructure projects",$self->config_entry("N_INFPROJ") || 0);
#		$block1->add_row("","","","");
#	}

	$block1->add_row("7","PROCESS SWITCHES","","");
	$block1->add_row("","7.01","Debug information follows (yes/no)","1");
	$block1->add_row("","7.02","Number of spin-up rounds",$self->config_entry("SPINUPS"));
	$block1->add_row("","7.03","Switch off updating of liquidity and equity",$self->config_entry("OFFLIQEQ"));
	$block1->add_row("","7.04","Switch off aging of household members",$self->config_entry("OFFHHAGING"));
	$block1->add_row("","7.05","Switch off aging of livestock",$self->config_entry("OFFLIVEAGE"));
	$block1->add_row("","7.06","Switch off aging of assets",$self->config_entry("OFFASSAGE"));
	$block1->add_row("","7.07","Switch off investments (immediately)",$self->config_entry("OFFINV"));
	$block1->add_row("","7.08","Switching off investments (delayed by)",$self->config_entry("OFFINVDELAY"));
	$block1->add_row("","7.09","Switch off updating of soil conditions and processes",$self->config_entry("OFFDYNSOIL"));
	$block1->add_row("","7.10","Switch off dynamic inflows",$self->config_entry("OFFDYNFLOW"));

	$block1->add_row("","","","");
	$block1->add_row("8","FINE-TUNING OF THE SOLVER","","");
	$block1->add_row("","8.01","Minimum objective value",$self->config_entry("MINOBJ"));
			
	$self->add_block($block1);		

	##Milp Debugging block
	my $milpblock = MpmasInputBlock->new(3, 20);

	my $ms = 0;
	if ($self->ini_entry("DBGMILPS") ) {
		for my $msp (@{$self->ini_entry("DBGMILPS")}){
			print "\t>>Warning!!!: Entries in DBGMILPS  have to be integers!!!\n\t\>>Value $msp has been skipped!!\n" and next unless $msp =~ /^-?\d*$/;
			$ms += 1;
			my $nmsp = $msp;
			$nmsp = $nmsp * -1 if ($nmsp > 0);
			$milpblock->add_row("","","",$nmsp);
		}
	}
	$milpblock->add_row_at_beginning("","8.02","Number of MILP problems to be saved","$ms");

	$self->add_block($milpblock);

	##Blacklist/Whitelist Block
	if ($self->ini_entry("SKIP_AGENTS")  || $self->ini_entry("USE_ONLY_AGENTS")) {
		
		if ($self->ini_entry("SKIP_AGENTS")  && $self->ini_entry("USE_ONLY_AGENTS"))
		{
			print STDERR "Error: Using SKIP_AGENTS and USE_ONLY_AGENTS at the same time is not allowed!\n";
			exit(1);
		}
		
		
		my $blackblock = MpmasInputBlock->new(3, 22);

		my $bs = 0;
		if ($self->ini_entry("SKIP_AGENTS") ) {
			for my $msp (@{$self->ini_entry("SKIP_AGENTS")}){
				print "\t>>Warning!!!: Entries in SKIP_AGENTS  have to be positive integers!!!\n\t\>>Value $msp has been skipped!!\n" and next unless $msp =~ /^\d*$/;
				$bs += 1;
				$blackblock->add_row("","","",$msp);
			}
		}
		$blackblock->add_row_at_beginning("","8.03","Number of black-listed farm agents","$bs");
		$self->add_block($blackblock);
		
		my $whiteblock = MpmasInputBlock->new(3, 24);

		my $ws = 0;
		if ($self->ini_entry("USE_ONLY_AGENTS") ) {
			for my $msp (@{$self->ini_entry("USE_ONLY_AGENTS")}){
				print "\t>>Warning!!!: Entries in USE_ONLY_AGENTS  have to be positive integers!!!\n\t\>>Value $msp has been skipped!!\n" and next unless $msp =~ /^\d*$/;
				$ws += 1;
				$whiteblock->add_row("","","",$msp);
			}
		}
		$whiteblock->add_row_at_beginning("","8.04","Number of white-listed farm agents","$ws");
		$self->add_block($whiteblock);
	}

	## Final Block
	my $lastblock = MpmasInputBlock->new(3, 30);
	
	$lastblock->add_row("","","","");
	
	$lastblock->add_row("","8.03","Fine-tuning information (yes/no)","1");
	$lastblock->add_row("","8.04","Maximum time allowed for solving (in seconds)", $self->config_entry("OSL_MAXSOLVETIME"));
	$lastblock->add_row("","8.05","Maximum iterations allowed for solving", $self->config_entry("OSL_MAXITERATE"));
	$lastblock->add_row("","8.06","Maximum number of nodes allowed for solving", $self->config_entry("OSL_MAXNODES"));
	$lastblock->add_row("","8.07","OSL mode sequencing ", $self->config_entry("OSL_SEQUENCE"));
	if ($self->config_entry("OSL_SEQUENCE") == 4) {
	      $lastblock->add_row("","8.08","Max. number of attempts", $self->config_entry("OSL_M4_ATTEMPTS"));
	      $lastblock->add_comment_row("","","Limits on first attempts");
	      $lastblock->add_row("","8.09","max. integers", $self->config_entry("OSL_M4_ITHRESH"));
	      $lastblock->add_row("","8.10","max. nodes", $self->config_entry("OSL_M4_NTHRESH"));
	      $lastblock->add_row("","8.11","max. feasible solutions", $self->config_entry("OSL_M4_STHRESH"));

	      $lastblock->add_comment_row("","","Presolving of relaxed LP (EKKPRSL)");
	      $lastblock->add_row("","8.12","...from attempt", $self->config_entry("OSL_M4_LP_PRESOLVE"));
	      $lastblock->add_row("","8.13","...if previous attempt infeasible", $self->config_entry("OSL_M4_LP_PRESOLVE_ONFAIL"));
	      
	      $lastblock->add_comment_row("","","Scaling (EKKSCAL)"); 
	      $lastblock->add_row("","8.14","...from attempt", $self->config_entry("OSL_M4_SCALE"));
	      $lastblock->add_row("","8.15","...if previous attempt infeasible", $self->config_entry("OSL_M4_SCALE_ONFAIL"));
	      
	      $lastblock->add_comment_row("","","Crash to find feasible basis (EKKCRSH)"); 
	      $lastblock->add_row("","8.16","OSL crash mode", $self->config_entry("OSL_M4_CRASHMODE"));
	      $lastblock->add_row("","8.17","...from attempt", $self->config_entry("OSL_M4_CRASH"));
	      $lastblock->add_row("","8.18","...if previous attempt infeasible", $self->config_entry("OSL_M4_CRASH_ONFAIL"));

	      $lastblock->add_comment_row("","","Integer presolving (EKKMPRE)"); 
	      $lastblock->add_row("","8.19","OSL integer strategy (Istrategy bit mask)", $self->config_entry("OSL_M4_I_STRATEGY"));
	      $lastblock->add_row("","8.20","OSL number of heuristic passes", $self->config_entry("OSL_M4_I_HEURPASS"));
	      $lastblock->add_row("","8.21","Max rows to add for integer presolving", $self->config_entry("OSL_M4_I_PRE_ADDROWS"));
	      $lastblock->add_row("","8.22","...from attempt", $self->config_entry("OSL_M4_I_PRESOLVE"));
	      $lastblock->add_row("","8.23","...if previous attempt infeasible", $self->config_entry("OSL_M4_I_PRESOLVE_ONFAIL"));

	      $lastblock->add_comment_row("","","Accept first attempt if");
	      $lastblock->add_row("","8.24","difference to best estimated < ", $self->config_entry("OSL_M4_ACCEPT_DIFF"));
	      $lastblock->add_row("","8.25","or rel. difference to best estimated < ", $self->config_entry("OSL_M4_ACCEPT_RELDIFF"));
	      $lastblock->add_row("","8.26","Try again after infeasible attempt ", $self->config_entry("OSL_M4_CONT_ONFAIL"));
	      $lastblock->add_row("","8.27","Continue in mode 3 if mode 4 failed", $self->config_entry("OSL_M4_MODE3_ONFAIL"));
	      $lastblock->add_row("","8.28","Log solving in mode 4", $self->config_entry("OSL_M4_LOG"));

	}
	if ($self->config_entry("RNGSTREAM")) {
			$lastblock->add_empty_rows(3);
			$lastblock->add_comment_row("9","","Random number generator");
			$lastblock->add_comment_row("","9.1","Seeds household member event RNG");
			$lastblock->add_row("","","(6 positive integers)", $self->config_entry("RNG_HME_1"), $self->config_entry("RNG_HME_2"), $self->config_entry("RNG_HME_3"), $self->config_entry("RNG_HME_4"), $self->config_entry("RNG_HME_5"), $self->config_entry("RNG_HME_6"));
			$lastblock->add_empty_rows(1);
			$lastblock->add_row("","","Start_FstID_position_shifter", $self->config_entry("RNG_HME_SHIFT"));
			$lastblock->add_empty_rows(1);
	}
	
	$self->add_block($lastblock);
	
	
	
}

1;
