#!/usr/bin/perl
use integer;
use Cwd qw(getcwd realpath);

$idesettings{'PREFIX'}="/usr/local";
$idesettings{'NAME'}="";

$VERSION = "4S08";

$NI = "$idesettings{'PREFIX'}/libexec/ni";
$I6 = "$idesettings{'PREFIX'}/libexec/inform-6.31-biplatform";
$BLORB = "$idesettings{'PREFIX'}/libexec/cBlorb";

$idesettings{'EDITOR'} = '';
$idesettings{'EDITOR'}=$ENV{'VISUAL'};
$idesettings{'EDITOR'}=$ENV{'EDITOR'} unless ($idesettings{'EDITOR'});
unless ($idesettings{'EDITOR'}) {
    if ( -f "/usr/bin/editor" ) {
	$idesettings{'EDITOR'}="/usr/bin/editor"
	}
}
unless ($idesettings{'EDITOR'}) {
    if ( -x "/bin/ed" ) {
	$idesettings{'EDITOR'}="/bin/ed"
	}
}
$idesettings{'EDITORBG'}=0;

$idesettings{'BROWSER'} = '';
$idesettings{'BROWSER'} = $ENV{'BROWSER'};
$idesettings{'BROWSERBG'}=0;

$idesettings{'ZTERP'}="$idesettings{'PREFIX'}/libexec/dumb-frotz";
$idesettings{'ZTERPBG'}=0;
$idesettings{'GTERP'}="$idesettings{'PREFIX'}/libexec/dumb-glulxe";
$idesettings{'GTERPBG'}=0;

$CLEANUP = "";

print "Linux I7 shell, cheesy Perl edition, version $VERSION.\n";
print "  Adam Thornton (<adam\@io.com>), 2007\n\n\n\n";

$HOME = $ENV{'HOME'};
if ((! -d "$HOME/Inform/Documentation") or (! -d "$HOME/Inform/Extensions")) {
    print "This looks like the first time you've run Inform 7.\n";
    print "I will now create the directories Inform, Inform/Extensions, and\n";
    print "Inform/Documentation in your home directory ($HOME).\n\n";
    if (! -d "$HOME/Inform") {
	mkdir "$HOME/Inform";
    }
    if (! -d "$HOME/Inform/Extensions") {
	mkdir "$HOME/Inform/Extensions";
    }
    if (! -d "$HOME/Inform/Documentation") {
	mkdir "$HOME/Inform/Documentation";
    }
}

readideprefs("$HOME/.i7rc");

unless ($idesettings{'NAME'}) {
    $idesettings{'NAME'}=printprompt("Please enter your name > ");
    print "\n";
}

while (! -d "$idesettings{'PREFIX'}/share/inform7" ) {
    print "\n";
    print "I could not find the Inform 7 libraries under $idesettings{'PREFIX'}.\n";
    $idesettings{'PREFIX'}=printprompt("Please enter the path where you installed the i7 package > ");
}

writeideprefs();    

INTRO: while(1) {
    print "WELCOME TO INFORM 7\n\n\n";
    print "(S)tart a new project.\n";
    print "(O)pen an existing project.\n";
    print "(Q)uit.\n";
    $proj = getcwd();
    $_=printprompt();
    if (m/^S/i) {
	$proj=newproj();
	last INTRO if ($proj);
	next INTRO;
    }
    if (m/^R/i) {
	$proj=readproj();
	last INTRO if ($proj);
	next INTRO;
    }
    if (m/^O/i) {
	$proj=openproj();
	last INTRO if ($proj);
	next INTRO;
    }
    if (m/^Q/i) {
	print "Thanks for putting up with this so-called interface!\n";
	exit 0;
    }
    print "I don't see any $_ here!\n";
}

print "Story is at $l\n";
writeideprefs();
$oldpwd = getcwd();
chdir $l;
print "\n\n";

%settings = (
    'zcode'  => 5,
    'blorb'  => 1,
    'zsuf'   => 'z5',
    'suffix' => 'blorb',
    'format' => 'zcode',
	     );

readsettings("$l/Settings.plist");

%ni_settings = (
    'rules' => "--rules \"$idesettings{'PREFIX'}/share/inform7/Inform7/Extensions\""
		);

