#!/usr/bin/perl

use GD;

$htmlpath="./";

$coastline=GD::Image->new($htmlpath."gbcoast.png");

$yes=$coastline->colorAllocate(255,0,0);
$no=$coastline->colorAllocate(0,0,255);
$heritage=$coastline->colorAllocate(0,128,0);
$friend=$coastline->colorAllocate(128,0,128);
$closed=$coastline->colorAllocate(0,0,0);

$xorigin=5;
$yorigin=728;
$scale=1480;

# Minimaps provide an overview map for the individual station pages

open (M,$htmlpath."minimaps.txt") or die ("Couldn't open minimaps file: $!");

while(<M>) {
  chomp;
  ($mapname,
   $fullname,
   $e1, $n1,
   $e2, $n2, $prio)=split(/,/);
# $prio is a priority.  Larger priority maps are smaller area maps
# so will get chosen in preference to smaller maps
  $regions{$mapname}{fullname}=$fullname;
  $regions{$mapname}{e1}=$e1;
  $regions{$mapname}{n1}=$n1;
  $regions{$mapname}{e2}=$e2;
  $regions{$mapname}{n2}=$n2;
  $regions{$mapname}{prio}=$prio;
}

close M;

# Station details: status, name, eastings, northings

open (S,$htmlpath."stationcoords.txt") or die ("Couldn't open stationcoords file: $!");

