#! /usr/bin/perl

# flaneth - flash and ethernet
# 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 - 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];



my $var_on_off_size = max( file_size( $dir . "/var_on.txt" ), file_size( $dir . "/var_off.txt" ) );
my $var_1_0_size = max( file_size( $dir . "/var_1.txt" ), file_size( $dir . "/var_0.txt" ) );

die( "variable too long (only 255 characters are allowed)\n" ) if( max( $var_on_off_size, $var_1_0_size ) > 255 );



# 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;

  $line =~ s/__VERSION__/$VERSION/g;
  for( my $i = 1; $i <= 8; $i++ ) {
    my $var;
    $var = chr2str( 0x80 + $i, $var_on_off_size );
    $line =~ s/__VAR_ONOFF_${i}__/$var/g;
    $var = chr2str( 0x90 + $i, $var_1_0_size );
    $line =~ s/__VAR_10_${i}__/$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 = textfile2code( $filename )
sub textfile2code
{
  my $filename = shift;

  my $txt = "";

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

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


  close( TEXTFILE );

  return $txt;
}



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

  my $txt = "";

  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 ) );
    }
    $txt .= "\"\n";
    last if( $i < 0x10 );
  }

  close( BINFILE );

  return $txt;
}



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

  open( TEXTFILE, "<$filename" ) or die( "cannot open \"$filename\" for reading: $!\n" );
  my $line = <TEXTFILE>;
  close( TEXTFILE );

  return "\"" . str_esc( $line ) . "\"";
}



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

print OUTPUT <<EOF;
//content for webpages
// - characters from 0x80..0xFF indicate 1 character of a variable
//   - e.g. "\\x80\\x80\\x80" indicates to insert the first 3 characters of varibale 0x80
//   - for meaning of variables, see HttpGetVariable

EOF

print OUTPUT <<EOF;
#define HttpBadRequestHeaderSize 121
const char PROGMEM HttpBadRequest[] =
"HTTP/1.0 400 Bad Request\\r\\n"
"Server: flaneth (ATMEGA128) by blinkenarea.org\\r\\n"
"Connection: close\\r\\n"
"Content-Type: text/html\\r\\n"
"\\r\\n"
EOF
print( OUTPUT textfile2code( $dir . "/bad_request.html" ) );
print OUTPUT <<EOF;
;

EOF

print OUTPUT <<EOF;
#define HttpNotFoundHeaderSize 119
const char PROGMEM HttpNotFound[] =
"HTTP/1.0 404 Not Found\\r\\n"
"Server: flaneth (ATMEGA128) by blinkenarea.org\\r\\n"
"Connection: close\\r\\n"
"Content-Type: text/html\\r\\n"
"\\r\\n"
EOF
print( OUTPUT textfile2code( $dir . "/not_found.html" ) );
print OUTPUT <<EOF;
;

EOF

print OUTPUT <<EOF;
#define HttpIndexHeaderSize 112
const char PROGMEM HttpIndex[] =
"HTTP/1.0 200 Ok\\r\\n"
"Server: flaneth (ATMEGA128) by blinkenarea.org\\r\\n"
"Connection: close\\r\\n"
"Content-Type: text/html\\r\\n"
"\\r\\n"
EOF
print( OUTPUT textfile2code( $dir . "/index.html" ) );
print OUTPUT <<EOF;
;

EOF

print OUTPUT <<EOF;
#define HttpImg1HeaderSize 112
const char PROGMEM HttpImg1[] =
"HTTP/1.0 200 Ok\\r\\n"
"Server: flaneth (ATMEGA128) by blinkenarea.org\\r\\n"
"Connection: close\\r\\n"
"Content-Type: image/png\\r\\n"
"\\r\\n"
EOF
print( OUTPUT binfile2code( $dir . "/image_on.png" ) );
print OUTPUT <<EOF;
;

EOF

print OUTPUT <<EOF;
#define HttpImg0HeaderSize 112
const char PROGMEM HttpImg0[] =
"HTTP/1.0 200 Ok\\r\\n"
"Server: flaneth (ATMEGA128) by blinkenarea.org\\r\\n"
"Connection: close\\r\\n"
"Content-Type: image/png\\r\\n"
"\\r\\n"
EOF
print( OUTPUT binfile2code( $dir . "/image_off.png" ) );
print OUTPUT <<EOF;
;

EOF

print OUTPUT <<EOF;
//text to fill in for variables
// - variables 0x81..0x88: filled with "On"- or "Off"-text (depending on output state 1..8)
// - variables 0x91..0x98: filled with "1"- or "0"-text (depending on output state 1..8)

EOF

print( OUTPUT 'const char PROGMEM HttpVarUnknown[] = ' . textfile2str( $dir . "/var_unknown.txt" ) . ";\n" );
print( OUTPUT 'const char PROGMEM HttpVarOn[] = ' . textfile2str( $dir . "/var_on.txt" ) . ";\n" );
print( OUTPUT 'const char PROGMEM HttpVarOff[] = ' . textfile2str( $dir . "/var_off.txt" ) . ";\n" );
print( OUTPUT 'const char PROGMEM HttpVar1[] = ' . textfile2str( $dir . "/var_1.txt" ) . ";\n" );
print( OUTPUT 'const char PROGMEM HttpVar0[] = ' . textfile2str( $dir . "/var_0.txt" ) . ";\n" );
print( OUTPUT "\n" );

close( OUTPUT );

