#!/usr/bin/perl
use lib '.';
require "./cgi-lib.pl";

@themeratings = (
		 "I had a friend once who liked this theme. This friend is no more.",
		 "I can't stand this theme. I refuse to have anything to do with it.",
		 "I won't buy it, but I have nothing against anyone else buying it.",
		 "This theme's ok, but I don't own any. Maybe someday.",
		 "I own a couple of 'em.",
		 "I like this theme. It's got some cool stuff.",
		 "I'm trying to be complete in this theme. I buy just about whatever I can from it.",
		 "They make OTHER themes?",
		 "All Other themes are the residue from the dust on the dirt spit upon by the slave monkeys of the trumpeters in the caravan of Grecian Gods carrying the All-Holy pedestal upon which this Theme resides.",
		 );

@subthemeratings = (
		    "This is the dumbest subtheme I've ever seen. Even mentioning it makes me ill. Excuse me, I have to go.",
		    "I really don't like this subtheme at all. It's a waste of ABS.",
		    "This subtheme never really sparked my interest. I suppose some people like it though, so it's not all bad.",
		    "I don't have any of this subtheme. I've thought about getting some once or twice, but never did.",
		    "I have a couple sets in this subtheme.",
		    "This subtheme had some nice pieces and designs. I like it.",
		    "It's really an incredible subtheme. I've got most of them.",
		    "If I could, I'd own this complete subtheme 3.84x10^8 times over.",
		    "I wrote my doctoral thesis on the greatness of this subtheme.",
		    );

$script = $0;
$script =~ s/^.*\///;

