#!/usr/bin/env perl
# $Id: install-menu-wizard.pl 15760 2009-10-11 05:03:45Z preining $
#
# Copyright 2009 Norbert Preining
# This file is licensed under the GNU General Public License version 2
# or any later version.
#

use strict;
$^W = 1;

my $svnrev = '$Revision: 11925 $';
$svnrev =~ m/: ([0-9]+) /;
$::menurevision = $1;

#
# the following lists define which options are shown in the Option screen
# for unix and windows. On W32 with admin privileges both @w32 list options
# are shown
my @unix_opts = qw/letter/;
my @w32_opts = qw/letter desktop_integration/;
my @w32_admin_opts = qw/w32_multi_user/;

my @opts_list = ();
if (win32()) {
  push @opts_list, @w32_opts;
  if (admin()) {
    push @opts_list, @w32_admin_opts;
  }
} else {
  push @opts_list, @unix_opts;
}


our %vars;
our $tlpdb;
our $texlive_release;

our $MENU_INSTALL = 0;
our $MENU_ABORT   = 1;
our $MENU_QUIT    = 2;
our $MENU_ALREADYDONE = 3;


my $return = $MENU_INSTALL;

require Tk;
require Tk::Dialog;
require Tk::DialogBox;
require Tk::PNG;
require Tk::ROText;
require Tk::ProgressBar;
require Tk::Font;

use utf8;
no utf8;

#
#
my $tit;
my $can;
my $prv;
my $nxt;
my $img;
my $dest;
my $warning;
my $mw;
my $usedfont;
my $fmain;
my $fbuttons;
my $ftitle;
my $counter;
my $lineskip;

my $LEFT = 130;
my $RIGHT = 50;
my $TOP  = 50;
my $BOTTOM = 50;
my $INF = 300;
my $MWIDTH = 730;
my $MHEIGHT = 480;
my $TITLEHEIGHT = 30;
my $BUTTONSHEIGHT = 50;
my $INNERWIDTH = ($MWIDTH - $LEFT - $RIGHT);
my $INNERHEIGHT = ($MHEIGHT - $TOP - $TITLEHEIGHT - $BOTTOM - $BUTTONSHEIGHT);

require("TeXLive/trans.pl");

# the main installer runs %{$::run_menu}
$::run_menu = \&run_menu_wizard;

######################################################################
# From here on only function definitions
# ####################################################################

sub setup_hooks_wizard {
  @::info_hook = ();
  push @::info_hook,
    sub {
      return unless defined($mw);
      wizard_update_status(join(" ",@_));
      $mw->update;
    };
  @::warn_hook = ();
  push @::warn_hook,
    sub {
      return unless defined($mw);
      wizard_update_status(join(" ",@_));
      $mw->update;
    };
  @::install_packages_hook = ();
  push @::install_packages_hook, \&wizard_update_progressbar;
  push @::install_packages_hook, sub { $mw->update; };
}

sub wizard_update_status {
  my ($p) = @_;
  $::progressw->insert("end", "$p");
  $::progressw->see("end");
}
sub wizard_update_progressbar {
  my ($n,$total) = @_;
  if (defined($n) && defined($total)) {
    $::progress->value(int($n*100/$total));
  }
}

################# WELCOME SCREEN ######################################

sub run_menu_wizard {
  $mw = Tk::MainWindow->new(-width => $MWIDTH, -height => $MHEIGHT);
  setup_hooks_wizard();

  $dest = $vars{'TEXDIR'};

  my $img = $mw->Photo(-format => 'png', -file => "$::installerdir/tlpkg/installer/texlive2009-wizard.png");
  $mw->Label(-image => $img, -background => "#0078b8")->place(-x => 0, -y => 0);

  $ftitle = $mw->Frame(-height => $TITLEHEIGHT, -width => $INNERWIDTH);
  $ftitle->update;
  $ftitle->place(-x => $LEFT, -y => $TOP);

  $tit = $ftitle->Label(-text => __('TeX Live %s Installation', $TeXLive::TLConfig::ReleaseYear));

  $usedfont= $tit->cget("-font");
  $lineskip = $usedfont->metrics("-linespace");

  $tit->place(-x => 0, -y => 0);

  $counter = $ftitle->Label(-text => "1/5");
  $counter->place(-x => $INNERWIDTH, -y => 0, -anchor => "ne");

  $fmain = $mw->Frame(-height => $INNERHEIGHT, -width => $INNERWIDTH);
          #, -borderwidth => 1, -relief => "ridge");
  $fmain->place(-x => $LEFT, -y => ($TOP + $TITLEHEIGHT));


  $can = $mw->Button(-width => 10, -relief => "ridge", -text => __('Cancel'),
               -command => sub { $return = $MENU_ABORT; $mw->destroy; });
  $prv = $mw->Button(-width => 10, -relief => "ridge", -text => __('< Back'));
  $nxt = $mw->Button(-width => 10, -relief => "ridge", -text => __('Next >'));

  $can->place(-x => $LEFT, -y => ($MHEIGHT - $BOTTOM), -anchor => "sw");

  my $rb = $MWIDTH - $RIGHT;
  $nxt->place(-x => ($MWIDTH - $RIGHT) , 
              -y => ($MHEIGHT - $BOTTOM), -anchor => "se")->focus();

  reset_start();

  Tk::MainLoop();
  return($return);
}

