#!/usr/bin/perl

use strict;

if ( $#ARGV < 0 ) {
	print "usage: pdic2c.pl normalizeSize patternDictionary.txt\n";
	exit 1;
}

my $outputNormalizeSize = shift @ARGV;
if ( $outputNormalizeSize == 0 )
{
	print "error: normalizeSize must be > 0\n";
	print "usage: pdic2c.pl normalizeSize patternDictionary.txt\n";
	exit 1;
}

my %nameMap = ();
my @nameArray = ();
my @patterns = ();
my $wholePointNum = 0;
my $wholeStrokeNum = 0;

while (<>) {
	chomp;
	my ($data, $comment) = /^([^#]*?)\s+#\s+(.*)$/;
	chop $comment;
	my ($name, $kind, $correction, $normalizeSize, $pointsString) = $data =~ /^"([^"]+)" (\d+) (-?\d+) (\d+) (.*)|\s+$/; #"
	my $index = $wholePointNum;
	my $pointCount = 0;
	$pointsString =~ s/^|//;
	if ( not exists $nameMap{$name} ) {
		push @nameArray, $name;
		$nameMap{$name} = $#nameArray;
	}
	my @strokesString = split /\|/, $pointsString;
	my @strokes = ();
	foreach my $strokeString ( @strokesString ) {
		my @points = map {/\(\s*(\d+)\s*,\s*(\d+)\s*\)/; [$1, $2]} ($strokeString =~ /\(\s*\d+\s*,\s*\d+\s*\)/g);
		next if (!@points);
		push @strokes, \@points;
#print "$points[0]->[0] $points[0]->[1]\n";
		$pointCount += $#points + 1;
		$pointCount ++ ; # PenUpMarker
	}
	push @patterns, {
		name => $name,
		code => $nameMap{$name},
		correction => $correction,
		kind => $kind,
		normalizeSize => $normalizeSize,
		index => $index,
		pointCount => $pointCount,
		strokes => \@strokes,
		comment => $comment,
	};
	$wholePointNum += $pointCount;
	$wholeStrokeNum += $#strokes + 1;
}


print <<'EOT';
/*---------------------------------------------------------------------------*
  Header File
 *---------------------------------------------------------------------------*/

#ifndef PATTERN_DICT_H_
#define PATTERN_DICT_H_

#ifdef __cplusplus
extern "C" {
#endif

EOT

my $patternNum = $#patterns + 1;
my $codeNum    = $#nameArray + 1;

print <<"EOT";
#include <nitro/prc/types.h>


#define PDIC_WHOLE_POINT_NUM             $wholePointNum
#define PDIC_WHOLE_STROKE_NUM            $wholeStrokeNum
#define PDIC_PATTERN_NUM                 $patternNum
#define PDIC_CODE_NUM                    $codeNum
#define PDIC_NORMALIZE_SIZE              $outputNormalizeSize


extern PRCDictionary PatternDictionary;
extern char* PatternName[PDIC_CODE_NUM];


#ifdef __cplusplus
} /* extern "C" */
#endif

/* PATTERN_DICT_H_ */
#endif

/*---------------------------------------------------------------------------*
  End of File
 *---------------------------------------------------------------------------*/

/*---------------------------------------------------------------------------*
  Source File
 *---------------------------------------------------------------------------*/

#include <nitro.h>
#include <nitro/prc/types.h>

#include "patternDict.h"

PRCPoint      PatternDictionaryPointArray[PDIC_WHOLE_POINT_NUM] =
{
EOT

foreach my $pattern (@patterns) {
	my $strokes = $pattern->{strokes};
	my $normalizeSize = $pattern->{normalizeSize};
	foreach my $points (@$strokes) {
		foreach my $point (@$points) {
			my ($x, $y);
			$x = int($point->[0] * $outputNormalizeSize / $normalizeSize);
			$y = int($point->[1] * $outputNormalizeSize / $normalizeSize);
			print <<"EOT";
    {$x, $y},
EOT
		}
		print <<"EOT";
    {-1, -1},
EOT
	}
}

print <<'EOT';
};

PRCDictionaryEntry PatternDictionaryEntries[PDIC_PATTERN_NUM] =
{
EOT

foreach my $pattern (@patterns) {
	my $strokeCount = $#{$pattern->{strokes}}+1;
	print <<"EOT";
    {
        TRUE, $pattern->{kind}, $pattern->{code}, $pattern->{correction}, NULL,        // $pattern->{comment}
        $pattern->{index}, $pattern->{pointCount}, $strokeCount
    },
EOT
}

print <<'EOT';
};

PRCDictionary PatternDictionary =
{
    PatternDictionaryEntries,       /* entries */
    PDIC_PATTERN_NUM,               /* entrySize */
    PatternDictionaryPointArray,    /* pointArray */
    PDIC_WHOLE_POINT_NUM,           /* pointArraySize */

    PDIC_NORMALIZE_SIZE,            /* normalizeSize */
};

char* PatternName[PDIC_CODE_NUM] =
{
EOT

foreach my $name (@nameArray) {
	print <<"EOT";
    "$name",
EOT
}

print <<'EOT';
};

/*---------------------------------------------------------------------------*
  End of File
 *---------------------------------------------------------------------------*/
EOT
