#!/usr/bin/perl -w

my @grid;

open(CR,"out") or die $!;
while (<CR>) {
    chomp;
    push @grid,[map uc, split''];
}
close(CR);

use CGI qw[:standard start_table end_table start_Tr end_Tr];

print start_html{title=>"foo",style=><<'EOS'};
#grid { border-collapse: collapse; background: black; font-family: Verdana, sans-serif; font-size: large; border: 2px solid black;}
#grid td.c { background: white;  margin: 0px; vertical-align: middle; width: 2em; height: 2em;text-align: center; border: 2px solid black;}
#grid td > div { position:relative;margin:0;border:0;width:0;height:0; }
#grid td > span { font-weight: bolder; }
#grid td .num { left: 0em; top:-.5em; width: 2em; height: 2em; font-size: 60%; position: absolute; text-align:left; }
#grid td.empty { background: black; }
#map {border: 2px solid black; border-collapse: collapse; }
#map td {border: 1px solid black; font-size: 80%; padding-left: .2em; padding-right: .2em; text-align:center}
#map td input { width: 1em; font-weight: bolder; font-size: 120%; text-align: center }
#status { border: 2px solid black; padding: .3em; }
#status span { font-weight: bold; }
EOS

print script <<'EOS';
var used=new Array;
function setsq(str, l) {
    var e=str.split(':');
    var p=document.getElementById('sq'+e[0]).firstChild.data;
//    if (p.match(/[A-Z]/i))
    lunuse(p);
    if (l) luse(l);
    for(var i=0;i<e.length;i++) {
	document.getElementById('sq'+e[i]).firstChild.data=l?l.toUpperCase():' ';
    }
    update();
}
function luse(l) {
    used[used.length]=l.toUpperCase();
}
function lunuse(l) {
    used=used.join().replace(l,'').split();
}
function lused(l) {
    for(var i=0;i<used.length;i++)
	if (used[i]==l) {
	    return 1;
	}
    return 0;
}

function update() {
    var s='';
    for(var i='A'.charCodeAt(0);i<='Z'.charCodeAt(0);i++)
    {
	var j=String.fromCharCode(i);
	if (!lused(j)) s+=j;
    }
    document.getElementById('used').firstChild.data=s;
}
EOS

my %letters;

for (@grid) {
    for (@$_) {
	$letters{$_}++ if /[A-Z]/;
    }
}

my $num=keys %letters;

my @map=(1..$num);
for(1..100) {
    my ($num1,$num2)=(int rand $num, int rand $num);
    @map[$num1,$num2]=@map[$num2,$num1];
}
my %map;
my $j;
for my $i (keys %letters) {
    $map{$i}=$map[$j++];
}


my @ids=();

my $id;
local $"="";
print start_table{id=>'grid'};
for my $line (@grid) {
    print start_Tr;
    for my $c (@$line) {
	if ($c!~/[A-Z]/) {
	    print td{class=>'empty'};
	} else {
#	    my $n=$map[ord($c)-ord'A'];
	    my $n=$map{$c};
	    $id++;
	    print td{class=>'c'},div(span{class=>'num'},$n),span{id=>"sq$id"},'&nbsp;';
	    push @{$ids[$n]}, $id;
	}
    }
    print end_Tr;
}
print end_table;
print p;
print start_table{id=>'map'};

print start_form;
print Tr td[1..$num];
print Tr td[map {input{name=>$_,maxlength=>1,onchange=>"setsq('".join(':',@{$ids[$_]})."',this.value)"}} 1..$num];
print end_form;
print end_table;

print p{id=>'status'},'Unused: '.span{id=>'used'},join'','A'..'Z';
print end_html;