sub reset_start {
  for ($fmain->children) {
    $_->destroy;
  }
  $counter->configure(-text => "1/5");
  $prv->placeForget;

  my $inf = $fmain->Label(-text => __("Welcome to the installation of TeX Live %s\nhttp://tug.org/texlive\n\nThis wizard will guide you through the installation.\n\nFor an advanced, customizable installation, please consult\nthe web pages or installation guide.", $TeXLive::TLConfig::ReleaseYear) . "\n" . (win32() ? __("Or use install-tl-advanced.bat") : __("Or use the argument --gui perltk to install-tl.")), -justify => "left");
  $inf->place(-x => 0, -y => 100);

  $nxt->configure(-text => __("Next >") , -command => \&ask_path );
  $nxt->configure(-state => "normal");
}

################## PATH SCREEN ################################

sub ask_path {
  for ($fmain->children) {
    $_->destroy;
  }
  $counter->configure(-text => "2/5");
  my $lab = $fmain->Label(-text => __('Destination folder:'));
  my $val = $fmain->Label(-textvar => \$dest);
  my $but = $fmain->Button(-text => __("Change"), -command => \&change_path,
                           -relief => "ridge", -width => 10);

  # texworks will be anyway installed in scheme-full
  #my $but_tw = $fmain->Checkbutton(-text => __("Install TeXworks front end'),
  #                                -variable => \$vars{"addon_editor"});

  #
  # disable the "Advanced Configuration" button switching to the 
  # perltk installer
  #
  #my $cb = $fmain->Button(-text => __("Advanced Configuration"), 
  #       -relief => "ridge",
  #       -command => sub { $mw->destroy; 
  #                         require("installer/install-menu-perltk.pl");
  #                         setup_hooks_perltk();
  #                         $return = run_menu_perltk();
  #                       });

  calc_depends();


  $fmain->Label(-text => __("The destination folder will contain the installation.\nIt is strongly recommended to keep the year as the last component."), 
                -justify => "left")->place(-x => 0, -y => 20);

  my $ytmp = 100;
  $lab->place(-x => 0, -y => $ytmp, -anchor => "w");
  $ytmp += ($lineskip + 10);
  $val->place(-x => 0, -y => $ytmp, -anchor => "w");

  $but->place(-x => $INNERWIDTH, -y => $ytmp, -anchor => "e");

  $warning = $fmain->Label(-foreground => "red");
  check_show_warning();
  $ytmp += ($lineskip + 10);
  $warning->place(-x => 0, -y => $ytmp, -anchor => "w");


  #if (win32()) {
  #  $but_tw->place(-x => 0, -y => $ytmp + 60);
  #}

  #$cb->place(-x => $INNERWIDTH, -y => $INNERHEIGHT, -anchor => "se");

  $fmain->Label(-text => __('disk space required') . ": $vars{'total_size'} MB", 
                -justify => "left"
             )->place(-x => 0, -y => $fmain->height, -anchor => "sw");

  $prv->configure(-text => __('< Back'), -command => \&reset_start );
  $nxt->configure(-text => __('Next >'), -command => \&ask_options );

  my $rb = $MWIDTH - $RIGHT;
  $rb -= $nxt->width;
  $rb -= 30;

  $prv->place(-x => $rb, -y => ($MHEIGHT - $BOTTOM), -anchor => "se");
}

sub check_show_warning {
  if (TeXLive::TLUtils::texdir_check($vars{'TEXDIR'})) {
    $warning->configure(-text => "");
    $nxt->configure(-state => "normal");
  } else {
    $warning->configure(-text => __('(default not writable - please change!)'));
    $nxt->configure(-state => "disabled");
  }
}
  