%themes = (
	   AD => {
	       name => "Adventurers",
	       subs => {
		   di => "Dino Island",
		   eg => "Egyptian",
		   jg => "Jungle",
		   or => "Orient Expedition",
	       },
	   },
           AG => { name => "Agents", },
           AL => { name => "Atlantis", },
	   AQ => {
	       name => "Aquazone",
	       subs => {
		   an => "Aquanauts",
		   ar => "Aquaraiders",
		   as => "Aquasharks",
		   hy => "Hydronauts",
		   st => "Stingrays",
	       },
	   },
           AR => { name => "Architecture", subs => { } },
           AT => { name => "Alpha Team", },
           AV => { name => "Avatar", },
           BI => { name => "Bionicle", },
           BO => { name => "Boats", },
           BT => { name => "Ben 10", },
           BV => { name => "Belville", },
	   CA => {
	       name => "Castle",
	       subs => {
		   bf => "Black Falcons",
		   bk => "Black Knights",
		   bl => "Bulls",
		   bn => "Bandit Ninjas",
		   bs => "Blue Samurai",
		   cl => "Classic Castle",
		   cr => "Crusaders",
		   df => "Dark Forest",
		   dm => "Dragon Masters",
		   em => "Emperor's Ninjas",
		   fe => "Fantasy Era",
		   fk => "Fright Knights",
		   fm => "Forestmen",
		   kg => "Kingdoms",
		   lk => "Leo's Knights",
		   rk => "Royal Knights",
		   wp => "Wolfpack",
	       },
	   },
           CH => { name => "Legends of Chima", subs => { }, },
           CL => { name => "Clikits", },
           CM => { name => "Collectible Minfigures", subs => { }, },
           # CO is reserved (Collecting)
           CR => { name => "Creator", },
           DC => { name => "Dacta", subs => { }, },
           DP => { name => "Disney Princess", subs => { }, },
           DI => { name => "Dino / Dino 2010 / Dino Attack", },
           DU => { name => "Duplo", },
           EF => { name => "Exo Force", },
           EL => { name => "Elves", subs => { }, },
           FL => { name => "Fabuland", },
           FR => { name => "Friends", subs => { }, },
           FS => { name => "Freestyle / Basic", },
           GA => { name => "Games", },
           GL => { name => "Galidor", },
           HF => { name => "Hero Factory", subs => { }, },
           HM => { name => "Homemaker", },
           HP => { name => "Harry Potter", },
           # IC is reserved (Inner Child)
           IJ => { name => "Indiana Jones", },
           JW => { name => "Jurassic World", },
           LO => { name => "Lord of the Rings / The Hobbit", },
           LE => { name => "LEGO Movie", },
           # LM is reserved (LEGO Modification)
           LR => { name => "Lone Ranger", },
           # LS is reserved (LEGO Sorting)
           MC => { name => "Minecraft", },
           MF => { name => "Monster Fighters", },
           MO => { name => "Modular Town", subs => { }, },
           MT => { name => "Model Team", subs => { }, },
           MX => { name => "Mixels", subs => { }, },
           NG => { name => "Ninjago", subs => { } },
           NX => { name => "Nexo Knights", subs => { } },
           PA => { name => "Paradisia", subs => { }, },
	   PI => {
	       name => "Pirates",
	       subs => {
		   ia => "Imperial Armada (green torso)",
		   ig => "Imperials (red torso)",
		   is => "Islanders",
		   pi => "Pirates",
		   so => "Soldiers (blue torso)",
	       },
	   },
           PM => { name => "Power Miners", },
           PO => { name => "Primo", },
           PP => { name => "Prince of Persia", },
           PQ => { name => "Pharaoh's Quest", },
	   PR => {
	       name => "Promotional",
	       subs => {
		   kb => "Kabaya",
		   mc => "McDonalds",
		   sh => "Shell",
	       },
	   },
           RA => { name => "Racers", },
           RB => { name => "Robotics / Mindstorms", },
           SB => { name => "Spongebob", },
           SC => { name => "Scala", },
           SD => { name => "Scooby Doo", },
           SI => { name => "The Simpsons", },
           SL => { name => "Sculpture", subs => { } },
	   SO => { name => "Sports",
		   subs => {
		       fb => "Football / Soccer",
		       ba => "Basketball",
		       hk => "Hockey",
		   },
           },
	   SP => {
	       name => "Space",
	       subs => {
		   aq => "Alien Conquest",
		   cl => "Classic Space",
		   bt1 => "Blacktron 1",
		   bt2 => "Blacktron 2",
		   ex => "Exploriens",
		   fu => "Futuron",
		   gs => "Galaxy Squad",
		   ip => "Ice Planet 2002",
		   is => "Insectoids",
		   lm => "Life on Mars",
		   mm => "Mars Mission",
		   mt => "Mtron",
		   rf => "Robo Force",
		   sp1 => "Space Police 1",
		   sp2 => "Space Police 2",
		   sp3 => "Space Police 3",
		   sy => "Spyrius",
		   uf => "UFO",
		   ut => "Unitron",
	       },
	   },
           SR => { name => "Speed Racer", },
           ST => { name => "Studios", },
           SU => { name => "Superheroes", subs => { }, },
	   SW => {
	       name => "Star Wars",
	       subs => {
		   cw => "Clone Wars",
		   pt => "Prequel Trilogy",
		   ot => "Original Trilogy",
		   nt => "Sequel Trilogy",
		   rb => "Rebels",
		   uc => "Ultimate Collectors Sets",
	       },
	   },
	   TC => {
	       name => "Technic",
	       subs => {
		   bc => "Bionicle",
		   cs => "Cyberslam",
		   eb => "Expert Builder",
		   pl => "Tech Play",
		   rr => "Robo Riders",
		   sl => "Slizer / Throwbots",
		   tc => "Standard Technic",
		   sw => "Star Wars Technic",
	       },
	   },
           TM => { name => "Teenage Mutant Ninja Turtles", },
	   TO => {
	       name => "Town",
	       subs => {
		   at => "Arctic",
		   cl => "Generic Town",
		   cn => "Construction",
		   re => "Rescue / Emergency",
		   sr => "Service / Repair",
		   fl => "Flight",
		   tr => "Transportation",
		   ra => "Race",
		   ad => "Adventure / Thrill Seekers",
		   na => "Nautica",
		   lc => "Launch Command",
		   tc => "Time Cruisers",
		   tt => "Time Twisters",
	       },
	   },
           TR => { name => "Trains", },
           TS => { name => "Toy Story", },
           UN => { name => "Underground", },
           # VL is reserved (Virtual LEGO)
           WV => { name => "Winter Village", subs => { }, },
           WW => { name => "Wild West", },
           # YB is reserved (Year of Birth)
           ZN => { name => "Znap", },
	   );

%radios = (
	     H => {
		 name => "Bag Holes (H)",
		 desc => "Easily the most important question. Why do you think Lego puts those little holes in the Lego baggies?",
		 opts => {
		     ri => "So they're easier to rip.",
		     rr => "They're more rip resistant with holes.",
		     ap => "If they didn't have holes, they would explode in airplanes!",
		     su => "So kiddies don't suffocate.",
		     al => "So the Lego doesn't suffocate! (It's alive!)",
		     sa => "Think of how much money Lego saves on plastic by saving the holes!",
		     sp => "Think of how much money Lego spends by making the holes!",
		     lp => "The bags weigh less with holes-- cheaper to ship!",
		     aw => "OK, the holes let the AIR out, so it weighs less!",
		     zl => "Like some veggies, Lego wilts without exposure to air. It turns into Mega Bloks.",
		     mu => "It's so the bags don't muffle that magical clinking noise.",
		     '!?' => "Who cares?!",
		 },
	     },
	     M => {
		 name => "Membership (M)",
		 desc => "Are you a member in a Lego club?",
		 opts => {
		     '+' => "Yes! I'm a member!",
		     '-' => "No, I'm not a member",
		 }
	     },
	   );

