
###############################################################################
# C^[tFCX ############################################################
{
	# ZbVf[^ۑ邽߂̃Xg[W
	package IDatabase;
	
	# Xg[W̊Jn
	# void initialize()
	sub initialize { die("this is an interface"); }
	
	# bZ[WPǂݍ
	# Message getNextMessage()
	sub getMessage() { die("this is an interface"); }
	
	# ̃bZ[W邩ǂ
	# bool hasNextMessage()
	sub hasNextMessage() { die("this is an interface"); }
	
	# Xg[W̏I
	# void finalize()
	sub finalize { die("this is an interface"); }
	
	1;
}
{
	# ZbVɗ^p[^
	package IParameter;
	
	# L[ɑΉp[^擾
	# String getParam(String key)
	sub getParam { die("this is an interface"); }
	
	# L[ɑΉp[^擾
	# String[] getParams(String key)
	sub getParams { die("this is an interface"); }
	
	1;
}
{
	# ZbV͂gpĉʕ\
	package IDisplay
	
	# ev[gp[^ݒ
	# void addParameter(String key, String value)
	sub addParameter { die("this is an interface"); }
	
	# \
	# void doDisplay()
	sub doDisplay { die("this is an interface"); }
}

###############################################################################
# NX ##################################################################
{
	# CSVf[^x[X
	package CSVFile;
	@ISA = qw(IDatabase);
	
	# property index
	use constant stream => 0;
	
	# \z
	# CSVFile new(String file)
	sub new {
		my($class,$file) = @_;
		my $this = [
			IO::File->new($file,'+rw'),
			];
		bless($this,$class);
	}
	
	# see IDatabase
	sub initialize {
		my($this) = @_;
		# ƂɕKvȂ
	}
	
	# see IDatabase
	sub getMessage() {
		my($this) = @_;
		
		my $csv = $this->_analizeCSV();
		return Message->new(
			$csv->[0],
			$csv->[1],
			);
	}
	
	# see IDatabase
	sub hasNextMessage() {
		my($this) = @_;
		return $this->[stream]->eof();
	}
	
	# see IDatabase
	sub finalize {
		my($this) = @_;
		$this->[stream]->close();
	}
	
	# Xg[ǂݎ͂zɂĕԂ
	# ARRAYREF analizeCSV()
	sub _analizeCSV {
		return [1,2,3,4,5];
	}
	
	1;
}
{
	package CGIForm;
	@ISA = qw(IParameter);
	
	# property index
	use constant cgi => 0;
	
	# {NXCGI.pm𗘗p܂
	# CGIForm new(CGI cgi)
	sub new {
		my($class,$cgi) = @_;
		my $this = [
			$cgi
			];
		bless($this,$class);
		
	}
	
	# see IParameter
	sub getParam {
		my($this,$key) = @_;
		$this->[cgi]->param($key);
	}
	
	# see IParameter
	sub getParams {
		my($this,$key) = @_;
		$this->[cgi]->param($key);
	}
	
	1;
}
{
	package HTMLPage;
	@ISA =qw(IDisplay);
	
	# o͐w
	# HTMLPage new(IO::Handle out)
	sub new {
		$this->[out] = out;
		$this->[template] = HTML::Template->new();
	}
	
	# see IDisplay
	sub addParameter {
		my($this,$key,$value) = @_;
		$this->[template]->param($key,$value);
	}
	
	# see IDisplay
	sub doDisplay { $this->[out]->print($this->[template]->output()); }
}

###############################################################################
# ZbV ##################################################################
{
	# ZbṼev[gzNX
	package AbstractSession;
	
	# \z
	# AbstractSession new()
	sub new {
		my($class) = @_;
		my $this = [
			undef, # IDatabase
			undef, # IParameter
			undef  # IDisplay
			];
		bless($this,$class);
	}
	
	# 
	# void initialize()
	sub initialize { }
	
	# Ǝɒ`IDatabaseNXԂ
	# IDatabase createDatabase()
	sub createDatabase { die("this is an abstract"); }
	
	# Ǝɒ`IParameterNXԂ
	# IParameter createParameter()
	sub createParameter { die("this is an abstract"); }
	
	# Ǝɒ`IDisplayNXԂ
	# IDisplay createDisplay()
	sub createDisplay { die("this is an abstract"); }
	
	# KuzuhasIy[V
	# void main()
	sub main {
		my($this) = @_;
		
		$this->[database] = $this->createDatabase();
		$this->[parameter] = $this->createParameter();
		$this->[display] = $this->createDisplay();
		
		if ($this->[parameter]->param("e")) {
			# ?
		} elsif ($this->[parameter]->param("[h")) {
			while ($this->[database]->hasNextMessage()) {
				$this->[display]->addParameter(
					"message",
					$this->[database]->getNextMessage()
					);
			}
			$this->[display]->doDisplay();
		}
	}
	
	# I
	# void finalize()
	sub finalize { }
	
	1;
}
{
	# CGIɂZbV
	package CGISession;
	@ISA = qw(AbstractSession);
	
	# see AbstractSession
	sub createDatabase { CSVFile->new("log.dat"); }
	
	# see AbstractSession
	sub createParameter { CGIForm->new( CGI->new() ); }
	
	# see AbstractSession
	sub createDisplay { HTMLPage->new('STDOUT'); }
	
	1;
}


###############################################################################
# Gg|Cg ############################################################
{
	# bbs.cgi
	package Application;
	use CGISession;
	
	# Gg|Cg
	main: {
		my $sess = CGISession->new();
		$sess->main();
	}
}