sub change_path {
  my $val = $dest;
  my $sw = $mw->Toplevel(-title => "Changing TEXDIR");
  $sw->transient($mw);
  $sw->grab();
  $sw->Label(-text => __('Enter path for') . " TEXDIR: ")->pack(-padx => "2m", -pady => "2m");
  my $entry = $sw->Entry(-textvariable => $val, -width => 60);
  $entry->pack(-padx => "2m", -pady => "2m")->focus();
  my $f = $sw->Frame;
  my $okbutton = $f->Button(-text => __('Ok'), -width => 10, 
     -relief => "ridge",
     -command => sub { $val = $entry->get; callback_change_texdir($val) ; $sw->destroy })->pack(-side => 'left', -padx => "2m", -pady => "2m");
  my $cancelbutton = $f->Button(-text => __('Cancel'), -relief => "ridge",
     -width => 10,
     -command => sub { $sw->destroy })->pack(-side => 'right', -padx => "2m", -pady => "2m");
  $f->pack(-expand => 'x');
  # bindings
  $sw->bind('<Return>' => [ $okbutton, 'Invoke']);
  $sw->bind('<Escape>' => [ $cancelbutton, 'Invoke']);
}

sub callback_change_texdir {
  my ($val) = @_;
  my $home = getenv('HOME');
  if (win32()) {
    $home = getenv('USERPROFILE');
    $home =~ s!\\!/!g;
  }
  $home ||= '~';
  $val =~ s!\\!/!g;
  $vars{'TEXDIR'} = $val;
  $vars{'TEXDIR'} =~ s/^~/$home/;
  $vars{'TEXMFLOCAL'} =~ s/^~/$home/;
  $vars{'TEXMFSYSVAR'} =~ s/^~/$home/;
  $vars{'TEXMFSYSCONFIG'} =~ s/^~/$home/;
  # only if we set TEXDIR we set the others in parallel
  if ($vars{'TEXDIR'}=~/^(.*)\/$texlive_release$/) {
    $vars{'TEXMFLOCAL'}="$1/texmf-local";
    $vars{'TEXMFSYSVAR'}="$1/$texlive_release/texmf-var";
    $vars{'TEXMFSYSCONFIG'}="$1/$texlive_release/texmf-config";
  } elsif ($vars{'TEXDIR'}=~/^(.*)$/) {
    $vars{'TEXMFLOCAL'}="$1/texmf-local";
    $vars{'TEXMFSYSVAR'}="$1/texmf-var";
    $vars{'TEXMFSYSCONFIG'}="$1/texmf-config";
  }
  $vars{'TEXDIRW'}=$vars{'TEXDIR'};
  $dest = $vars{'TEXDIR'};
  check_show_warning();
}

################## OPTIONS SCREEN ################################

my %opts_to_str = (
  "letter" => "Use letter size instead of A4 by default",
  "desktop_integration" => "Add shortcuts to menu and desktop",
  "file_assocs" => "Change file associations",
  "path" => "Adjust PATH setting in registry",
  "w32_multi_user" => "Installation for all users",
);

sub ask_options {
  for ($fmain->children) {
    $_->destroy;
  }
  $counter->configure(-text => "3/5");

  my $inf = $fmain->Label(-text => __("This screen allows you to configure some options"), -justify => "left");
  $inf->place(-x => 0, -y => 20);

#  my %opt_cb;
#
#  $opt_cb{"letter"} = $fmain->Checkbutton(
#                    -text => __("Use letter size instead of A4 by default"), 
#                    -variable => \$vars{"option_letter"});
#
#  $opt_cb{"desktop_integration"} = $fmain->Checkbutton(
#                    -text => __("Add shortcuts to menu and desktop"),
##                    -variable => \$vars{"option_desktop_integration"});
#
#  $opt_cb{"file_assocs"} = $fmain->Checkbutton(
#                    -text => __('Change file associations'), 
##                    -variable => \$vars{"option_file_assocs"});
#
#  $opt_cb{"path"} = $fmain->Checkbutton(
#                    -text => __('Adjust PATH setting in registry'), 
#                    -variable => \$vars{"option_path"});
#
#  $opt_cb{"w32_multi_user"} = $fmain->Checkbutton(
##                    -text => __('Installation for all users'), 
#                    -variable => \$vars{"option_w32_multi_user"});
#
  calc_depends();

  my $ytmp = 60;

  for my $o (@opts_list) {
    $fmain->Checkbutton(-text => __($opts_to_str{$o}),
             -variable => \$vars{"option_$o"})->place(-x => 0, -y => $ytmp);
    # $opt_cb{$o}->place(-x => 0, -y => $ytmp);
    $ytmp += 50;
  }

  $prv->configure(-text => __('< Back'), -command => \&ask_path );
  $nxt->configure(-text => __('Next >'), -command => \&ask_go );

  my $rb = $MWIDTH - $RIGHT;
  $rb -= $nxt->width;
  $rb -= 30;

  $prv->place(-x => $rb, -y => ($MHEIGHT - $BOTTOM), -anchor => "se");
}


