#!/usr/bin/perl

require "../cgi-lib.pl";
ReadParse(*in);
print "Content-type: text/html\n\n";

head();
body();
foot();

sub body {
    init();
    print "<font size=+1><b>Lego Scale Converter</b></font><br>\n";
    print "<form>\n";
    print "<table><tr><td>\n";
    print "How much is: <input type=text name=from size=5 value=\"$in{from}\">\n";
    $in{from} =~ s/,/./g;
    print "<select name=ftype>\n";
    foreach (sort { $units{$a}{order} <=> $units{$b}{order}; } (keys %units)) {
	print "<option value=\"$_\"";
	print " selected" if($in{ftype} eq $_);
	print ">$units{$_}{name}</option>\n";
    }
    print "</select>\n";

    print "<input type=checkbox".(($in{precision}) ? " checked" : "")." name=precision value=1><font size=-1>Extra Geeky Precision!</font>\n";

    print "<br>Fig scale:\n";
    print "<select name=stype>\n";
    foreach (sort { $scales{$a}{order} <=> $scales{$b}{order}; } (keys %scales)) {
	print "<option value=\"$_\"";
	print " selected" if($in{stype} eq $_);
	print ">$scales{$_}{name}</option>\n";
    }
    print "</select>\n";
    $size = $in{size} || "6";
    $fscale = $in{fscale} || "foot";
    print "&nbsp;Assumed fig height: <input type=text size=4 name=size value=\"$size\">\n";
    print "<select name=fscale>\n";
    foreach (sort { $units{$a}{order} <=> $units{$b}{order}; } (keys %units)) {
	next if(/mf|stud|plate|brick|base/);
	print "<option value=\"$_\"";
	print " selected" if($fscale eq $_);
	print ">$units{$_}{name}</option>\n";
    }
    print "</select>\n";
    print "</td></tr><tr><td align=center>";
    print "<input type=submit value=\"Convert\">";
    print "<input type=reset value=\"Reset\">";
    print "</td></tr></table\n";
    
    print "</form>\n";

    if($in{from} =~ /^\s*\d+\.?\d*\s*$/ || $in{from} =~ /^\s*\.\d+\s*$/) {
	if($in{size} =~ /^\s*\d+\.?\d*\s*$/ || $in{size} =~ /^\s*\.\d+\s*$/) {
	    if($units{$in{ftype}}{hlen} =~ /^[\d\.]+(mm|in)$/) {
		if($units{$in{ftype}}{hlen} =~ /^([\d\.]+)mm$/) {
		    $mmlen = $1*$in{from};
		    $inlen = $mmlen/25.4;
		} elsif($units{$in{ftype}}{hlen} =~ /^([\d\.]+)in$/) {
		    $inlen = $1*$in{from};
		    $mmlen = $inlen*25.4;
		}
		if($scales{$in{stype}}{hlen} =~ /^([\d\.]+)mm$/) { $fmmht = $1; }
		else { $fmmht = 42; } #why wouldnt it?
		if($units{$in{fscale}}{hlen} =~ /^([\d\.]+)in$/) {
		    $mfinlen = $mmlen/(($fmmht)/($in{size}*$1));
		    $mfmmlen = $mfinlen*25.4;
		}
		elsif($units{$in{fscale}}{hlen} =~ /^([\d\.]+)mm$/) {
		    $mfmmlen = $mmlen/(($fmmht)/($in{size}*$1));
		    $mfinlen = $mfmmlen/25.4;
		}
	    } else {
		if($units{$in{ftype}}{hlen} =~ /^([\d\.]+)mfmm$/) {
		    $mfmmlen = $1*$in{from};
		    $mfinlen = $mfmmlen/25.4;
		} elsif($units{$in{ftype}}{hlen} =~ /^([\d\.]+)mfin$/) {
		    $mfinlen = $1*$in{from};
		    $mfmmlen = $mfinlen*25.4;
		}
		if($scales{$in{stype}}{hlen} =~ /^([\d\.]+)mm$/) { $fmmht = $1; }
		else { $fmmht = 42; } #why wouldnt it?
		if($units{$in{fscale}}{hlen} =~ /^([\d\.]+)in$/) {
		    $mmlen = ($mfinlen*$fmmht)/($in{size}*$1);
		    $inlen = $mmlen/25.4;
		} elsif($units{$in{fscale}}{hlen} =~ /^([\d\.]+)mm$/) {
		    $mmlen = ($mfmmlen*$fmmht)/($in{size}*$1);
		    $inlen = $mmlen/25.4;
		}
	    }
	    print "<table>\n";
	    foreach $m ("brick","fig","real") {
		print "<tr><td>\n";
		print "<table border=1 width=100\%>\n";
		$r1 = "";
		$r2 = "";
		foreach $unit (sort { $units{$a}{order} <=> $units{$b}{order}; } (keys %units)) {
		    next if($units{$unit}{mtype} ne $m);
		    $r1 .= "<td><B>";
		    if($m eq "fig") {
			$r1 .= ($in{stype} eq "minifig") ? "mini" : "tech. ";
		    }
		    $r1 .= "$units{$unit}{name}</B></td>\n";
		    $r2 .= "<td>";
		    $val = 0;
		    if($units{$unit}{hlen} =~ /^([\d\.]+)(\w+)$/) { ($tmult,$tunit) = ($1,$2); }
		    else { $val = "ERROR!\n"; ($tmult,$tunit) = (1,"mm"); }
		    if($tunit eq "mm") { $val = ($mmlen/$tmult); }
		    elsif($tunit eq "in") { $val = ($inlen/$tmult); }
		    elsif($tunit eq "mfmm") { $val = ($mfmmlen/$tmult); }
		    elsif($tunit eq "mfin") { $val = ($mfinlen/$tmult); }
		    else { $val = "error"; }
		    if($in{precision}) {
			$r2 .= $val;
		    } else {
			$r2 .= sprintf("%2.2f",$val);
		    }
		    $r2 .= "</td>\n";
		}
		print "<tr>$r1</tr>\n<tr>$r2</tr>\n";
		print "</table>\n";
		print "</td></tr>\n";
	    }
	    print "</table>\n";
	} else {
	    print "Invalid assumed height!<br>\n";
	}
    } elsif($in{from}) {
	print "Invalid value!<br>\n";
    }
}