%multiples = (
	     VL => {
		 name => "Virtual Lego (VL)",
		 desc => "Do you do any work with virtual Lego? (Ex: \"VLr\" or \"VLdw\" or \"VLwvr\")",
		 opts => {
		     r => "I render virtual Lego models.",
		     v => "I view virtual Lego models.",
		     d => "I build virtual Lego models.",
		     w => "I WRITE virtual Lego software.",
		 }
	     },
	     );

%ratings = (
	    '#' => {
		name => "Number of sets",
		desc => "About how many sets do you have?",
		default => "",
		opts => [
			 "0-9 (I'm just starting)",
			 "10-49 (a bunch)",
			 "50-99 (quite a bit)",
			 "100-249 (a lot)",
			 "250-499 (a whole lot)",
			 "500-999 (a remarkable amount)",
			 "1000+ (an insane amount)",
			 ],
		},
	    P => {
		name => "Number of pieces",
		desc => "About how many pieces do you have?",
		default => "",
		opts => [
			 "<1,000 (a little bit)",
			 "1,000-4,999 (a big box full)",
			 "5,000-9,999 (a crate full)",
			 "10,000-49,999 (a closet full)",
			 "50,000-99,999 (a small room's worth)",
			 "100,000-499,999 (a big room full)",
			 "500,000+ (gobs and gobs)",
		     ],
	    },
	    A => {
		name => "Auctions",
		desc => "Lego auctions are a big part of the Lego community. What do you think of 'em?",
		default => "---",
		opts => [
			 "I block out any news group that ever had an auction posted to it ever.",
			 "Money-grubbing sales-mongering scum!  I loathe auctions!",
			 "I tried an auction. Once. It was stupid.",
			 "Whatever. I mostly just ignore them.",
			 "Auctions are ok. I bought a couple things once.",
			 "I may have run an auction once. And/or bought a bunch of stuff from them too.",
			 "I pretty much always have an auction going. And/or I'm always buying from them.",
			 "I financed/built my summer ranch via Lego auctions.",
			 ],
		},
	    CO => {
		name => "Set Collecting",
		desc => "Lots of people collect sets in order to be complete. And many buy strictly for parts. How do you collect?",
		default => "---",
		opts => [
			 "I won't buy sets. I only trade or buy pieces individually.",
			 "I only buy sets on deep discount. Mostly I buy bricks in service packs and in part auctions.",
			 "I have a couple sets. But mostly I buy sets for parts, or buy pieces specificially.",
			 "I buy sets when they're cool, but I'll also buy parts in auctions, etc.",
			 "I mostly collect sets, but occaisionally I'll pick up a service pack or parts individually.",
			 "I live for sets. That's all I'll buy. But if I happen across some good pieces, I'll get 'em.",
			 "If I ever find sets that I own with missing pieces, I'll throw the rest of the set out.",
			 ],
		},
	    S => {
		name => "Specialized Pieces",
		desc => "There's lots of specialized pieces out there, like BURPs, 1x2x5 bricks, the rope bridges, etc, etc. How do you feel about this stuff?",
		default => "-----",
		opts => [
			 "Bricks are way too specialized. I use plates instead, and burn anything else.",
			 "Why do they make minifigs? Talk about a specialized piece!",
			 "All I buy are Freestyle sets and buckets",
			 "I *WOULD* have bought that set, but...",
			 "Is the CRAPP really necessary?",
			 "Who cares? It's all Lego.",
			 "I use them without a second thought",
			 "I've found all kinds of uses for those specialized pieces!",
			 "I scrounge up all of them I can find. I've built K2 out of BURPs.",
			 "I buy sets just for the specialized pieces, and don't use the other stuff",
			 "I burn regular bricks. What else can you build with them, other than bonfires?",
			 ],
	    },
	    LS => {
		name => "Sorting Lego",
		desc => "To what degree do you sort your Lego?",
		default => "----",
		opts => [
			 "I keep it all over the house, car, and office. I don't have a designated place for it.",
			 "It's all in a big pile on the floor.",
			 "I keep it in buckets, drawers, shoeboxes-- whatever it'll fit into.",
			 "I sorted it once. I hated it.",
			 "Maybe someday I'll start sorting...",
			 "I keep minifigs and their accessories separated, the rest is all together.",
			 "Standard bricks in one box, teeny pieces in another, minifigs in another, and one box for misc pieces.",
			 "It bugs me when I find a slope in my box of arches.",
			 "That red 2x4 doesn't go in THAT red 2x4 box! Those other red 2x4's were minted in 1983! That one's clearly an '86.",
			 ],
	    },
	    LM => {
		name => "Lego Modification",
		desc => "How sacred is a Lego brick to you? What do you think of modifying Lego elemets?",
		default => "----",
		opts => [
			 "I'm working on a special nuke that will destroy those who modify pieces.",
			 "Does the Bible/Torah/Qu'ran not say \"Thou shalt not deface a brick\"?",
			 "I can't figure out why people do this. It just doesn't seem right.",
			 "I don't, but if you want to, go right ahead.",
			 "Whatever. Some cool models are made with modified bricks.",
			 "I've come up with some designs that would require it.",
			 "I've got a model or two with some saw marks.",
			 "There's so much you just can't do with off-the-shelf bricks!",
			 "I think I have 2 1x6 plates that I haven't modified yet. But I've been saving those for this weekend.",
			 ],
	    },
	    MOC => {
		name => "MOCs",
		desc => "(My Own Creations) Do you build stuff from a set or build your own things?",
		default => "----",
		opts => [
			 "I only build sets that Lego created. I won't even build Samsonite sets.",
			 "I just build sets. I don't build any MOCs at all.",
			 "I modify official sets sometimes, but that's it.",
			 "I mostly build sets, but I've built a MOC once or twice",
			 "I build both sets and MOCs pretty equally.",
			 "I build more MOCs than sets.",
			 "I mainly build MOCs, though I do enjoy sitting down and building a set sometimes.",
			 "I build the set once, but that's only to ensure all the pieces are there.",
			 "Instructions? How boring. I never build a set per the instructions.",
			 "I shield my eyes from Lego instructions. They're for whimps.",
			 ],
	    },
	    );


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