MAINLOOP: while(1) {
    print "MAIN MENU\n\n\n";
    if (! $idesettings{'BROWSER'}) {
	print "Set the environment variable BROWSER (or set your browser preferences in the\n";
	print " preference panel) to allow browsing the generated HTML index.\n";
    }
    if ($idesettings{'EDITOR'}) {
	print "(E)dit the story with $idesettings{'EDITOR'}.\n"
	} else {
	    print "Apply the editor of your choice (set in the preference panel) to\n";
	    print "$l/Source/story.ni\n";
	    print "\nAfter you have saved your work, do one of the following:\n";
	}  
    print "\n";
    print "(C)ompile the story.\n";
    print "(G)o -- compile and run the story.\n";
    print "(R)elease the story.\n";
    print "\n";
    if ($idesettings{'BROWSER'}) {
	print "(I)ndex -- open the generated story index with $idesettings{'BROWSER'}.\n\n";
    }
    print "Change (S)ettings.\n";
    print "(Q)uit.\n";
    $_ = printprompt();
    if ((m/^E/i) && ($idesettings{'EDITOR'})) {
	if ( -e "$l/Source/story.ni" ) {
	    my $cmd="\"$idesettings{'EDITOR'}\" \"$l/Source/story.ni\"";
	    if ($idesettings{'EDITORBG'}) {
		$cmd .= " &";
	    }
	    system($cmd);
	    print "\n\n";
	} else {
	    print "\n\n*** Cannot find story file! ***\n\n";
	}
    }
    if (m/^C/i) {
	$bad = compile();
	if ($bad) {
	    print "\n\n*** COMPILATION HAD ERRORS ***\n\n";
	} else {
	    print "\n\nCompile Succeeded: test your game by running ";
	    print "$l/Build/output.$settings{'zsuf'}";
	    print " with the $settings{'format'} interpreter of your choice\n\n";
	}
	next MAINLOOP;
    }
    if (m/^G/i) {
	$bad = compile();
	if ($bad) {
	    print "\n\n*** COMPILATION HAD ERRORS ***\n\n";
	} else {
	    print "\n\nCompile Succeeded.  Proceeding to interpreter.";
	    my $terp=($settings{'format'} eq 'glulx' ? 
		      $idesettings{'GTERP'} : $idesettings{'ZTERP'});
	    my $terpbg=($settings{'format'} eq 'glulx' ? 
		      $idesettings{'GTERPBG'} : $idesettings{'ZTERPBG'});
	    $terpbg=($terpbg?"&":"");
	    my $cmd="\"$terp\" \"$l/Build/output.$settings{'zsuf'}\" $terpbg";
	    if ($terpbg) {
		print "  Exit interpreter to return to i7.";
	    }
	    print "\n\n";
	    system($cmd);
	    print "\n\n";
	}
	next MAINLOOP;
    }
    if (m/^R/i) {
	$bad = compile("--release");
	if ($bad) {
	    print "\n\n*** COMPILATION HAD ERRORS ***\n\n";
	    next MAINLOOP;
	} 
	my $target = release();
	unless ($target) {
	    print "\n\n*** COULD NOT GENERATE BLORB ***\n\n";
	} else {
	    print "\n\nRelease Succeeded.  Blorb file is in:\n";
	    print "$target\n\n";
	}
	next MAINLOOP;
    }
    if (m/^I/i) {
	browse();
	next MAINLOOP;
    }
    if (m/^S/i) {
	settings();
	next MAINLOOP;
    }
    if (m/^Q/i) {
	print "\n\nThanks for putting up with this so-called interface!\n";
	if ($CLEANUP) {
	    unlink $CLEANUP;
	}
	chdir $oldpwd;
	exit 0;
    }
    print "I don't see any $_ here!\n";
}

exit 1;

# End of mainline code

sub printprompt {
    my $prompt = shift;
    my $default = shift;
    $prompt = "> " unless ($prompt);
    $default = "" unless ($default);
    my $i = '';
    while ($i eq '') {
	print "\n$prompt";
	$i=<>;
	chomp $i;
	unless ($i) {
	    $i = $default;
	}
	unless ($i) {
	    print "I beg your pardon?\n";
	}
    }
    return $i;
}

