#! /usr/bin/perl

# flaneth - flash and ethernet - dartboard mod
# version 0.1 date 2008-11-09
# Copyright (C) 2007-2008 Stefan Schuermans <stefan@schuermans.info>
# Copyleft: GNU public license V2 - http://www.gnu.org/copyleft/gpl.html
# a BlinkenArea project - http://www.blinkenarea.org/

use strict;

my $VERSION="version 0.1 date 2008-11-09";



die( "usage: $0 <http_dir> <http_content.inc>\n" ) if( @ARGV < 2 );

my $dir = @ARGV[0];
my $output = @ARGV[1];



# maximum
# usage: $m = max( $a, $b )
sub max
{
  my $a = shift;
  my $b = shift;
  return $a > $b ? $a : $b;
}



# convert a character to a string
# usage: $txt = chr2str( $ascii_code, $cnt )
sub chr2str
{
  my $ascii_code = shift;
  my $cnt = shift;

  my $txt = "";

  for( ; $cnt > 0; $cnt-- ) {
    $txt .= pack( "C", $ascii_code );
  }

  return $txt;
}



# c string escaping
# usage: $escaped = str_esc( $txt )
sub str_esc
{
  my $txt = shift;

  my $escaped = "";
  for( my $i = 0; $i < length( $txt ); $i++ ) {
    my $chr = substr( $txt, $i, 1 );
    if( $chr eq '\\' ) {
      $escaped .= "\\\\";
    } elsif( $chr eq '"' ) {
      $escaped .= "\\\"";
    } elsif( $chr eq "\t" ) {
      $escaped .= "\\t";
    } elsif( $chr eq "\r" ) {
      $escaped .= "\\r";
    } elsif( $chr eq "\n" ) {
      $escaped .= "\\n";
    } elsif( $chr ge ' ' && $chr le '~' ) {
      $escaped .= $chr;
    } else {
      $escaped .= sprintf( "\\x%02X", unpack( "C", $chr ) );
    }
  }

  return $escaped;
}



# replace variables
# usage: $line_replaced = var_replace( $line )
sub var_replace
{
  my $line = shift;

  my $var;
  $line =~ s/__VERSION__/$VERSION/g;
  $var = chr2str( 0x80, 1 );
  $line =~ s/__FACTOR__/$var/g;
  $var = chr2str( 0x90, 1 );
  $line =~ s/__VALUE_L__/$var/g;
  $var = chr2str( 0x91, 1 );
  $line =~ s/__VALUE_H__/$var/g;

  return $line;
}



# get file size
# usage: $size = file_size( $filename )
sub file_size
{
  my $filename = shift;

  my @info = stat( $filename );

  return @info[7] if( @info > 7 ); # @info[7] is the size (see documentation of stat)

  return 0;
}



# convert a text file to c code
# usage: ($code, $len) = textfile2code( $filename )
sub textfile2code
{
  my $filename = shift;

  my $txt = "";
  my $len = 0;

  open( TEXTFILE, "<$filename" ) or die ( "cannot open \"$filename\" for reading: $!\n" );

  my $line;
  while( $line = <TEXTFILE> ) {
    $line = var_replace( $line );
    $txt .= "\"" . str_esc( $line ) . "\"\n";
    $len += length( $line );
  }


  close( TEXTFILE );

  return ($txt, $len);
}



# convert a binary file to c code
# usage: ($code, $len) = binfile2code( $filename )
sub binfile2code
{
  my $filename = shift;

  my $txt = "";
  my $len = 0;

  open( BINFILE, "<$filename" ) or die ( "cannot open \"$filename\" for reading: $!\n" );
  binmode( BINFILE );

  my $val;
  while( 1 ) {
    $txt.= "\"";
    my $i;
    for( $i = 0; $i < 0x10; $i++ ) {
      read( BINFILE, $val, 1 ) or last;
      $txt .= sprintf( "\\x%02X", unpack( "C", $val ) );
      $len++;
    }
    $txt .= "\"\n";
    last if( $i < 0x10 );
  }

  close( BINFILE );

  return ($txt, $len);
}



# generate page
# usage: $page = gen_page( $ret, $file, $name, $ctype, $bin )
sub gen_page
{
  my $ret = shift;
  my $file = shift;
  my $name = shift;
  my $ctype = shift;
  my $bin = shift;

  my ($code, $len);
  if( $bin ) {
    ($code, $len) = binfile2code( $file );
  } else {
    ($code, $len) = textfile2code( $file );
  }

  my $header =
    "const char PROGMEM Http${name}[] =\n" .
    "\"HTTP/1.0 $ret\\r\\n\"\n" .
    "\"Server: flaneth (ATMEGA128) by blinkenarea.org\\r\\n\"\n" .
    "\"Connection: close\\r\\n\"\n" .
    "\"Content-Type: $ctype\\r\\n\"\n" .
    "\"Content-Length: $len\\r\\n\"\n" .
    "\"\\r\\n\"\n";
  my $hlen = length( $header );

  return "#define Http${name}HeaderSize $hlen\n$header$code;\n\n"
}

open( OUTPUT, ">", "$output" ) or die( "cannot open \"$output\" for writing: $!\n" );

print OUTPUT <<EOF;
//content for webpages
// - characters from 0x80..0xFF indicate a 1 character variable

EOF

print( OUTPUT gen_page( "400 Bad Request", "$dir/bad_request.html", "BadRequest", "text/html", 0 ) );
print( OUTPUT gen_page( "404 Not Found", "$dir/not_found.html", "NotFound", "text/html", 0 ) );
print( OUTPUT gen_page( "200 Ok", "$dir/index.html", "Index", "text/html", 0 ) );
print( OUTPUT gen_page( "200 Ok", "$dir/dart_no.xml", "DartNo", "text/xml", 0 ) );
print( OUTPUT gen_page( "200 Ok", "$dir/dart_1d.xml", "Dart1d", "text/xml", 0 ) );
print( OUTPUT gen_page( "200 Ok", "$dir/dart_2d.xml", "Dart2d", "text/xml", 0 ) );

close( OUTPUT );