sub init {
    %units = (
	      stud => {
		  name => "studs",
		  hlen => "8mm",
		  order => 1,
		  mtype => "brick",
	      },
	      plate => {
		  name => "plates",
		  hlen => "3.2mm",
		  order => 2,
		  mtype => "brick",
	      },
	      brick => {
		  name => "bricks",
		  hlen => "9.6mm",
		  order => 3,
		  mtype => "brick",
	      },
	      base32 => {
		  name => "32x32 baseplates",
		  hlen => "256mm",
		  order => 4,
		  mtype => "brick",
	      },
	      base48 => {
		  name => "48x48 baseplates",
		  hlen => "384mm",
		  order => 5,
		  mtype => "brick",
	      },
	      milli => {
		  name => "millimeters",
		  hlen => "1mm",
		  order => 6,
		  mtype => "real",
	      },
	      centi => {
		  name => "centimeters",
		  hlen => "10mm",
		  order => 7,
		  mtype => "real",
	      },
	      inch => {
		  name => "inches",
		  hlen => "1in",
		  order => 8,
		  mtype => "real",
	      },
	      foot => {
		  name => "feet",
		  hlen => "12in",
		  order => 9,
		  mtype => "real",
	      },
	      yard => {
		  name => "yards",
		  hlen => "36in",
		  order => 10,
		  mtype => "real",
	      },
	      meter => {
		  name => "meters",
		  hlen => "1000mm",
		  order => 11,
		  mtype => "real",
	      },
	      kilo => {
		  name => "kilometers",
		  hlen => "1000000mm",
		  order => 12,
		  mtype => "real",
	      },
	      mile => {
		  name => "miles",
		  hlen => "63360in",
		  order => 13,
		  mtype => "real",
	      },
	      mfin => {
		  name => "fig inches",
		  hlen => "1mfin",
		  order => 14,
		  mtype => "fig",
	      },
	      mfft => {
		  name => "fig feet",
		  hlen => "12mfin",
		  order => 15,
		  mtype => "fig",
	      },
	      mfyd => {
		  name => "fig yards",
		  hlen => "36mfin",
		  order => 16,
		  mtype => "fig",
	      },
	      mfm => {
		  name => "fig meters",
		  hlen => "1000mfmm",
		  order => 17,
		  mtype => "fig",
	      },
	      mfkm => {
		  name => "fig kilometers",
		  hlen => "1000000mfmm",
		  order => 18,
		  mtype => "fig",
	      },
	      mfmi => {
		  name => "fig miles",
		  hlen => "63360mfin",
		  order => 19,
		  mtype => "fig",
	      },
	      );
    %scales = (
	       minifig => {
		   name => "mini",
		   hlen => "42mm",
		   order => 1,
	       },
	       technic => {
		   name => "technic",
		   hlen => "81mm",
		   order => 2,
	       },
	       );
}

sub head {
    print "<html><body>\n";
}

sub foot {
    print "</body></html>\n";
}
