#!/usr/bin/perl -w

# Debconf script for printbill. Uses Matthew Palmer's simple state machine.

use Debconf::Client::ConfModule ':all';
use Debconf::Log ':all';

version ('2.0');
capb ('backup');

my @STATESTACK;

my $STATE = 'upgrade';

while ($STATE ne 'exit') {
	no strict 'refs';
	my $NEXTSTATE = &$STATE;
	use strict;
	
	if ($NEXTSTATE) {
		push (@STATESTACK, $STATE);
	} else {
		$NEXTSTATE = pop (@STATESTACK);
	}
	
	$STATE = $NEXTSTATE;
}

# Validate floating-point numbers

sub validate_float {
	my ($arg) = shift;
	return ($arg =~ /^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/);
}

# Validate integers

sub validate_int {
	my ($arg) = shift;
	return ($arg =~ /^\d+$/);
}

sub upgrade {
	title ("Printbill Configuration - Upgrades");
	input ("critical", "printbill/upgrade");
	my @ret = go;

	if ($ret [0] == 30) {
		return undef;
	} else {
		return "pbdebconf";
	}
}

sub pbdebconf {
	title ("Printbill Configuration - Printbill and Debconf");
	input ("critical", "printbill/debconf");
	my @ret = go;

	if ($ret [0] == 30) {
		return undef;
	} else {
		return "use_admin_web_interface";
	}
}

sub use_admin_web_interface {
	title ("Printbill Configuration - Administrative Web Interface");
	input ("critical", "printbill/use_admin_web_interface");
	my @ret = go;

	if ($ret [0] == 30) {
		return undef;
	} else {
		return "admin_form_type";
	}
}

sub admin_form_type {
	my @ret = get ("printbill/use_web_interface");
	
	if ($ret [1] eq "true") {
		title ("Printbill Configuration - Administration Form Type");
		input ("critical", "printbill/admin_form_type");
		my @ret = go;

		if ($ret [0] == 30) {
			return undef;
		} else {
			return "use_user_web_interface";
		}
	}
	
	return "use_user_web_interface";
}

sub use_user_web_interface {
	title ("Printbill Configuration - Web Interface");
	input ("critical", "printbill/use_user_web_interface");
	my @ret = go;

	if ($ret [0] == 30) {
		return undef;
	} else {
		return "def_price_per_page";
	}
}

sub def_price_per_page {
	title ("Printbill Configuration - Per-Page Charge");
	input ("critical", "printbill/def_price_per_page");
	my @ret = go;

	if ($ret [0] == 30) {
		return undef;
	} else {
		@ret = get ("printbill/def_price_per_page");
		
		if (validate_float ($ret [1])) {
			return "def_colourspace";
		} else {
			return "err_price_per_page";
		}
	}
}

sub err_price_per_page {
	title ("Printbill Configuration - Error");
	input ("critical", "printbill/bad_float");
	go;
	return undef;
}

sub def_colourspace {
	title ("Printbill Configuration - Default Colourspace");
	input ("critical", "printbill/def_colourspace");
	my @ret = go;

	if ($ret [0] == 30) {
		return undef;
	} else {
		@ret = get ("printbill/def_colourspace");

# What happens next depends on the colourspace

		if ($ret [1] eq "pagecount") {
			return "response_method";
		} elsif ($ret [1] eq "mono") {
			return "black_cartridge_cost";
		} elsif ($ret [1] eq "cmyk") {
			return "black_cartridge_cost";
		} elsif ($ret [1] eq "cmy") {
			return "colour_cartridge_cost";
		}
	}
}

sub black_cartridge_cost {
	title ("Printbill Configuration - Price of Black Cartridge");
	input ("critical", "printbill/black_cartridge_cost");
	my @ret = go;

	if ($ret [0] == 30) {
		return undef;
	} else {
		@ret = get ("printbill/black_cartridge_cost");
		
		if (validate_float ($ret [1])) {
			return "black_cartridge_quoted_pages";
		} else {
			return "err_black_cartridge_cost";
		}
	}
}

sub err_black_cartridge_cost {
	title ("Printbill Configuration");
	input ("critical", "printbill/bad_float");
	go;
	return undef;
}

sub black_cartridge_quoted_pages {
	title ("Printbill Configuration - Expected Pages for Black Cartridge");
	input ("critical", "printbill/black_cartridge_quoted_pages");
	my @ret = go;

	if ($ret [0] == 30) {
		return undef;
	} else {
		@ret = get ("printbill/black_cartridge_quoted_pages");
		
		if (validate_int ($ret [1])) {
			@ret = get ("printbill/def_colourspace");
			
			if ($ret [1] eq "cmyk") {
				return "colour_cartridge_cost";
			} else { #if ($ret [1] eq "mono") {
				return "response_method";
			}
		} else {
			return "err_black_cartridge_quoted_pages";
		}
	}
}

