#!/usr/bin/perl -w
#
#   This file is part of the KDE libraries
#
#   Copyright (C) 1999 Lars Knoll (knoll@mpi-hd.mpg.de)
#                 2004-2005 Nikolas Zimmermann (wildfox@kde.org)
#
#   This library is free software; you can redistribute it and/or
#   modify it under the terms of the GNU Library General Public
#   License as published by the Free Software Foundation; either
#   version 2 of the License, or (at your option) any later version.
#
#   This library is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
#   Library General Public License for more details.
#
#   You should have received a copy of the GNU Library General Public License
#   along with this library; see the file COPYING.LIB.  If not, write to
#   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
#   Boston, MA 02110-1301, USA.
#

use strict;

my $nsFull = $ARGV[1];
my $ns = $nsFull; $ns =~ s/K//;
my $basename = "cssvalues";
if (defined($ARGV[2]) && $ARGV[2] eq "-f") {
    my $inputfile = $ARGV[3];
    $inputfile =~ m/(.*)\.in/;
    $basename = $1;
}

my $filec = "$basename.c";
my $fileh = "$basename.h";
my $filein = "$basename.in";
my $filegperf = "$basename.gperf";

open IN, $filein or die "Can't open $filein\n";
open HEADER, ">$fileh" or die "Can't open $fileh\n";
open OUT, ">$filegperf" or die "Can't open $filegperf\n";

print OUT "%{\n/* This file is automatically generated from $filein by cssmakevalues, do not edit */\n#include \"$fileh\"\n%}\n";
print OUT "struct css_val {\n    const char* name;\n    int id;\n};\n\n";
print OUT "static const struct css_val *find${ns}Val (register const char *str, register unsigned int len);\n\n%%\n";

print HEADER "/* This file is automatically generated from $filein by cssmakevalues, do not edit */\n/* Copyright 1999 Lars Knoll */\n\n#ifndef ${nsFull}_CSSVALUES_H\n#define ${nsFull}_CSSVALUES_H\n\n";

my %amap = ();

my $num = 0;
if ($nsFull ne "KDOM") {
	$num = 10001; # Bigger than all values from HTML CSS

	print HEADER "#define ${ns}CSS_VAL_INVALID 0\n";
	print HEADER "#define ${ns}CSS_VAL_MIN $num\n";

    $num = $num - 1;
} else {
	print HEADER "#define CSS_VAL_INVALID 0\n";
	print HEADER "#define CSS_VAL_MIN 1\n";
}

my @a = ();

while (<IN>) {
    chomp;
    my $prop = $_;

	if(not($prop =~ /#/) and (length($prop) > 0)) {
	    $num = $num + 1;

	    my $up = uc($prop);
	    push(@a, $up);

		my $pup = $up;
		$pup =~ s/-/_/g;

	    $amap{$pup} = $num;
		
		if ($nsFull eq "KDOM") {
	    	print OUT $prop . ", CSS_VAL_" . $pup . "\n";
		    print HEADER "#define CSS_VAL_" . $pup . " " . $num . "\n";
		} else {
	    	print OUT $prop . ", ${ns}CSS_VAL_" . $pup . "\n";
		    print HEADER "#define ${ns}CSS_VAL_" . $pup . " " . $num . "\n";
		}
    }
}

close(IN);

if ($nsFull eq "KDOM") {
	print HEADER "#define CSS_VAL_MAX $num\n";
} else {
	print HEADER "#define ${ns}CSS_VAL_MAX $num\n";
}

print OUT "%%\n";
close OUT;

print HEADER "\nnamespace ${nsFull}\n{\n";
print HEADER "    const char* getSVGCSSValueName(unsigned short id);\n";
print HEADER "    int getSVGCSSValueID(const char *tagStr, int len);\n";
print HEADER "}\n";

print HEADER "\n#endif\n";
close HEADER;

my $result = system("gperf -c -a -L ANSI-C -G -D -E -C -o -t --key-positions=\"*\" -Nfind${ns}Val -Hhash_val -Wwordlist_val -D -s 3 $filegperf > $filec");
if ($result) {
  unlink "$filec";
  exit $result;
}

# Avoid clashes in parser.cpp, which includes both CSSValueKeywords.c & CSSPropertyNames.c
open F, "<$filec";
my $tmp = "";
while (<F>) {
    s/TOTAL_KEYWORDS/VAL_TOTAL_KEYWORDS/;
    s/MIN_WORD_LENGTH/VAL_MIN_WORD_LENGTH/;
    s/MAX_WORD_LENGTH/VAL_MAX_WORD_LENGTH/;
    s/MIN_HASH_VALUE/VAL_MIN_HASH_VALUE/;
    s/MAX_HASH_VALUE/VAL_MAX_HASH_VALUE/;
    s/lookup/lookupVal/g;
    $tmp = $tmp . $_;
}
close F;
open F, ">$filec";
print F $tmp;
close F;

# read the hash mappings (is there a better way?)
my %hmap = ();
open(IN, "< $filec");
my $i = 0;
while(<IN>) {
	my $lookFor = "CSS_VAL_";
	if ($nsFull ne "KDOM") {
		$lookFor = $ns . $lookFor;
	}

	if (/"[\w-]+", ${lookFor}([\w_]+)/) {
		$hmap{$amap{$1}} = $i;
		$i += 1;
	}
}
close(IN);  

open(OUT, ">> $filec");
print OUT "\nnamespace ${nsFull}\n{\n";
print OUT "\n\nstatic const unsigned short valList[] = {\n";
print OUT "    65535,\n";

while(defined (my $line = shift @a)) {
    my $l = $line;

	if(not($l =~ /#/) and (length($l) > 0)) {
		$l =~ y/-/_/;

    	die if !length($hmap{$amap{$l}});

	    print OUT "    " .$hmap{$amap{$l}}.",\n";
	}
}

my $lookFor = "CSS_VAL_MAX";
if ($nsFull ne "KDOM") {
	$lookFor = $ns . $lookFor;
}

print OUT "    65535\n};\n\n";
print OUT "const char *getSVGCSSValueID(unsigned short id)\n{\n";
print OUT "    if (!id || id > $lookFor) return \"\";\n";
print OUT "    return wordlist_val[valList[id]].name;\n";
print OUT "}\n";
print OUT "\nint getSVGCSSValueID(const char *tagStr, int len)\n";
print OUT "{\n";
print OUT "    const struct css_val *valPtr = find${ns}Val(tagStr, len);\n";
print OUT "    if(!valPtr)\n";
print OUT "      return 0;\n";
print OUT "    return valPtr->id;\n";
print OUT "}\n\n";
print OUT "}\n";