sub newproj {
    my $m = printprompt("Location of new project [$proj] > ",$proj);
    $m =~ s/~/$HOME/;
    if (substr($m,-7,7) ne ".inform" ) {
	print "$m does not end in \".inform\" -- it will be appended.\n";
	$m .= ".inform";
    }
    if ($^V lt 5.8) {
	$l = $m;
    } else {
	$l = realpath($m);
    }
    unless ($l) {
	print "Uh oh!  I can't turn $m into a directory name!\n";
	return '';
    }
    if ( -d $l) {
	print "Uh oh!  $l already exists.\n";
	print "Maybe you meant (O)pen?\n";
	return '';
    }
    if (mkdir("$l")) {
	mkdir("$l/Build");
	mkdir("$l/Source");
	mkdir("$l/Index");
	if ((! -d "$l/Build") || (! -d "$l/Source") || (! -d "$l/Index")) {
	    print "Uh oh!  Failed to create one or more directories!\n";
	    rmdir ("$l/Build");
	    rmdir ("$l/Source");
	    rmdir ("$l/Index");
	    rmdir ("$l");
	    return '';
	}
	$uuid = '';
	$uuid = `uuidgen`;
	if ($uuid eq '') {
	    print "Could not generate UUID--what, you don't have uuidgen?\n";
	    print "It's probably in the package e2fsprogs: install that.\n";
	    return '';
	}
	chomp $uuid;
	open(UUID,">$l/uuid.txt");
	unless(UUID) {
	    print "Could not open $l/uuid.txt for writing: $!\n";
	    return '';
	}
	print UUID $uuid;
	close UUID;
	my $storyname = `basename $l .inform`;
	chomp $storyname;
	open STORY, ">$l/Source/story.ni";
	unless (STORY) {
	    print "Could not open $l/Source/story.ni for writing: $!\n";
	    return '';
	}
	print STORY "\"$storyname\" by \"$idesettings{'NAME'}\".\n";
	close STORY;
	writesettings();
	return $l;
    } else {
	print "Uh oh!  Could not create $l\n";
	return '';
    }
}

sub openproj {
    if ($idesettings{'PREVIOUS'}) {
	$proj = $idesettings{'PREVIOUS'};
    }
    my $m = printprompt("Location of existing project [$proj] > ",$proj);
    $m =~ s/~/$HOME/;
    if ($^V lt 5.8) {
	$l = $m;
    } else {
	$l = realpath($m);
    }
    unless ($l) {
	print "Uh oh!  I can't turn $m into a directory name.\n";
	return '';
    }
    my $bad = 0;
    if (! -d $l) {
	$bad = 1;
	print "Uh oh!  $l does not exist.\n";
	if (substr($l,-7,7) ne ".inform" ) {
	    $l .= ".inform";
	    print "Trying $l...\n";
	    if (-d $l) {
		$bad =0;
	    } else {
		print "$l still does not exist.\n";
	    }
	}
    }
    if ($bad) {
	print "Maybe you meant (S)tart a new project?\n";
	return '';
    }
    if (! -f "$l/uuid.txt") {
	print "Uh oh!  Cannot find UUID.  Refusing to believe this is a project!\n";
	return '';
    }
    if (! -f "$l/Source/story.ni") {
	print "Dude, where's the story?  Not in $l/Source/story.ni!\n";
	return '';
    }
    return $l;
}

sub compile {
    my $arg = shift;
    $arg = "" unless ($arg);
    my $cmd = "\"$NI\" $arg $ni_settings{'rules'} --extension=$settings{'zsuf'} --package \"$l\"";
    my $rc = system($cmd);
    return $rc if ($rc);
    my $i6opts = "-kE2SDw";
    my $i6lib = "+\"$idesettings{'PREFIX'}/share/inform7/Library/Natural\"";
    if ($settings{'zcode'} == 5) {
	$i6opts .= "v5";
    } elsif ($settings{'zcode'} == 6) {
	$i6opts .= "v6";
    } elsif ($settings{'zcode'} == 8) {
	$i6opts .= "v8";
    } else {
	$i6opts .= "G";
    }
    $i6opts .= "x";
    $cmd = "\"$I6\" $i6opts $i6lib \"$l/Build/auto.inf\" -o \"$l/Build/output.$settings{'zsuf'}\"";
    $rc = system($cmd);
    return($rc);
}