################## INSTALL SCREEN #############################

sub ask_go {
  for ($fmain->children) {
    $_->destroy;
  }
  $counter->configure(-text => "4/5");
  my $inf = $fmain->Label(-justify => "left", -text => __("We are ready to install TeX Live %s.\nThe following settings will be used.\nIf you want to change something please go back,\notherwise press the \"Install\" button.", $TeXLive::TLConfig::ReleaseYear));


  $inf->place(-x => 0, -y => 80);

  my $ytmp = 170;

  $fmain->Label(-justify => "left", 
                -text => __("Destination folder:") . "\t $dest")->place(-x => 0, -y => $ytmp);
  $ytmp += 20;

  for my $o (@opts_list) {
    $fmain->Label(-justify => "left", 
                  -text => __($opts_to_str{$o}) . ":\t" . ($vars{"option_$o"} ? __("Yes") : __("No")))->place(-x => 0, -y => $ytmp);
    $ytmp += 20;
  }


  
  $nxt->configure(-text => __('Install'), 
                  -command => \&wizard_installation_window);
  $prv->configure(-text => __('< Back'), -command => \&ask_options);
}

sub wizard_installation_window {
  for ($fmain->children) {
    $_->destroy;
  }
  $counter->configure(-text => "5/5");
  # create a progress bar window
  # compute the height of the Text by the given font

  $::progressw = $fmain->Scrolled("ROText", -scrollbars => "e",
                                -wrap => "word");

  # we want to have the progressbar about 20px wide, so compute how
  # many lines of the current font do fit into the remaining area
  my $lines = int( ($INNERHEIGHT - 20) / $lineskip);
  # it seems that on Windows the computation is not right, the
  # progress bar overwrites the last line of the text widget
  # remove one line here
  $lines-- if win32();
  $::progressw->configure(-height => $lines);
  $::progressw->place(-x => 0, -y => 0, -width => $INNERWIDTH); 

  # that is necessary otherwise the progressbar gets very strange dimensions
  $fmain->update;


  my $percent_done = 0;

  # compute the remaining space in pixel for the progressbar
  my $pw = $INNERHEIGHT - ($lines * $lineskip) - 5;
  # make sure that the line we remove above for Windows is not re-added
  # to the size of the progressbar. The 7 was found by trial and error
  $pw -= ($lineskip + 7) if win32();
  $::progress = $fmain->ProgressBar(-variable => \$percent_done,
      -width => $pw, -length => $INNERWIDTH,
      -from => 0, -to => 110, -blocks => 10,
      -colors => [ 0, '#0078b8' ]);
  $::progress->place(-x => 0, -y => $INNERHEIGHT, -anchor => "sw");

  #
  # change the buttons so that the Prev disappears, the Next becomes
  # Cancel, and the Cancel button disappears
  $prv->placeForget;
  $can->placeForget;
  $nxt->configure(-text => __('Cancel'),
                  -command => sub { $return = $MENU_ABORT; $mw->destroy; });
  calc_depends();
  do_installation();
  $::progress->value(110);
  $return = $MENU_ALREADYDONE;
  my $t = __("See %s/index.html for links to documentation.\nThe TeX Live web site (http://tug.org/texlive/) contains any updates and corrections. TeX Live is a joint project of the TeX user groups around the world; please consider supporting it by joining the group best for you. The list of groups is available on the web at http://tug.org/usergroups.html.", $::vars{'TEXDIR'});
  if (!win32()) {
    $t .= "\n\n" . __("Add %s/texmf/doc/man to MANPATH.\nAdd %s/texmf/doc/info to INFOPATH.\nMost importantly, add %s/bin/%s\nto your PATH for current and future sessions.", $::vars{'TEXDIR'}, $::vars{'TEXDIR'}, $::vars{'TEXDIR'}, $::vars{'this_platform'});
  }
  $t .= "\n\n" . __('Welcome to TeX Live!');
  #$t =~ s/\\n/\n/g;
  my $linechar = $::progressw->index("end");
  $::progressw->markSet("finaltext", $linechar);
  $::progressw->markGravity("finaltext", "left");
  $::progressw->insert("end", "\n$t");
  $::progressw->see("end");
  $::progressw->tagAdd("centered", $linechar, "end");
  $::progressw->tagConfigure("centered", -justify => "center");
  $nxt->configure(-text => __('Finish'),
                -command => sub { $mw->destroy; });
}

################### END OF MODULE RETURN 1 FOR REQUIRE ###########

1;

__END__

### Local Variables:
### perl-indent-level: 2
### tab-width: 2
### indent-tabs-mode: nil
### End:
# vim:set tabstop=2 expandtab: #

