#!/usr/bin/perl -w

use strict;
use integer;

($ARGV[0] && $ARGV[1]) || die "Usage: $0 infile.cpl outfile\n";

my $NEWLINES = 0;

my %keywords=&cplkeywords();
my %chars1=&getchars1();
my %charsn=&getcharsn();


open(SRC, "< $ARGV[0]") || die "Can't open file $ARGV[0]\n";
my @source = <SRC>;
close(SRC);

open(DEST, "> $ARGV[1].cpl") || die "Can't open/create file $ARGV[1].cpl\n";


#remove comments    
for (@source) { s/(.*?);.*/$1/ }

# tokenize and find all words
my @words;
my $line;

@words = split(/[\W]/,join("\n",@source));

my %wordh;
my $i = 0;
foreach $_ (@words){
	if (!(/^\d+$/) && !(defined $wordh{$_}) && !(defined $keywords{$_}))
	{
	  $wordh{$_}= &alphacounter($i);
		$i = $i+1;
	}
}

#print join("\n", %wordh);

# replace the mappings and blank lines and stuff
foreach $_ (@source){
	s/^\s*(.*?)\s*$/$1/;
	s/(.*?);.*/$1/;
	$line = &replacewords($_);

	if($NEWLINES==1){
	    print DEST "$line\n";	
	}else{
	    if(!($line eq "")){ 
    		if(substr($line, length($line)-1,1) =~ /\)/){
	    	    print DEST "$line";			
		}else{
	    	    print DEST "$line\n";		    
		}
	    }
	}
}

close(DEST);

#print out the translation table
my ($key,$value);
open(MAP, "> $ARGV[1].map") || die "Can't open/create file $ARGV[1].map\n";
while (($key,$value) = each %wordh) {
	print MAP "$key->$value\n";
}  

close(MAP);

############# FINISHED

sub replacewords{
	my $test;
	$test = $_[0];
	$test || return "";
	$_ = $test;
	if(/^(.*?)(\w+)(.*)/){
#		print "#$2\n";
		if (exists $wordh{$2}){
			return "$1". $wordh{$2} . &replacewords($3);		
		}else{
			return "$1$2" . &replacewords($3);		
		}			
	}else{
		return $test;
	}

}


sub getchars1{
(
	1 , "a" 
, 2 , "b" 
, 3 , "d" 
, 4 , "e" 
, 5 , "f" 
, 6 , "g" 
, 7 , "h" 
, 8 , "i" 
, 9 , "j" 
, 10 , "k" 
, 11 , "l" 
, 12 , "m" 
, 13 , "n" 
, 14 , "p" 
, 15 , "q" 
, 16 , "r" 
, 17 , "s" 
, 18 , "t" 
, 19 , "u" 
, 20 , "v" 
, 21 , "w" 
, 22 , "x" 
, 23 , "y" 
, 0 , "z" 
);
}

sub getcharsn{
(
	1 , "a" 
, 2 , "b" 
, 3 , "d" 
, 4 , "e" 
, 5 , "f" 
, 6 , "g" 
, 7 , "h" 
, 8 , "i" 
, 9 , "j" 
, 10 , "k" 
, 11 , "l" 
, 12 , "m" 
, 13 , "n" 
, 14 , "p" 
, 15 , "q" 
, 16 , "r" 
, 17 , "s" 
, 18 , "t" 
, 19 , "u" 
, 20 , "v" 
, 21 , "w" 
, 22 , "x" 
, 23 , "y" 
, 24 , "z" 
, 0 , "0" 
, 25 , "1" 
, 26 , "2" 
, 27 , "3" 
, 28 , "4" 
, 29 , "5" 
, 30 , "6" 
, 31 , "7" 
, 32 , "8" 
, 33 , "9" 
);
}