sub release {
    if ($settings{'blorb'} == 0) {
	print "Release-as-blorb is NO.\n";
	print "Story can be found in $l/Build/output.$settings{'zsuf'}\n\n";
	return "$l/Build/output.$settings";
    }
    my $cmd = "\"$BLORB\" \"$l/Release.blurb\"";
    my $rc = system($cmd);
    if ($rc) {
	return undef;
    }
    open(BLURB, "<$l/Release.blurb");
    unless (BLURB) {
	print "Could not open Blurb file $l/Release.blurb: $!\n";
	return undef;
    }
    my $target = "";
    my $src = "$l/story.zblorb";
    READBLURB: while (<BLURB>) {
	if (/^destination/) {
	    m/"(.*)"/;
	    $target = $1;
	    last READBLURB;
	}
    }
    close BLURB;
    if (($target eq '') && ($settings{'zcode'} == 256)) {
	$target = "$l/story.gblorb";
    }
    if ($target) {
	my $rc = rename($src,$target);
	unless ($rc) {
	    print "Rename of blorb file \"$src\" to \"$target\" failed!\n";
	    return undef;
	}
	return $target;
    }
    return $src;
}

sub browse {
    my $idir = "$l/Index";
    my $ifile = $idir . "/_index.html";

    unless (open IFILE, ">$ifile") {
	print "*** Could not create Index file $ifile! ***\n\n";
	return 3;
    }
    print IFILE <<EOF;
<html>
<head>
<title>
Inform Index
</title>
</head>
<body>
<a href="./Actions.html">Actions</a><p>
<a href="./Contents.html">Contents</a><p>
<a href="./Kinds.html">Kinds</a><p>
<a href="./Phrasebook.html">Phrasebook</a><p>
<a href="./Scenes.html">Scenes</a><p>
<a href="./World.html">World</a><p>
<a href="../Build/Problems.html">Errors</a></p>
<a href="$idesettings{'PREFIX'}/share/inform7/Documentation/index.html">Documentation</a></p>
</body>
</html>
EOF
;

    close IFILE;
    print "Using $idesettings{'BROWSER'} as your browser.";
    if ($idesettings{'BROWSERBG'} == 0) {
	print"  Exit the browser to return to i7.";
    }
    print "\n\n";
    $cmd = $idesettings{'BROWSER'};
    if ($cmd =~ m/%s/) {
	$cmd =~ s/%s/$ifile/;
    } else {
	$cmd .= " $ifile";
    }
    if ($idesettings{'BROWSERBG'}) {
	$cmd .= " &";
    }
    system($cmd);
    print "\n\n";
    if ($idesettings{'BROWSERBG'}) {
	$CLEANUP = $ifile;
    } else {
	unlink $ifile;
    }
    return 0;
}
    
sub settings {
  SETTINGS: while(1) {
      my %target = (
		    5   => "Zcode version 5 (z5)",
		    6   => "Zcode version 6 (z6)",
		    8   => "Zcode version 8 (z8)",
		    256 => "Glulx (ulx)"
		    );
      my %blorbtarget = (
			 1 => "yes",
			 0 => "no"
			 );
      print "SETTINGS\n\n\n";
      print "Target: (currently ",$target{$settings{'zcode'}},")\n\n";
      print "Compile to Zcode version (5)\n";
      print "Compile to Zcode version (6)\n";
      print "Compile to Zcode version (8)\n";
      print "Compile to (G)lulx\n";
      print "\n\n";
      print "Toggle (B)lorb release: (currently ",$blorbtarget{$settings{'blorb'}},")\n\n";

      print "(I)DE Options\n\n";
      print "(R)eturn to main menu\n\n";
      $_ = printprompt();
      if (m/^R/i) {
	  writesettings();
	  last SETTINGS;
      }
      if (m/^B/i) {
	  $settings{'blorb'} = 1 - $settings{'blorb'};
	  next SETTINGS;
      }
      if (m/^5/) {
	  $settings{'format'} = "zcode";
	  $settings{'zcode'} = 5;
	  $settings{'suffix'} = "zblorb";
	  $settings{'zsuf'} = "z5";
	  next SETTINGS;
      }
      if (m/^6/) {
	  $settings{'format'} = "zcode";
	  $settings{'zcode'} = 6;
	  $settings{'suffix'} = "zblorb";
	  $settings{'zsuf'} = "z6";
	  next SETTINGS;
      }
      if (m/^8/) {
	  $settings{'format'} = "zcode";
	  $settings{'zcode'} = 8;
	  $settings{'suffix'} = "zblorb";
	  $settings{'zsuf'} = "z8";
	  next SETTINGS;
      }
      if (m/^G/i) {
	  $settings{'format'} = "glulx";
	  $settings{'zcode'} = 256;
	  $settings{'suffix'} = "gblorb";
	  $settings{'zsuf'} = "ulx";
	  next SETTINGS;
      }
      if (m/^I/i) {
	  idesettings();
	  next SETTINGS;
      }
  }
    return;
}