sub head {
    print "Content-type: text/html\n\n";
    print "<html>\n";
    print "<head><title>Lego Geek Code Generator, Parser, \& Info</title></head>\n";
    print "<body>\n";
}

sub init {
    ReadParse(*in);
}

sub body {
    if($in{'func'} ne "generate" && $in{'func'} ne "translate") {
	#help, info, etc.
	print "<font size=+1><b>Lego Geek Code</b></font><br>\n";
	print "<font size=-1>Adapted somewhat by David Eaton based on Derek Schin's <a href=\"http://www.geocities.com/SoHo/Lofts/9639/lcodev22.txt\">
most recent version</a></font>\n";
	print "<br><br>\n";
	print "You may have seen 'Geek Code' before. It usually looks like some sort of gibberish appended to the end of someone's email or news posting. And usually it's got to do with some fairly geeky type stuff, like whether they use emacs or vi, UNIX or LINUX, or some such garbage that us Lego fans for the most part couldn't care less about. Well, now's your chance to get them back with Lego Geek Code.  And you can let everyone know how you feel about Lego issues, particular themes, etc. (Provided they know how to interpret it!)<br>\n";
	print "<br>\nLego Geek Code (LGC) should always start with \"LEGO: \". After that, specific codes are added in (usually uppercase letters), and separated by whitespace. Each of these codes represents a different opinion that you may have about something Lego related. Most of these codes look like: \"LS++\" or \"A---\". The more + signs you see, the more you like/agree with something, the more - signs you see, the less you like/agree with something.<br>\n";
	print "<br>\nIf your opinion varies from (for example) \"MOC-\" to \"MOC+++\", you can write \"MOC-/+++\"<br>\n";
	print "If you have no opinion on something, you can put an \"\@\" sign after it. For example \"S@\" instead of, say someone else, who might put \"S++\".<br>\n";
	print "If you WANT something more, but don't do it/have it currently, you can precede the rating with a \">\" symbol. For example, \"LS>+++\" would mean \"I want to sort my Lego this way (+++), but I don't yet.\".<br>\n";
	print "<br>\n";
	print "If you don't really care about one aspect or another, you'd probably do best just to skip over it and leave it out of your code. That way, you don't have to give your opinion on EVERY theme, and on anything else you don't want to bother answering. Of course, you can if you want. You just may end up with a huge LGC :)<br>\n";
	print "<br>\nThis website has a tool to interpret LGC, and it doesn't really care what order you put things in (or even if you put them in multiple times). But for the most part, just to be nice, try and follow the order given here, just so we can try to have some more consistent codes.<br>\n";
	print "<br>\n<font size=+1><b>Themes</b></font><br>\n";
	print "<br>\nThemes are probably the most complex part of the LGC. Let's get them out of the way first. (They also go first too-- go figure.)<br>\n";
	print "<br>\nFirst, select a theme (see theme table below). Now rate it:<br>\n";
	$rat = "---";
	print "<table>\n";
	while($themeratings[get_rating_index($rat,"theme")]) {
	    print "<tr><td>$rat</td><td>".$themeratings[get_rating_index($rat,'theme')]."</td></tr>\n";
	    if($rat !~ s/-//) {
		$rat .= "+";
	    }
	}
	print "</table>\n";
	print "<br>\nBy the way-- don't worry if you don't match the description perfectly. You might like a theme a little bit and therefore want to rate it at \"+\", even if you don't have any. Don't worry. Go right ahead. Think of the explanations given here as general guidelines. Your specifics may vary. Anyway, you should now have something like: \"LEGO: AQ++\" (AQ = Aquazone, see table below for the complete list)<br>\n";
	print "<br>\nIf you've got a favorite set in this theme, put its number in parentheses: \"LEGO: AQ++(6195)\". Try not to use the actual name of the set, since this may differ from language to language.<br>\n";
	print "<br>\nIf you're complete in this theme, add a \"c\" after it. Ex: \"LEGO: AQ++(6195)c\". And again, it's the spirit that counts. If your definition of complete is just all the sets released in the US, or that you need every set ever made in that theme, complete with box, instructions and reciept, feel free to use that definition.<br>\n";
	print "<br>\nIf you want to comment on the theme's subthemes, we need a subtheme 'block' to put your comments in. This block goes inside square brackets: \"[\" and \"]\". Within these brackets, you can denote your feelings on particular subthemes, much in the same way that themes are done. For example:<br>\n";
	print "[as- an++(6195) hy+++c ar---]<br>\n";
	print "Subtheme ratings are pretty much the same as theme ratings:<br>\n";
	$rat = "---";
	print "<table>\n";
	while($subthemeratings[get_rating_index($rat,"subtheme")]) {
	    print "<tr><td>$rat</td><td>".$subthemeratings[get_rating_index($rat,'subtheme')]."</td></tr>\n";
	    if($rat !~ s/-//) {
		$rat .= "+";
	    }
	}
	print "</table>\n";
	print "<br>\nFinally, if you feel the exact same on any two themes or subthemes, you can combine them using commas: \"AQ,SP++\" or \"AQ++[an+++ ar,hy-]\"<br>\n";
	print "<br>\nSome examples of the code so far:<br>\n";
	print "LEGO: SP+++c AQ[ar,an++ hy,st--]<br>\n(I like space a lot, and am complete in it, I'm indifferent about Aquazone, I like Aquanauts and Aquaraiders, but not Hydronauts or Stingrays)<br>\n";
	print "LEGO: TC,BV++ TO@(6390) <br>\n(I like Technic and Belville, but don't have any opinion on the Town theme, but my favorite set from Town is 6390)<br>\n";
	print "LEGO: CA++/++++(6080)[bf++ fk--(6097)c]<br>\n(I range from liking castle to REALLY liking castle. My favorite castle set is 6080. I like the Black Falcons, but don't like Fright Knights. I'm complete in Fright Knights, and my favorite Fright Knight set is 6097.)<br>\n";
	print "<br>\nMaybe you're confused. If so, don't be. If you're not sure exactly what a certain code means, you're not sure if you did it right, or something, don't worry. Just for you (well, ok, for other people too), we've got the LGC <a href=\"$script?func=translate\">interpreter</a>. You can type in whatever you want, and it'll tell you (as best it can) what it means in Lego Geek Code. It's a great way to double check your own code or to figure out someone else's without having to go through it step by step.<br>\n";
	print "<br>\nTheme & Subtheme Table<br>\n";
	print "<table border=1 cellpadding=2>\n";
	foreach $theme (sort (keys %themes)) {
	    print "<tr><td bgcolor=#cccccc>$theme</td><td colspan=2 bgcolor=#cccccc>$themes{$theme}{name}</td></tr>\n";
	    foreach $sub (sort (keys %{$themes{$theme}{subs}})) {
		print "<tr><td></td><td bgcolor=#eeeeee>$sub</td><td bgcolor=#eeeeee>$themes{$theme}{subs}{$sub}</td></tr>\n";
	    }
	}
	print "</table>\n";
	print "<br>\n";
	print "<br>\n<font size=+1><b>Ratings Questions</b></font><br>\n";
	print "<br>\nThe most common part (aside from themes) in the LGC are ratings questions. That means you rate each thing on the list according to how you feel about it (or whatever) using only '+' and '-' signs. (Or '/' or '>' or '\@' signs, see the very beginning). Here we go:<br>\n<br>\n";

	foreach $r (sort (keys %ratings)) {
	    print "<b>$ratings{$r}{name}</b><br>\n$ratings{$r}{desc}<br>\n";
	    print "<table>\n";
	    $rat = $ratings{$r}{default};
	    while($ratings{$r}{opts}[get_rating_index($rat,$r)]) {
		print "<tr><td>$r$rat</td><td>".$ratings{$r}{opts}[get_rating_index($rat,$r)]."</td></tr>\n";
		if($rat !~ s/-//) {
		    $rat .= "+";
		}
	    }
	    print "</table><br>\n";
	}

	print "<font size=+1><b>Other Questions</b></font><br>\n<br>\n";
	
	foreach $r (sort (keys %radios)) {
	    print "<b>$radios{$r}{name}</b><br>\n$radios{$r}{desc}<br>\n";
	    print "<table>\n";
	    foreach (sort (keys %{$radios{$r}{opts}})) {
		print "<tr><td>$r$_</td><td>$radios{$r}{opts}{$_}</td></tr>\n";
	    }
	    print "</table><br>\n"
	}

	foreach $m (sort (keys %multiples)) {
	    print "<b>$multiples{$m}{name}</b><br>\n$multiples{$m}{desc}<br>\n";
	    print "<table>\n";
	    foreach (sort (keys %{$multiples{$m}{opts}})) {
		print "<tr><td>$_</td><td>$multiples{$m}{opts}{$_}</td></tr>\n";
	    }
	    print "</table><br>\n"
	}

	print "<br>\n";
	print "<b>Age and Sex</b><br>\n";
	print "Finally, you can specify how old you are and your gender. First, simply add a \"YB\" to the end of your code, followed by your birth year. Ex: \"YB72\" or \"YB1981\". Next, add an \"m\" afterwards if you're male, or an \"f\" if you're female. Also, if you so desire, you can specify the age of your Inner Child. But instead, write \"IC\" and the age of your inner child (not you inner child's birth year!). You can also specify gender after you Inner Child's age too. Ex: \"IC12f\"<br>\n";
	print "<br>\n";
	print "That's about all there is to it. Have fun!<br><br><br>\n";
	print "What? You <b>still</b> have questions? Well, if you don't want to worry about doing all this right, we've provided a little LGC <a href=\"$script?func=generate\">generator</a> you can use to make your own LGC without having to scroll all around trying desperately to find what rating meant what, etc. Play well!\n";

	return;
    }
    elsif($in{'func'} eq "translate") {
	#parse that code, baby!
	print "For information on the Lego Geek Code as interpreted here, see the <a href=$script>Lego Geek Code Overview</a><br>\n";
	print "<form method=get>\n";
	print "<textarea name=interpret rows=4 cols=60>$in{interpret}</textarea><br>\n";
	print "<input type=hidden name=func value=\"translate\">\n";
	print "<input type=submit value=\"Interpret\">\n";
	print "</form>\n";
	if($in{'interpret'} =~ /\S/) {
	    $in{'interpret'} =~ s/^\s*lego\:?//;
	    $remcode = $in{'interpret'} . " ENDCODE";
	    while($remcode =~ s/^\s*([A-Z\#]+[,A-Z]*[^A-Z\#]*)\s+([A-Z\#])/$2/) {
		$code = $1;
		$code =~ /^([A-Z\#]+)[^A-Z]/;
		$base = $1;
		print "<!-- CODE:\"$code\" BASE:\"$base\" -->\n";
		if($themes{$base}) {
		    my(@th) = ();
		    my($complete) = 0;
		    my($favset) = "";
		    my($range) = 0;
		    my($subth) = "";
		    my($val) = "";
		    my($high) = "";
		    my($low) = "";
		    my($rating) = "";
		    my(@names) = ();
		    #does this cover more than 1 theme?
		    if($code =~ /^([A-Z]+,[,A-Z]*)([^A-Z]*)/) {
			$val = $2;
			@th = split /,/,$1;
		    }
		    else {
			$th[0] = $base;
			$code =~ /^[A-Z]+([^A-Z]*)/;
			$val = $1;
		    }
		    #does it include subthemes?
		    if($val =~ s/\[([^\]]*)\]//) {
			$subth = $1;
		    }
		    #does it have a favorite set?
		    if($val =~ s/\((.*)\)//) {
			$favset = $1;
		    }
		    #are they complete in this theme?
		    if($val =~ s/c//) {
			$complete = 1;
		    }
		    #do they have a range of their rating? --/+ , etc?
		    if($val =~ s/([\+\-]*)\/([\+\-]*)//) {
			$range = 1;
			$low = $1;
			$high = $2;
		    }
		    #do they have a rating?
		    if($val =~ s/([\+\-]+)//) {
			$rating = $1;
		    }
		    $no_opinion = 0;
		    if(($rating =~ /^\s*$/) && (!$range) && ($val =~ s/\@//)) {
			$no_opinion = 1;
		    }
		    $desire = 0;
		    if($val =~ s/\>//) {
			$desire = 1;
		    }
		    
		    print "<b>How I feel about <font color=#008000>";
		    foreach (@th) {
			$names[@names] = $themes{$_}{name};
		    }
		    print (join ",",@names);
		    print "</font>:</b><br>\n";
		    if($desire) { print "<b>I <u>wish</u> I could say:</b><br>\n"; }
		    if($range) {
			print "<b>I fluctuate from:</b> ".$themeratings[get_rating_index($low,"theme")]."<br>\n<b>to:</b> ".$themeratings[get_rating_index($high,"theme")]."<br>\n";
		    }
		    else {
			if($no_opinion) { print "I don't have an opinion on this theme.<br>\n"; }
			else { print $themeratings[get_rating_index($rating,"theme")]."<br>\n"; }
		    }
		    
		    if($complete) {
			my($cflag) = 0;
			print "I'm actually complete in this theme!";
			foreach(@th) {
			    if($_ eq "SP" || $_ eq "TO" || $_ eq "TR" || $_ eq "TC" || $_ eq "PR" || $_ eq "FS" || $_ eq "CA") {
				$cflag = 1;
			    }
			}
			if($cflag) { print " And that means I have a <i>sick</i> amount of Lego!"; }
			print "<br>\n";
		    }
		    
		    if($favset =~ /\S/) {
			print "<b>My favorite set from ";
			if(@names > 1) { print "these themes "; }
			else { print "this theme "; }
			print "is</b> $favset<br>\n";
		    }
		    if($subth =~ /\S/) {
			my(@st,$sbcomplete,$sbfav,$sbrat,@sbnames);
			my(@subs) = split /\s+/,$subth;
		      SUBTHEME: foreach(@subs) {
			  print "<!-- subcode=\"$_\" -->\n";
			  @st = ();
			  $sbcomplete = 0;
			  $sbfav = "";
			  $sbrat = "";
			  @sbnames = ();
			  if(s/^(\w+,[\w,]+)//) {
			      my($tmp) = $1;
			      if($tmp =~ s/(\w\w+)c$/$1/) {
				  $sbcomplete = 1;
			      }
			      @st = split /,/,$tmp;
			  }
			  elsif(s/^(\w\w+)c//) {
			      $st[0] = $1;
			      $sbcomplete = 1;
			  }
			  elsif(s/^(\w+)//) {
			      $st[0] = $1;
			  }
			  else {
			      next SUBTHEME;
			  }
			  if(s/\((\d+)\)//) {
			      $sbfav = $1;
			  }
			  $range = 0;
			  $low = "";
			  $high = "";
			  $rating = "";
			  if(s/c//) {
			      $sbcomplete = 1;
			  }
			  if(s/([\+\-]*)\/([\+\-]*)//) {
			      $range = 1;
			      $low = $1;
			      $high = $2;
			  }
			  if(s/([\+\-]+)//) {
			      $rating = $1;
			  }
			  $no_opinion = 0;
			  if(($rating =~ /^\s*$/) && (!$range) && (s/\@//)) {
			      $no_opinion = 1;
			  }
			  $desire = 0;
			  if(s/\>//) {
			      $desire = 1;
			  }
			  
		        THEME: foreach (@st) {
			    foreach $theme (@th) {
				if($themes{$theme}{subs}{$_}) { $sbnames[@sbnames] = $themes{$theme}{subs}{$_}; next THEME; }
			    }
			}
			  if(@sbnames) {
			    print "<font size=-1>";
			    print "<b><font color=#0000ff>";
			    print join(",",@sbnames) . ": ";
			    print "</font>";
			    if($range) {
				if($desire) { print " <b>I wish I could say:</b>"; }
				print "<br>\nMy feelings on this subtheme vary.<br>\nFrom:</b>";
				print $subthemeratings[get_rating_index($low,"subtheme")];
				print "<br>\n<b>To:</b> ";
				print $subthemeratings[get_rating_index($high,"subtheme")];
			    }
			    else {
				if($desire) { print " I wish I could say:"; }
				print "</b>";
				if($no_opinion) { print "I have no opinion about this subtheme."; }
				else { print $subthemeratings[get_rating_index($rating,"subtheme")]; }
			    }
			    print "<br>\n";
			    if($sbcomplete) { print "I'm complete in this subtheme!<br>\n"; }
			    if($sbfav) { print "<b>My favorite set from this subtheme is</b> $sbfav<br>\n"; }
			    print "</font>\n";
			}
		      }
		    }
		    print "</font><br>\n";
		}
		elsif($multiples{$base}) {
		    print "<font size=+1 color=#008000><b>$multiples{$base}{name}</b></font><br>\n<b>$multiples{$base}{desc}</b><br>\n";
		    $code =~ s/^\Q$base\E//;
		    $flag = 0;
		    if($code =~ s/\>//) {
			print "<b>I <u>wish</u> I could say:</b><br>\n";
		    }
		    while($code =~ s/(\w)//) {
			$flag = 1;
			if($multiples{$base}{opts}{$1}) {
			    print "$multiples{$base}{opts}{$1}<br>\n";
			}
		    }
		    if(!$flag && $code =~ /\@/) {
			print "I have no opinion/comment about this.<br>\n";
		    }
		    print "<br>\n";
		}
		elsif($ratings{$base}) {
		    my($rating) = "";
		    my($low,$high);
		    print "<font size=+1 color=#008000><b>$ratings{$base}{name}</b></font><br>\n<b>$ratings{$base}{desc}</b><br>\n";
		    $code =~ s/^\Q$base\E//;
		    if($code =~ s/\>//) {
			print "<b>I <u>wish</u> I could say:</b><br>\n";
		    }
		    if($code =~ /([\+\-]*)\/([\+\-]*)/) {
			$low = $1;
			$high = $2;
			print "I range from: ";
			print $ratings{$base}{opts}[get_rating_index($low,"$base")];
			print "<br>\nTo: ";
			print $ratings{$base}{opts}[get_rating_index($high,"$base")];
		    }
		    else {
			$code =~ /([\+\-]+)/;
			$rating = $1;
			if(($rating =~ /^\s*$/) && ($code =~ /\@/)) {
			    print "I have no opinion/comment about this.";
			}
			else {
			    print $ratings{$base}{opts}[get_rating_index($rating,"$base")];
			}
		    }
		    print "<br>\n";
		    print "<br>\n";
		}
		elsif($radios{$base}) {
		    print "<font size=+1 color=#008000><b>$radios{$base}{name}</b></font><br>\n<b>$radios{$base}{desc}</b><br>\n";
		    $code =~ s/^\Q$base\E//;
		    if($code =~ /\>/) { print "<b>I wish I could say:</b> "; }
		    if($code =~ /(\S+)/) {
			if($radios{$base}{opts}{$1}) {
			    print "$radios{$base}{opts}{$1}<br>\n";
			}
			elsif($code =~ /\@/) {
			    print "I have no opinion/comment on this.<br>\n";
			}
		    }
		    print "<br>\n";
		}
		elsif($base eq 'YB') {
		    $code =~ /^YB(\d*)([mf]?)/;
		    $birth = $1;
		    $sex = $2;
		    print "<font size=+1 color=#008000><b>Age";
		    if($sex) {
			print " and Sex";
		    }
		    print "</b></font><br>\n";
		    if($birth < 100) { $birth += 1900; }
		    print "Born: $birth<br>\n";
		    if($sex) { print "Sex: ".(($sex eq "m") ? 'Male' : 'Female')."<br>\n"; }
		    print "<br>\n";
		}
		elsif($base eq 'IC') {
		    $code =~ /^IC(\d*)([mf]?)/;
		    $birth = $1;
		    $sex = $2;
		    print "<font size=+1 color=#008000><b>Inner Child's Age";
		    if($sex) {
			print " and Sex";
		    }
		    print "</b></font><br>\n";
		    print "Inner Child: $birth years old<br>\n";
		    if($sex) { print "Sex: ".(($sex eq "m") ? 'Male' : 'Female')."<br>\n"; }
		    print "<br>\n";
		}
		else {
		    if($base !~ /lego/i) {
			#?
			print "Couldnt parse element \"$code\" with base code \"$base\"<br>\n<br>\n";
		    }
		}
		if($code =~ /\s+([mf])\s*$/) {
		    $sex = $1;
		    print "<font size=+1 color=#008000><b>Age and Sex</b></font><br>\n";
		    print "Born: (Undisclosed)<br>\n";
		    if($sex) { print "Sex: ".(($sex eq "m") ? 'Male' : 'Female')."<br>\n"; }
		    print "<br>\n";
		}
	    }
	}
    }
    elsif($in{'func'} eq "generate") {
	print "Dave is hard at work making this generator function properly. But for now, it's not working. Actually, neither is Dave, most likely. He's lazy.<br>\n";
    }
}

sub foot {
    print "<br><br>\n";
    print "LGC shown here has been shamelessly stolen and adapted from <a href=\"http://www.geocities.com/SoHo/Lofts/9639/lcodev22.txt\">Derek Schin's version</a> of the LGC by <a href=\"mailto:dave\@suave.net\">David Eaton</a><br>\n";
    print "</body>\n";
    print "</html>\n";
}

sub get_rating_index {
    my($default);
    if($_[1] =~ /theme/i) { $default = "---"; }
    else { $default = $ratings{$_[1]}{default}; }
    if(($default =~ /-/) && ($_[0] =~ /-/) && (length($_[0]) > length($default))) {
	return 0;
    }
    my($rating) = 0;
    my($val) = $default;
    while(($val ne $_[0]) && ($rating <= 11)) {
	if($val =~ /\-/) { $val =~ s/\-//; }
	else{ $val .= "+"; }
	$rating++;
    }
    return $rating;
}