while(<S>) {
  next if (m/^(#|\n)/);
  chomp;
  ($status,$name,$e,$n,$code,$collecteddate,$connections)=split(/,/);

  if($status eq "y") {
    $colour=$yes;
  } elsif($status eq "n") {
    $colour=$no;
  } elsif($status eq "h") {
    $colour=$heritage;
  } elsif($status eq "f") {
    $colour=$friend;
  } elsif($status eq "c") {
    $colour=$closed;
  }

  $x=int($xorigin+($e/$scale)); $y=int($yorigin-($n/$scale));
#  $coastline->arc($x,$y,5,5,0,360,$colour);
#  $coastline->fill($x,$y,$colour);
  $coastline->filledArc($x,$y,5,5,0,360,$colour);

  $stations{$name}{e}=$e;
  $stations{$name}{n}=$n;
  $stations{$name}{x}=$x;
  $stations{$name}{y}=$y;
  $stations{$name}{status}=$status;
  $stations{$name}{code}=$code;
  $stations{$name}{collecteddate}=$collecteddate;
  $stations{$name}{connections}=$connections;
}

close S;

# Write the main stations page

open(W,">".$htmlpath."stations.html");

htmlhead(\*W,"master","British Railway Stations");

print W <<EOJ;
<p>
<img id="coastmap" alt="All stations" src="p.png" usemap="#map1"/>
<map id="map1" name="map1">
EOJ

# Parse station connection definitions
# Technically could be in reading loop above, but we might in future want
# to allow more flexible descriptions of stations that would need us to
# have read all the stations in first.
foreach $station (keys %stations) {
  # Construct connections definition for station
  # Syntax in stationcoords:
  # N=Waterbeach/Dullingham;S=Foxton/Shelford
  next unless defined $stations{$station}{connections};
  my @dir = split(/;/, $stations{$station}{connections});
  my @conn;
  foreach (@dir) {
    my ($dir, @dest) = split /[=\/]/, $_, -1;
    push @conn, map([$dir, $_], @dest);
  }
  $stations{$station}{connections} = \@conn;
}

# Link each station on the master map

foreach $station (keys %stations) {
  $linkablename=lc($station);
  $linkablename=~s/\W//g;
  print W qq{<area href="stnpages/$linkablename.html"
	     shape="circle"
	     coords="$stations{$station}{x},$stations{$station}{y},3"
	     alt="$station"
	     title="$station"/>\n};

# Generate each station's own page

  open(SP,">".$htmlpath."stnpages/".$linkablename.".html");

# Choose a region this station is in

  ($e,$n)=($stations{$station}{e},$stations{$station}{n});
  $rgn = "wholeuk"; $curprio=0;
  foreach $region (keys %regions) {
    next if (!$region);
    if ($e >= $regions{$region}{e1} &&
	$e <= $regions{$region}{e2} &&
	$n >= $regions{$region}{n2} &&
	$n <= $regions{$region}{n1} &&
	$curprio <= $regions{$region}{prio}) {
      $rgn=$region;
      $curprio=$regions{$region}{prio};
    }
  }

  htmlhead(\*SP,"station","$station",$rgn);


# Include hand-written fragment of station page

  if ( -e $htmlpath."stnfrags/".$linkablename.".frag.html") {
    open(SF, $htmlpath."stnfrags/".$linkablename.".frag.html");
    while(<SF>) {
      print SP;
    }
  } else {
    print SP "<h2>Pictures and Text to come...</h2>";
    if ($stations{$station}{status} eq "f") {
	print SP "<p>A friend sent me pictures of this station but they've not yet made their way here.  Sorry!</p>";
    } else {
	print SP "<p>I've visited this station and taken pictures of it, but they've not yet made their way here.  Sorry!</p>";
    }
  }

print SP <<EOJ;
<hr />
<p class="copyright">
All photographs are &copy; Alexandra Lanes  You may reproduce them anywhere
for any purpose.  Coastline maps are reproduced from Ordnance Survey
map data by permission of the Ordnance Survey &copy; Crown copyright
2001
</p>
</body>
</html>
EOJ

  close SP;

  # Construct connections map definition for this station
  if (@{$stations{$station}{connections}}) {
    open SM, "> stnmaps/$linkablename.stn.tmp"
	or die "stnmaps/$linkablename.stn.tmp: $!\n";
    $mainsym = "$stations{$station}{status}Splot";
    print SM qq<(LabelSpec{label="$station",symbol="$mainsym"}, [\n>;
    my $comma = 0;
    foreach (@{$stations{$station}{connections}}) {
      my ($dir, $dest) = @$_;
      my $invdir, $sym;
      if ($dest eq '') {
	  # Dummy connection to force layout
	  $invdir = $dir; $sym = "nullSplot";
      } elsif (exists $stations{$dest}) {
	  next unless exists $stations{$dest};
	  my ($invlink) =
	      grep($_->[1] eq $station, @{$stations{$dest}{connections}});
	  unless (defined $invlink) {
	  warn "non-reciprocal link $station -> $dest\n";
	  next;
	  }
	  $invdir = $invlink->[0];
	  $invdir =~ y/NESW/SWNE/;
	  $sym = "$stations{$dest}{status}Splot";
      } else {
	  $invdir = $dir; $sym = "Arrow";
	  $dest = "to $dest";
      }
      print SM ',' if $comma++;
      print SM qq<($dir,$invdir,LabelSpec{label="$dest",symbol="$sym"})\n>;
    }
    print SM qq<])\n>;
    close SM or die "close stnmaps/$linkablename.stn.tmp: $!\n";
    # Only make map if there's at least one connection.
    if ($comma) {
	push @mapstomake, $linkablename;
	mvifchange("stnmaps/$linkablename.stn.tmp",
		   "stnmaps/$linkablename.stn");
    }
  }
}

sub mvifchange {
    open my $a, "<", $_[0] or die "$_[0]: $!\n";
    open my $b, "<", $_[1];
    if (join('', <$a>) ne join('', <$b>)) {
	rename $_[0], $_[1] or die "rename $_[0] to $_[1]: $!\n";
    } else {
	unlink $_[0] or die "unlink $_[0]: $!\n";
    }
}

open MK, "> stnmaps/targets.mk" or die "stnmaps/targets.mk: $!\n";
print MK "PNGS = ", join "\\\n    ", map "$_.png", @mapstomake;
close MK or die "close stnmaps/targets.mk: $!\n";

foreach $region (keys %regions) {
  $e1=$regions{$region}{e1}; $n1=$regions{$region}{n1};
  $e2=$regions{$region}{e2}; $n2=$regions{$region}{n2};
  $x1=int($xorigin+($e1/$scale)); $y1=int($yorigin-($n1/$scale));
  $x2=int($xorigin+($e2/$scale)); $y2=int($yorigin-($n2/$scale));
  if ($region ne "wholeuk") {
    print W qq{<area href="regions/$region.html"
	       shape="rect"
	       coords="$x1,$y1,$x2,$y2"
	       alt="$regions{$region}{fullname}"
	       title="$regions{$region}{fullname}"/>\n};
  }
}

print W "</map></p>\n";

# Include hand-written fragment of master map page.

open (WF,$htmlpath."stations.frag.html");
while(<WF>) {
  print W;
}
close WF;

print W "</body></html>\n";
close W;

open(P,">".$htmlpath."p.png");
binmode P;
print P $coastline->png;
close P;

# Generate a region page for each region

foreach $region (keys %regions) {
  next if (!$region);
  open (W, ">".$htmlpath."regions/$region.html");
  htmlhead(\*W,"region",$regions{$region}{fullname},$region);
  print W <<EOJ;
<p>
<img id="coastmap" alt="$regions{$region}{fullname}" src="../maps/$region.png" usemap="#map1"></img>
<map id="map1" name="map1">
EOJ

  $coastline=GD::Image->new($htmlpath."maps/$region.500.png");

  $yes=$coastline->colorAllocate(255,0,0);
  $no=$coastline->colorAllocate(0,0,255);
  $heritage=$coastline->colorAllocate(0,128,0);
  $friend=$coastline->colorAllocate(128,0,128);
  $closed=$coastline->colorAllocate(0,0,0);

  $scale=abs($regions{$region}{n1}-$regions{$region}{n2})/500;
  print "$scale\n";

  $laststn="";

  foreach $station (sort(keys %stations)) {
    $e=$stations{$station}{e};
    $n=$stations{$station}{n};
    $status=$stations{$station}{status};

    if($status eq "y") {
      $colour=$yes;
    } elsif($status eq "n") {
      $colour=$no;
    } elsif($status eq "h") {
      $colour=$heritage;
    } elsif($status eq "f") {
      $colour=$friend;
    } elsif($status eq "c") {
      $colour=$closed;
    }

    if ($e >= $regions{$region}{e1} &&
	$e <= $regions{$region}{e2} &&
	$n >= $regions{$region}{n2} &&
	$n <= $regions{$region}{n1}) {
      $x=int(($e-$regions{$region}{e1})/$scale);
      $y=500-int(($n-$regions{$region}{n2})/$scale);
#      $coastline->arc($x,$y,7,7,0,360,$colour);
#      $coastline->fill($x,$y,$colour);
      $coastline->filledArc($x,$y,7,7,0,360,$colour);

      if (substr($station,0,1) ne $laststn && $laststn ne "") {
	print substr($station,0,1);
	print W "<br/>\n";
      }

      $linkablename=lc($station);
      $linkablename=~s/\W//g;
      print W qq{<area href="../stnpages/$linkablename.html"
		 shape="circle"
		 coords="$x,$y,4"
		 title="$station"><a href="../stnpages/$linkablename.html">
		 $station</a></area>\n};
      $laststn=substr($station,0,1);
    }
  }

  print W <<EOJ;
</map>
</p>
<hr />
<p class="copyright">
All photographs are &copy; Alexandra Lanes.  You may reproduce them anywhere
for any purpose.  Coastline maps are reproduced from Ordnance Survey
map data by permission of the Ordnance Survey &copy; Crown copyright
2001
</p>
</body></html>
EOJ

  close W;

  open (R,">".$htmlpath."maps/$region.png");
  binmode R;
  print R $coastline->png;
  close R;
}

sub htmlhead {
  $fh = shift;
  $type = shift;
  $title = shift;
  $region = shift;

  print $fh <<EOJ;
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
     <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"><head>
     <meta charset="utf-8" />
  <link rel="stylesheet" type="text/css" href="/~owend/osd.css" title="OSD"/>
  <title>$title</title></head>
  <body><div class="header">
EOJ

  if ($type eq "master") {
    print $fh qq{<a href="stations.html"><img id="ctxmap" alt="Britain >" src="maps/wholeuk.100.png"/></a>};
  } elsif ($type eq "station" || $type eq "region") {
    print $fh qq{<a href="../stations.html"><img id="ctxmap" alt="Britain >" src="../maps/wholeuk.100.png"/></a>};
    print $fh qq{<a href="../regions/$region.html"><img id="localmap" alt="$regions{$region}{fullname} >" src="../maps/$region.100.png"/></a>};
  };
  if ($type eq "station") {
    if (-e $htmlpath."stnmaps/$linkablename.png") {
      print $fh qq{<img id="neighbourmap" src="../stnmaps/$linkablename.png" alt="$title" usemap="#neighbours" />};
    }
    open (NM, $htmlpath."stnmaps/$linkablename.map");
    while (<NM>) {
      print $fh $_;
    }
  }

  print $fh "<h1>$title</h1>";

  if ($type eq "station") {
# Basic station page metadata

print $fh <<EOJ;
<table class="stnmetadata">
<tr class="crscode">
<td>CRS Code</td>
<td><a href="http://www.livedepartureboards.co.uk/ldb/summary.aspx?T=$stations{$station}{code}">$stations{$station}{code}</a></td>
</tr>
<tr class="collecteddate">
<td>Collected date</td>
<td>$stations{$station}{collecteddate}</td>
</tr>
</table>
EOJ

}
print $fh "</div>";

}