sub readsettings {
    my $PFILE=shift;
    unless (open PFILE,"<$PFILE") {
	print " *** Could not open preferences file for reading! ***\n\n";
    }
    my $state = 0;
    while(<PFILE>) {
	if (/<key>IFSettingCreateBlorb<\/key>/i) {
	    $state = 1;
	}
	if (/<key>IFSettingZCodeVersion<\/key>/i) {
	    $state = 2;
	}
	if ($state == 1) {
	    if (/<true\/>/) {
		$settings{'blorb'} = 1;
		$state = 0;
	    }
	    if (/<false\/>/) {
		$settings{'blorb'} = 0;
		$state = 0;
	    }
	}
	if ($state == 2) {
	    (/<integer>(\d+)<\/integer>/) && do {
		$settings{'zcode'} = $1;
		$state = 0;
	    }
	}
    }
    
    my $a = $settings{'zcode'};
    if ($a == 256) {
	$settings{'format'} = "glulx";
	$settings{'suffix'} = "gblorb";
	$settings{'zsuf'} = "ulx";
    } else {
	$settings{'format'} = "zcode";
	$settings{'suffix'} = "zblorb";
	$settings{'zsuf'} = "z" . $a;
    }
    return 0;
}


sub writesettings {
    my $PFILE = "$l/Settings.plist";
    unless ( open PFILE,">$PFILE") {
	print " *** Could not open preferences file for writing! ***\n\n";
	return 2;
    }  
    my $ofh=select PFILE;
    my $do_blorb = ($settings{'blorb'}?"<true/>":"<false/>");
    print <<EOF;
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.
com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>IFCompilerOptions</key>
        <dict>
                <key>IFSettingNaturalInform</key>
                <true/>
        </dict>
        <key>IFInform6Extensions</key>
        <dict/>
        <key>IFLibrarySettings</key>
        <dict>
                <key>IFSettingLibraryToUse</key>
                <string>Natural</string>
        </dict>
        <key>IFMiscSettings</key>
        <dict>
                <key>IFSettingInfix</key>
                <false/>
        </dict>
        <key>IFOutputSettings</key>
        <dict>
                <key>IFSettingCreateBlorb</key>
		$do_blorb
                <key>IFSettingZCodeVersion</key>
                <integer>$settings{'zcode'}</integer>
        </dict>
</dict>
</plist>
EOF
;
    select $ofh;
    close PFILE;
    return 0;
}

sub readideprefs {
    my $PFILE = shift;
    unless (open PFILE,"<$PFILE") {
	return 2;
    }	
    while (<PFILE>) {
	next unless (/=/);
	my ($key,$value) = split('=');
	$key = trim($key);
	$value = trim($value);
	$idesettings{$key} = $value;
    }
    return 0;
}