sub alphacounter{
	# there should be no c and o at the beginning, because of: "cp" and "on" 
	my $i = $_[0];
	my ($f,$s);
	if ($i <= 23){
		return $chars1{$i};
	}else{
		$f = $i / 34;
		$s = $i % 34;		
		return $chars1{$f} . $charsn{$s};
	}
}

sub cplkeywords{
	( "team", 1
	, "config", 1
	, "cp", 1
	, "env", 1
	, "stdcpl" , 1
	, "cnf" , 1
	, "bool", 1
	, "fact", 1
	, "led", 1
	, "or", 1
	, "while", 1
	, "false", 1
	, "hard", 1
	, "ctest", 1
	, "string", 1
	, "local", 1
	, "switch", 1
	, "not", 1
	, "cond", 1
	, "stop", 1
	, "soft", 1
	, "dimx", 1
	, "action", 1
	, "actuator", 1
	, "infra", 1
	, "setf", 1
	, "send", 1
	, "start", 1
	, "fncall", 1
	, "protect", 1
	, "int", 1
	, "sensor", 1
	, "hall", 1
	, "aref", 1
	, "receive", 1
	, "resume", 1
	, "progn", 1
	, "real", 1
	, "motor", 1
	, "and", 1
	, "return", 1
	, "true", 1
	, "wait", 1
	, "init", 1
	
	, "on", 1
	, "off", 1
	, "reverse", 1
	, "slowreverse", 1
	, "fastreverse", 1
	, "halt", 1
	, "forward", 1
	, "slowforward", 1
	, "fastforward", 1
	, "_stop", 1
	, "_wait", 1
	, "_start", 1
	, "_resume", 1
	, "_error", 1
	, "_pend", 1
	, "interrupt", 1
	, "short_delay", 1
	, "long_delay", 1
	, "serial_enable", 1
	, "serial_disable", 1
	, "serial_raise", 1
	, "serial_lower", 1
	, "pend_enable", 1
	, "pend_disable", 1
	, "pend_raise", 1
	, "pend_lower", 1
	, "wait_enable", 1
	, "wait_disable", 1
	, "wait_raise", 1
	, "wait_lower", 1
	, "reset", 1
	, "init", 1
	, "_send", 1
	, "_receive", 1
	, "cplc", 1
	
	, "switch1", 1
	, "switch2", 1
	, "switch3", 1
	, "switch4", 1
	, "switch5", 1
	, "switch6", 1
	, "b_switch1", 1
	, "b_switch2", 1
	, "b_switch3", 1
	, "b_switch4", 1
	, "b_switch5", 1
	, "b_switch6", 1
	, "h_e_sense", 1
	, "b_h_e_sense", 1
	, "powersense", 1
	, "b_powersense", 1
	, "ldr1", 1
	, "ldr2", 1
	, "ldr3", 1
	, "ldr4", 1
	, "b_ldr1", 1
	, "b_ldr2", 1
	, "b_ldr3", 1
	, "b_ldr4", 1
	, "infra1", 1
	, "infra2", 1
	, "infra3", 1
	, "infra4", 1
	, "b_infra1", 1
	, "b_infra2", 1
	, "b_infra3", 1
	, "b_infra4", 1
	, "random", 1
	, "b_random", 1
	, "light1", 1
	, "light2", 1
	, "light3", 1
	, "light4", 1
	, "light5", 1
	, "light6", 1
	, "light7", 1
	, "light8", 1
	, "b_light1", 1
	, "b_light2", 1
	, "b_light3", 1
	, "b_light4", 1
	, "b_light5", 1
	, "b_light6", 1
	, "b_light7", 1
	, "b_light8", 1
	, "motor1", 1
	, "motor2", 1
	, "motor3", 1
	, "motor4", 1
	, "b_motor1", 1
	, "b_motor2", 1
	, "b_motor3", 1
	, "b_motor4", 1
	, "seed", 1
	, "b_seed", 1

	, "team1", 1
	, "team2", 1
	, "team3", 1
	, "team4", 1
	);
}
