/**
 * create one test case
 *
 * @param integer $case
 * @param integer $stopcase
 * @return boolean true after last case
 */
function create_case($case, $stopcase) {
	global $date, $login, $ngroup;

	$stop = 0;
	$branch = 0;
	static $branch1 = 0;
	$casedesc = $case." (".$stopcase."/".$branch1.")";
	echo "Test case ".$casedesc."\n";

	Login::$member = $login;

	// create period
	if ($stopcase == ++$stop) {
		// period without ballot voting
		$sql = "INSERT INTO period (debate, preparation, voting, ballot_assignment, ballot_preparation, counting, ballot_voting, ngroup)
		VALUES (
			now(),
			now() + interval '1 week',
			now() + interval '2 weeks',
			NULL,
			NULL,
			now() + interval '4 weeks',
			false,
			".$ngroup->id."
		)";
		DB::query($sql);
		return;
	} else {
		// period with ballot voting
		$sql = "INSERT INTO period (debate, preparation, voting, ballot_assignment, ballot_preparation, counting, ballot_voting, ngroup, postage)
		VALUES (
			now(),
			now() + interval '1 week',
			now() + interval '2 weeks',
			now() + interval '1 week',
			now() + interval '3 weeks',
			now() + interval '4 weeks',
			true,
			".$ngroup->id.",
			true
		) RETURNING id";
		$result = DB::query($sql);
		$row = DB::fetch_row($result);
		$period = new Period($row[0]);
	}

	${'branch'.++$branch.'_array'} = array(0, 5, 15);
	$ballot_count = ${'branch'.$branch.'_array'}[${'branch'.$branch}];

	for ( $i=1; $i<=$ballot_count; $i++ ) {
		// create a ballot
		$ballot = new Ballot;
		$ballot->ngroup = $ngroup->id;
		$ballot->name = "Test ballot ".$casedesc;
		$ballot->agents = "Test agents";
		$ballot->period = $period->id;
		$ballot->opening = "8:00";
		$ballot->create();
		// add participants
		for ( $j=1; $j<=$i-1; $j++ ) {
			add_participant($period, $ballot, $case, "a".$ballot_count."i".$i."j".$j);
		}
	}

	// add postal voters
	for ( $j=1; $j<=10; $j++ ) {
		add_participant($period, true, $case, "a".$ballot_count."i0j".$j);
	}

	if ($stopcase == ++$stop) return;

	// approve ballots with 10 or more participants
	$sql = "SELECT * FROM ballot WHERE period=".intval($period->id);
	$result = DB::query($sql);
	while ( $ballot = DB::fetch_object($result, "Ballot") ) {
		if ($ballot->voters < 10) continue;
		$ballot->approved = true;
		$ballot->update(["approved"]);
	}

	if ($stopcase == ++$stop) return;

	// add further participants without assigning them to ballots
	for ($i=1; $i<=100; $i++) {
		add_participant($period, null, $case, "t".$date."c".$case."i".$i);
	}

	// move to phase "ballot_assignment"
	time_warp($period, "1 week");
	cron();

	if ($stopcase == ++$stop) return;

	// move to phase "ballot_preparation"
	time_warp($period, "2 weeks");
	cron();

	// continue with next case if branches are still available
	for ($i=1; $i<=$branch; $i++) {
		if (isset(${'branch'.$i.'_array'}[++${'branch'.$i}])) {
			for ($j=1; $j<$i; $j++) ${'branch'.$j}=0;
			return true;
		}
	}

	// end of last case
	return "end";
}
 $event_note = note_to_db($_POST['event_note']);
 $event_date = pad_date($_POST['date_1']) . $_POST['date_type'] . pad_date($_POST['date_2']) . '1';
 $sort_date = parse_sort_date($_POST['sort_date'], $event_date);
 $place = $_POST['place_fk'];
 if ($place == 0) {
     $place = 1;
 }
 $tag = $_POST['tag_fk'];
 pg_query("BEGIN");
 $event = fetch_val("\n        INSERT INTO events (\n            tag_fk,\n            place_fk,\n            event_date,\n            sort_date,\n            event_note\n        )\n        VALUES (\n            {$tag},\n            {$place},\n            '{$event_date}',\n            '{$sort_date}',\n            '{$event_note}'\n        )\n        RETURNING event_id\n    ");
 set_last_selected_place($place);
 add_participant($person, $event);
 if ($_POST['coprincipal'] && has_coprincipal($tag)) {
     // constrain to events which allows for coprincipal, ie tag_type = 2
     $coprincipal = $_POST['coprincipal'];
     add_participant($coprincipal, $event);
 }
 if ($tag == 31) {
     // hard-coded reference to probate
     pg_query("SELECT generate_probate_witnesses({$event})");
 }
 $source_id = add_source($person, $tag, $event, $src, note_to_db($txt));
 $age = $_POST['age'];
 if ($age && is_numeric($age)) {
     // generate birth event
     add_birth($person, $event_date, $age, $source_id);
 }
 if ($tag == 3) {
     // hard-coded death tag, check if died young
     if ((died_young($person) || $age && $age < 16) && fetch_val("SELECT dead_child({$person})") == 'f') {
         pg_query("INSERT INTO dead_children (person_fk) VALUES ({$person})");
     if ($merge_mothers) {
         // delete 'source' mother relationship, transfer citation(s)
         $relid_s = get_relation_id($source, 2);
         $relid_t = get_relation_id($target, 2);
         pg_query("\n                UPDATE relation_citations\n                SET relation_fk = {$relid_t}\n                WHERE relation_fk = {$relid_s}\n            ");
         pg_query("\n                DELETE FROM relations\n                WHERE relation_id = {$relid_s}\n            ");
     }
     // transfer remaining relations
     pg_query("\n            UPDATE relations\n            SET child_fk = {$target}\n            WHERE child_fk = {$source}\n        ");
     pg_query("\n            UPDATE relations\n            SET parent_fk = {$target}\n            WHERE parent_fk = {$source}\n        ");
     // update source_linkage
     pg_query("\n            UPDATE source_linkage\n            SET person_fk = {$target}\n            WHERE person_fk = {$source}\n        ");
     // insert "event" for source person with a link to target person
     $event_note = " [p={$target}|ID #{$target}]";
     $event = fetch_val("\n            INSERT INTO events (\n                tag_fk,\n                place_fk,\n                event_date,\n                sort_date,\n                event_note\n            )\n            VALUES (\n                1040,\n                1,\n                '000000003000000001',\n                '00010101',\n                '{$event_note}'\n            )\n            RETURNING event_id\n        ");
     add_participant($source, $event);
     pg_query("\n            INSERT INTO merged (old_person_fk,new_person_fk)\n            VALUES ({$source}, {$target})\n        ");
     set_last_edit($source);
     set_last_edit($target);
     pg_query("\n            COMMIT\n        ");
     // return to main view of "stripped" person.
     header("Location: {$app_root}/family.php?person={$source}");
 } else {
     // explain why the merge failed
     $title = "{$_App_name}: {$_Merge_persons_failed}";
     require "./form_header.php";
     echo "<h2>{$title}!</h2>\n";
     $name_1 = get_name($person_1);
     $name_2 = get_name($person_2);
     echo "<p>{$_Cannot_merge} {$name_1} ({$_born} {$bdate_1}), {$_with} {$name_2} ({$_born} {$bdate_2}).<br />\n";
     echo "{$_Reason}: {$reason}</p>\n";
 $place = $_POST['place_fk'];
 if ($place == 0) {
     $place = 1;
 }
 $event_date = pad_date($_POST['date_1']) . $_POST['date_type'] . pad_date($_POST['date_2']) . '1';
 $sort_date = parse_sort_date($_POST['sort_date'], $event_date);
 // minimal cleanup of event note
 $event_note = note_to_db($_POST['event_note']);
 $event = fetch_val("\n        INSERT INTO events (\n            tag_fk,\n            place_fk,\n            event_date,\n            sort_date,\n            event_note\n        )\n        VALUES (\n            {$tag},\n            {$place},\n            '{$event_date}',\n            '{$sort_date}',\n            '{$event_note}'\n        )\n        RETURNING event_id\n    ");
 set_last_selected_place($place);
 // participant data
 add_participant($person, $event);
 // if the script was called with the 'addspouse' param
 // and tag is in marriage group, connect spouse to event
 if (isset($_POST['spouse']) && fetch_val("SELECT get_tag_group({$event})") == 2) {
     add_participant($_POST['spouse'], $event);
 }
 // note that add_source() returns 0 for no source, else current source_id
 $source_id = add_source($person, $tag, $event, $src, $txt);
 // add relation if this script was called with an 'addparent' param:
 if ($_POST['child']) {
     $child = $_POST['child'];
     $relation_id = fetch_val("\n            INSERT INTO relations (\n                child_fk,\n                parent_fk\n            )\n            VALUES (\n                {$child},\n                {$person}\n            )\n            RETURNING relation_id\n        ");
     if ($source_id) {
         // add relation citation
         pg_query("\n                INSERT INTO relation_citations (\n                    relation_fk,\n                    source_fk\n                )\n                VALUES (\n                    {$relation_id},\n                    {$source_id}\n                )\n            ");
     }
 }
 // add relation if this script was called with a 'father' param:
 if ($_POST['father']) {
     $father = $_POST['father'];