sub writeideprefs {
    my $PFILE = "$HOME/.i7rc";
    unless ( open PFILE,">$PFILE") {
	print " *** Could not open IDE preferences file for writing! ***\n\n";
	return 2;
    }  
    print PFILE "\n#These are specific to the Linux stdio IDE\n\n";
    print PFILE "NAME      = $idesettings{'NAME'}\n";
    print PFILE "PREFIX    = $idesettings{'PREFIX'}\n";
    print PFILE "EDITOR    = $idesettings{'EDITOR'}\n";
    print PFILE "BROWSER   = $idesettings{'BROWSER'}\n";
    print PFILE "ZTERP     = $idesettings{'ZTERP'}\n";
    print PFILE "GTERP     = $idesettings{'GTERP'}\n";
    print PFILE "EDITORBG  = $idesettings{'EDITORBG'}\n";
    print PFILE "BROWSERBG = $idesettings{'BROWSERBG'}\n";
    print PFILE "ZTERPBG   = $idesettings{'ZTERPBG'}\n";
    print PFILE "GTERPBG   = $idesettings{'GTERPBG'}\n";
    print PFILE "PREVIOUS  = $l\n";
    close PFILE;
}

sub idesettings {
  IDESETTINGS: while(1) {
      print "IDE SETTINGS\n\n\n";
      print "Set (E)ditor";
      if ($idesettings{'EDITOR'}) {
	  print " (currently $idesettings{'EDITOR'})";
      }
      print "\n";
      print "(&) Toggle running editor in background (currently ";
      if ($idesettings{'EDITORBG'}) {
	  print "ON";
      } else {
	  print "OFF";
      }
      print ").\n\n";
      print "Set (B)rowser";
      if ($idesettings{'BROWSER'}) {
	  print " (currently $idesettings{'BROWSER'})";
      }
      print "\n";
      print "Toggle running browser in bac(K)ground (currently ";
      if ($idesettings{'BROWSERBG'}) {
	  print "ON";
      } else {
	  print "OFF";
      }
      print ").\n\n";
      print "Set (Z)-code interpreter";
      if ($idesettings{'ZTERP'}) {
	  print " (currently $idesettings{'ZTERP'})";
      }
      print "\n";
      print "Toggle running Z-code interpreter in ba(C)kground (currently ";
      if ($idesettings{'ZTERPBG'}) {
	  print "ON";
      } else {
	  print "OFF";
      }
      print ").\n\n";
      print "Set (G)lulx interpreter";
      if ($idesettings{'GTERP'}) {
	  print " (currently $idesettings{'GTERP'})";
      }
      print "\n";
      print "Toggle running Glulx interpreter in backgroun(D) (currently ";
      if ($idesettings{'GTERPBG'}) {
	  print "ON";
      } else {
	  print "OFF";
      }
      print ").\n\n";
      print "(R)eturn to main menu\n\n";
      $_ = printprompt();
      if (m/^R/i) {
	  writeideprefs();
	  last IDESETTINGS;
      }
      if (m/^E/i) {
	  $idesettings{'EDITOR'} = printprompt("Editor [$idesettings{'EDITOR'}]> ");
	  next IDESETTINGS;
      }
      if (m/^B/i) {
	  $idesettings{'BROWSER'} = printprompt("Browser [$idesettings{'BROWSER'}]> ");
	  next IDESETTINGS;
      }
      if (m/^Z/i) {
	  $idesettings{'ZTERP'} = printprompt("Z-code Interpreter [$idesettings{'ZTERP'}]> ");
	  next IDESETTINGS;
      }
      if (m/^G/i) {
	  $idesettings{'GTERP'} = printprompt("Glulx Interpreter [$idesettings{'GTERP'}]> ");
	  next IDESETTINGS;
      }
      if (m/^&/i) {
	  $idesettings{'EDITORBG'} = 1 - $idesettings{'EDITORBG'};
	  next IDESETTINGS;
      }
      if (m/^K/i) {
	  $idesettings{'BROWSERBG'} = 1 - $idesettings{'BROWSERBG'};
	  next IDESETTINGS;
      }
      if (m/^C/i) {
	  $idesettings{'ZTERPBG'} = 1 - $idesettings{'ZTERPBG'};
	  next IDESETTINGS;
      }
      if (m/^D/i) {
	  $idesettings{'GTERPBG'} = 1 - $idesettings{'GTERPBG'};
	  next IDESETTINGS;
      }
  }
    
}

sub trim {
    my @out = @_;
    for (@out) {
	s/^\s+//;
	s/\s+$//;
    }
    return wantarray ? @out : $out[0];
}


__END__

=head1 i7

i7 - Interactive shell for Inform 7 compiler