sub err_black_cartridge_quoted_pages {
	title ("Printbill Configuration - Error");
	input ("critical", "printbill/bad_int");
	go;
	return undef;
}

sub colour_cartridge_cost {
	title ("Printbill Configuration - Price of Colour Cartridge");
	input ("critical", "printbill/colour_cartridge_cost");
	my @ret = go;

	if ($ret [0] == 30) {
		return undef;
	} else {
		@ret = get ("printbill/colour_cartridge_cost");
		
		if (validate_float ($ret [1])) {
			return "colour_cartridge_quoted_pages";
		} else {
			return "err_colour_cartridge_cost";
		}
	}
}

sub err_colour_cartridge_cost {
	title ("Printbill Configuration - Error");
	input ("critical", "printbill/bad_float");
	go;
	return undef;
}

sub colour_cartridge_quoted_pages {
	title ("Printbill Configuration - Expected Pages for Colour Cartridge");
	input ("critical", "printbill/colour_cartridge_quoted_pages");
	my @ret = go;

	if ($ret [0] == 30) {
		return undef;
	} else {
		@ret = get ("printbill/colour_cartridge_quoted_pages");
		
		if (validate_int ($ret [1])) {
			return "response_method";
		} else {
			return "err_colour_cartridge_quoted_pages";
		}
	}
}

sub err_colour_cartridge_quoted_pages {
	title ("Printbill Configuration - Error");
	input ("critical", "printbill/bad_int");
	go;
	return undef;
}

sub response_method {
	title ("Printbill Configuration - Response Method");
	input ("critical", "printbill/response_method");
	my @ret = go;
	if ($ret [0] == 30) {
		return undef;
	} else {
		return "dpi";
	}
}

sub dpi {
	my @ret = get ("printbill/def_colourspace");
	
	if ($ret [1] ne "pagecount") {
		title ("Printbill Configuration - Calculation Resolution");
		input ("critical", "printbill/dpi");
		@ret = go;

		if ($ret [0] == 30) {
			return undef;
		} else {
			@ret = get ("printbill/dpi");
		
			if (validate_int ($ret [1])) {
				return "filter";
			} else {
				return "err_dpi";
			}
		}
	}
}

sub err_dpi {
	title ("Printbill Configuration - Error");
	input ("critical", "printbill/bad_int");
	go;
	return undef;
}

sub filter {
	title ("Printbill Configuration - Optional Filter");
	input ("critical", "printbill/filter");
	my @ret = go;
	
	if ($ret [0] == 30) {
		return undef;
	} else {
		return "admin_mail";
	}
}

sub admin_mail {
	title ("Printbill Configuration - Administrator E-mail");
	input ("critical", "printbill/admin_mail");
	my @ret = go;
	
	if ($ret [0] == 30) {
		return undef;
	} else {
		return "verbosity";
	}
}

sub verbosity {
	title ("Printbill Configuration - Verbosity");
	input ("critical", "printbill/verbosity");
	my @ret = go;
	
	if ($ret [0] == 30) {
		return undef;
	} else {
		return "bill_max_processes";
	}
}

sub bill_max_processes {
	title ("Printbill Configuration - Maximum Concurrent Billing Processes");
	input ("critical", "printbill/bill_max_processes");
	my @ret = go;

	if ($ret [0] == 30) {
		return undef;
	} else {
		@ret = get ("printbill/bill_max_processes");
		
		if (validate_int ($ret [1])) {
			return "currency_symbol";
		} else {
			return "err_bill_max_processes";
		}
	}
}

sub err_bill_max_processes {
	title ("Printbill Configuration - Error");
	input ("critical", "printbill/bad_int");
	go;
	return undef;
}

sub currency_symbol {
	title ("Printbill Configuration - Currency Symbol");
	input ("critical", "printbill/currency_symbol");
	my @ret = go;
	if ($ret [0] == 30) {
		return undef;
	} else {
		return "stats_path";
	}
}

sub stats_path {
	title ("Printbill Configuration - Statistics Path");
	input ("critical", "printbill/stats_path");
	my @ret = go;
	if ($ret [0] == 30) {
		return undef;
	} else {
		return "financelog";
	}
}

sub financelog {
	title ("Printbill Configuration - Finance Log");
	input ("critical", "printbill/financelog");
	my @ret = go;
	if ($ret [0] == 30) {
		return undef;
	} else {
		return "exit";
	}
}
