#!/usr/bin/env perl
use Mojolicious::Lite;
use Cache::File;
use Travel::Status::DE::DeutscheBahn;

our $VERSION = '0.02';

sub get_results_for {
	my ($station) = @_;

	my $cache = Cache::File->new(
		cache_root      => '/tmp/db-fake',
		default_expires => '900 sec'
	);

	my $results = $cache->thaw($station);

	if ( not $results ) {
		my $status
		  = Travel::Status::DE::DeutscheBahn->new( station => $station );
		$results = [ $status->results ];
		$cache->freeze( $station, $results );
	}

	return @{$results};
}

sub handle_request {
	my $self    = shift;
	my $station = $self->stash('station');
	my $via     = $self->stash('via');

	my @platforms = split( /,/, $self->param('platforms') // q{} );
	my $template = $self->param('mode') // 'multi';

	$self->stash( departures => [] );
	$self->stash( title      => 'db-fakedisplay' );
	$self->stash( version    => $VERSION );

	if ( not( $template ~~ [qw[multi single]] ) ) {
		$template = 'multi';
	}

	if ( not $station ) {
		$self->render($template);
		return;
	}

	my @departures;
	my @results = get_results_for($station);

	if ( not @results ) {
		$self->render( 'multi', error => "Got no results for '$station'" );
		return;
	}

	if ( $template eq 'single' ) {
		if ( not @platforms ) {
			for my $result (@results) {
				if ( not( $result->platform ~~ \@platforms ) ) {
					push( @platforms, $result->platform );
				}
			}
			@platforms = sort { $a <=> $b } @platforms;
		}
		my %pcnt;
		@results = grep { $pcnt{ $_->platform }++ < 1 } @results;
		@results = sort { $a->platform <=> $b->platform } @results;
	}

	for my $result (@results) {
		my $platform = ( split( / /, $result->platform ) )[0];
		if ($via) {
			my @route = $result->route;
			if ( not( grep { $_ =~ m{$via}io } @route ) ) {
				next;
			}
		}
		if ( @platforms and not grep { $_ eq $platform } @platforms ) {
			next;
		}
		push(
			@departures,
			{
				time        => $result->time,
				train       => $result->train,
				via         => [ $result->route_interesting(3) ],
				destination => $result->destination,
				platform    => $platform,
				info        => $result->info,
			}
		);
	}

	$self->render(
		$template,
		departures => \@departures,
		version    => $VERSION,
		title      => "departures for ${station}"
	);
}

get '/_redirect' => sub {
	my $self    = shift;
	my $station = $self->param('station');
	my $via     = $self->param('via');
	my $params  = $self->req->params;

	$params->remove('station');
	$params->remove('via');

	if ($params->param('mode') and $params->param('mode') eq 'multi') {
		$params->remove('mode');
	}

	for my $param (qw(platforms)) {
		if ( not $params->param($param) ) {
			$params->remove($param);
		}
	}

	$params = $params->to_string;

	if ($via) {
		$self->redirect_to("/${station}/${via}?${params}");
	}
	else {
		$self->redirect_to("/${station}?${params}");
	}
};

app->defaults( layout => 'default' );

get '/'               => \&handle_request;
get '/:station'       => \&handle_request;
get '/:station/:via'  => \&handle_request;
get '/multi/:station' => \&handle_request;

app->config(
	hypnotoad => {
		accepts  => 10,
		listen   => ['http://*:8092'],
		pid_file => '/tmp/db-fake.pid',
		workers  => 2,
	},
);

app->start();

__DATA__

@@ layouts/default.html.ep
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
	"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
	<title><%= $title %></title>
	<meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"/>
	<style type="text/css">

	html {
		font-family: Sans-Serif;
	}

	div.outer {
		border: 0.2em solid #000066;
		width: 55em;
	}

	div.display {
		background-color: #0000ff;
		color: white;
		font-family: Sans-Serif;
		font-weight: bold;
		position: relative;
		margin-bottom: 0;
		margin-top: 0;
		padding-top: 0;
		padding-bottom: 0;
		width: 55em;
		height: 1.4em;
	}

	div.display div {
		overflow: hidden;
		position: absolute;
		height: 100%;
	}

	div.time {
		left: 0;
		width: 6%;
		font-size: 95%;
	}

	div.train {
		left: 5%;
		width: 9%;
		background-color: white;
		color: #0000ff;
		font-size: 95%;
	}

	div.via {
		left: 15%;
		width: 35%;
	}

	div.via span {
		margin-right: 0.4em;
		font-size: 80%;
	}

	div.destination {
		left: 50%;
		width: 25%;
		font-size: 120%;
	}

	div.platform {
		left: 75%;
		width: 5%;
	}

	div.info {
		left: 80%;
		width: 20%;
		background-color: white;
		color: #0000ff;
		font-size: 80%;
		line-height: 150%;
	}

	div.separator {
		border-bottom: 0.1em solid #000066;
	}

	div.about {
		font-family: Sans-Serif;
		color: #666666;
	}

	div.about a {
		color: #000066;
	}

	div.input-field {
		margin-top: 1em;
		clear: both;
	}

	span.fielddesc {
		display: block;
		float: left;
		width: 15em;
		text-align: right;
		padding-right: 0.5em;
	}

	input, select {
		border: 1px solid #000066;
	}

	div.s_display {
		background-color: #0000ff;
		color: white;
		font-family: Sans-Serif;
		font-weight: bold;
		position: relative;
		margin-left: 1em;
		margin-top: 1em;
		float: left;
		width: 28em;
		height: 4.5em;
		border: 0.7em solid #000066;
	}

	div.s_display div {
		overflow: hidden;
		position: absolute;
	}

	div.s_no_data {
		top: 0.5em;
		left: 1em;
		font-size: 1.7em;
	}

	div.s_time {
		top: 0em;
		left: 0em;
		font-size: 1.7em;
	}

	div.s_train {
		left: 0em;
		top: 1.8em;
	}

	div.s_via {
		top: 1.5em;
		left: 5.8em;
		width: 17em;
		height: 1em;
	}

	div.s_via span {
		margin-right: 0.4em;
	}

	div.s_destination {
		top: 1.6em;
		left: 3.6em;
		width: 12em;
		font-size: 1.6em;
		height: 1.2em;
	}

	div.s_platform {
		top: 0em;
		right: 0em;
		font-size: 3em;
	}

	div.s_info {
		top: 0em;
		left: 5.8em;
		width: 16.5em;
		height: 1em;
		background-color: white;
		color: #0000ff;
	}

	</style>
</head>
<body>

<%= content %>

<div class="input-field">

<% if (my $error = stash 'error') { %>
<p>
  Error: <%= $error %><br/>
</p>
<% } %>

<%= form_for _redirect => begin %>
<p>
  <span class="fielddesc">Station name</span>
  <%= text_field 'station' %>
  <br/>
  <span class="fielddesc fieldoptional">only display routes via</span>
  <%= text_field 'via' %>
  (optional)
  <br/>
  <span class="fielddesc fieldoptional">on platforms</span>
  <%= text_field 'platforms' %>
  (optional)
  <br/>
  <span class="fielddesc fieldoptional">display type</span>
  <%= select_field mode => [['combined' => 'multi'], ['platform' => 'single']] %>
  <%= submit_button 'Display' %>
</p>
<% end %>

</div>

<div class="about">
<a href="http://finalrewind.org/projects/db-fakedisplay/">db-fakedisplay</a>
v<%= $version %>
</div>

</body>
</html>

@@ multi.html.ep
% if (@{$departures}) {

<div class="outer">
% my $i = 0;
% for my $departure (@{$departures}) {
% $i++;

<div class="display <% if (($i % 2) == 0) { %> separator<% } %>">
<div class="platform">
%= $departure->{platform}
</div>

<div class="time">
%= $departure->{time}
</div>

<div class="train">
%= $departure->{train}
</div>

<div class="via">
% my $via_max = @{$departure->{via}};
% my $via_cur = 0;
% for my $stop (@{$departure->{via}}) {
% $via_cur++;
<span><%= $stop %><% if ($via_cur < $via_max) { %> - <% } %></span>
% }
</div>

<div class="destination">
%= $departure->{destination}
</div>

% if ($departure->{info}) {
<div class="info">
%= $departure->{info}
</div>
% }

</div> <!-- display -->

% }

</div> <!-- outer -->

% }
% else {

<p>
DB-Fakedisplay displays the next departures at a DB station, just like the big
LC display in the station itself.
</p>

% }

@@ single.html.ep

% if (@{$departures}) {

% my $i = 0;
% for my $departure (@{$departures}) {
% $i++;
<div class="s_display">
<div class="s_platform">
%= $departure->{platform}
</div>
<div class="s_time">
%= $departure->{time}
</div>
<div class="s_train">
%= $departure->{train}
</div>
<div class="s_via">
% my $via_max = @{$departure->{via}};
% my $via_cur = 0;
% for my $stop (@{$departure->{via}}) {
% $via_cur++;
<span><%= $stop %><% if ($via_cur < $via_max) { %> - <% } %></span>
% }
</div>
<div class="s_destination">
%= $departure->{destination}
</div>
% if ($departure->{info}) {
<div class="s_info">
%= $departure->{info}
</div>
% }
</div> <!-- s_display -->
% }

% }
% else {

<div class="s_display">
<div class="s_no_data">
Bitte Ansage beachten
</div>
</div>

<p>
DB-Fakedisplay displays the next departures at a DB station, just like the big
LC display in the station itself.
</p>

% }

@@ not_found.html.ep
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
	"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
	<title>page not found</title>
	<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/>
</head>
<body>
<div>
page not found
</div>
</body>
</html>