i7

i7 allows the creation and compilation of Interactive Fiction works
written in the Inform 7 programming language by Graham Nelson.

=over

=item Invocation

Invoke "i7" with no options, and then choose whether to begin a new
story or to work with an existing story.  You will be prompted for the
name of the directory that is the root of your story project.  Don't
go too crazy with the name of the directory: spaces are fine, but
quotation marks, the pipe character, and shell metacharacters like "*"
and "?" are not a good idea.

If a new story is chosen, the appropriate directory structures and
UUID will be created for the story file.  For an existing story, the
directory given will be checked for the UUID file, and if it is not
found, i7 will complain.

Once a story directory has been set, i7 will move on to its main
screen.  From here you may change story settings (unfortunately,
settings are not yet saved, so you have to do this on each i7
invocation), compile your story, or release it.

From here, you should edit your story file
I<project-directory>/Source/story.ni as you desire.

If you have your VISUAL or EDITOR environment variables described, or
/usr/bin/editor exists, or /bin/ed exists, or you set your preferred
editor from the IDE preference panels, then the Inform 7 environment
will allow you the ability to edit your story from the i7 interface.
Otherwise, just open the story in your favorite editor.

Save your story and then choose Compile.  i7 will tell you where the
output is (I<project-directory>/Build/output.I<suffix>, where
I<suffix> is usually "z5", but may be "z6", "z8", or "ulx" depending
on compilation options.

If you prefer, you can Go, which compiles and then runs your story.
The interpreter invoked has no dependencies other than stdio, which
makes it very portable, but if you want your game to look nice, you
can play it in any other interpreter as directed by the Compile
option, or you can set other interpreters in the IDE preference panel.

When you are ready to release your story, choose Release, and i7 will
tell you where the blorb (or zcode/ulx, if you chose "Do not release
as Blorb" as a setting) output can be found.

=item What i7 is

I7 is intended as an utterly barebones Inform 7 development system.
All it really does is generate a UUID for the project and invoke the
appropriate compilers when asked.

It is fervently hoped that, a Linux port having been released, that
some enterprising soul or souls will provide an actual interface to it
of the quality and feature set of the Mac OS X or Windows versions.

This port of Inform 7 is deliberately intended to have minimal
requirements.  A Perl interpreter is needed to run the i7 shell.  It
is presumed that C<uuidgen> is present somewhere on the user's path;
uuidgen is part of the e2fstools package and should be present on
almost every Linux system.  Other than that, the actual compilers
invoked are statically linked, and require only stdio for input and
output, as do the bundled z-code and Glulx interpreters.

=item What is implemented

Compilation and Release are fully implemented.  

The Index is built and is available as files in
I<project-directory>/Index (and can be reached via the (I)ndex
function if a browser is appropriately set, although since the inform:
URL type is not implemented, the icons will all be missing, and since
the source: type is not implemented either, links to portions of the
source text also will not work).

Any problems during compilation can be found in
I<project-directory>/Build/Problems.html.

Story preferences are saved, and will be respected if you move your
game to a different platform.  IDE preferences are saved globally, but
are not respected on other platforms (which generally use their own
built-in editors and interpreters in any event).

=item What is not implemented

The Skein and the Transcript are not implemented at all.  There is no
"Replay" function.  Although preferences are
saved, the preference save files are not understood by other Inform 7
ports; nor does this port understand their preferences file.

Only Inform 7 story projects are implemented.  You will have to put your own
"begins here" and "ends here" markers around extensions you write, and
there is no support for Inform 6 story creation.

=item Problems, Suggestions, and So Forth

If you have difficulty installing i7 for Linux, please feel free to
write to Adam Thornton at C<adam@io.com>.  Likewise, if i7 chokes at some
place other than compiling your sources, let Adam know.

If you need help with the Inform 7 language, the newsgroup
rec.arts.int-fiction is the right place to start.  

If you feel that the interface for i7 is horrifically bad and ought to
be scrapped, you're exactly right.  There's no need to tell Adam: he
knows.  Now that you have the native command-line tools, though,
there's no reason for you I<not> to implement an interface that's the
functional equivalent of the Mac OS X or Windows versions.  Please
feel free to do so!

=cut
