######################################################################
#
#  GTK.PL - wmtheme support for GTK themes
#

use Cwd;
choke("$programname: root usage is not supported.") unless $>;

$tosite = 'gtk.classic.themes.org';
$badnamechars = '"';
$no_run_check = 1;
$modulepath = "$home/.themes/theme-engines";
$gtkrc = "$home/.gtkrc";
$autoblurb = "# -- THEME AUTO-WRITTEN DO NOT EDIT";

insistdir("$home/.themes");

  ###
  #
  #  WM_GETDEFAULTDIRS
  #
  ###

sub wm_getdefaultdirs {
  my ($gtkconfig, $gtkprefix);
  my @guesses = ("$home/.themes");

  if ($gtkconfig = findexe('gtk-config') and
      $gtkprefix = `$gtkconfig --prefix`) {
    $gtkprefix =~ s!\n!/share/themes!;
    push @guesses, $gtkprefix;
  }

  verify_themedirs(0, @guesses, "/usr/share/themes",
    "/usr/local/share/themes");
}

  ###
  #
  #  WM_SCANDIR
  #
  ###

sub wm_scandir {
  my $dir = shift;
  my (%scanned, $entry, $owner);

  $scanned{$dir} = (stat $dir)[9];
  $owner = (stat _)[4];
  opendir DH, $dir or choke("Can't opendir $dir: $!");
  while (defined($entry = readdir DH)) {
    next if $entry =~ /^\.\.?$/;
    if (-f "$dir/$entry/gtk/gtkrc") {
      createthemerec($entry, "$dir/$entry", $owner);
    }
  }
  closedir DH;
  %scanned;
}

  ###
  #
  #  WM_INSTALLTHEME
  #
  ###

sub wm_installtheme {
  my ($location, $filename, $defname) = @_;
  my ($themename, $entry, $themedir, $conflocation);

  unless ($localthemedir) {
    choke("No local theme directory: can't install GTK themes");
  }

  unless (-d $location) {
    choke("GTK themes must be installed from a directory. (Internal error?)");
  }

  if ($defname) {
    $themename = $defname;
  } elsif ($themedir = findsubdirwithfile($location, 'gtkrc') and
           $themedir =~ m!([^/]+)/gtk$!) {
    $themename = $1;
  } elsif ($filename =~ m!([^/.]+)[^/]*$!) {
    $themename = $1;
  } else {
    choke("Can't extract a name from $location!");
  }
    
  $themename = checkname($themename);

  $conflocation = findsubdirwithfile($location, 'configure');
  if ($conflocation and confirm_engine_install()) {
    install_engined_gtk($conflocation, $themename);
  } else {
    $rclocation = findsubdirwithfile($location, 'gtkrc');
    if ($rclocation and $rclocation =~ s!([^/])/gtk$!$1!) {
      $themedir = $rclocation;
      dbugout("found themedir $themedir") if $debug;
      syscmd('mv', $themedir, "$localthemedir/$themename");
    } else {
        choke("Theme doesn't seem to have a gtk/gtkrc file; can't install");
    }
  }

  createthemerec($themename, "$localthemedir/$themename", $>);
  $themename;
}

  ###
  #
  #  WM_ACTIVATETHEME
  #
  #  This is how we make sure the local theme-engines directory
  #  doesn't get forgotten, even if you go and use gnomecc's
  #  theme-selector capplet.
  #
  #  *  ~/.gtkrc must have a module_path setting pointing to the
  #     local theme engines directory.  Now, gnomecc might erase
  #     this line if we're not careful.  If we do the following,
  #     it will be safe:
  #
  #       1.  Ensure there are a pair of lines like this:
  #
  #           # -- THEME AUTO-WRITTEN DO NOT EDIT
  #
  #       2.  Put the module_path line above those.
  #
  #  *  Secondly we would like to emulate gnomecc's habits when
  #     writing .gtkrc, so only stuff between the # -- THEME ...
  #     lines will be modified.  Except that the module_path
  #     will go in front of that, once.
  #
  ###

sub wm_activatetheme {
  my ($themename, $explicit) = @_;
  my $rctext = '';
  my $include = "include \"$themes{$themename}{path}/gtk/gtkrc\"\n\ninclude \"$home/.gtkrc.mine\"\n";

  $rctext = slurpfile($gtkrc) if -e $gtkrc;

  if ($rctext =~ s/\Q$autoblurb\E.*\Q$autoblurb\E/$autoblurb\n$include\n$autoblurb/s) {
    if ($rctext !~ /^\s*module_path\s+"\Q$modulepath\E"/m) {
      $rctext = "module_path \"$modulepath\"\n\n$rctext";
    }
  } else {
    $rctext = "module_path \"$modulepath\"\n\n$autoblurb\n$include\n$autoblurb\n$rctext";
  }

  stowfile("$home/.gtkrc", $rctext);

  if (my $agtfile = findexe('apply-gtk-theme', '.')) {
    syscmd($agtfile);
  }
}

  ###
  #
  #  WM_UNINSTALLTHEME
  #
  ###

sub wm_uninstalltheme {
  my $themename = shift;

  dirwipe($themes{$themename}{path}, 1);
}

  ###
  #
  #  WM_RENAME
  #
  ###

sub wm_rename {
  my ($old, $new) = @_;
  my $path = $themes{$old}{path};

  if ($path =~ s!/\Q$old\E$!/$new!) {
    system('mv', $themes{$old}{path}, $path);
    $path;
  } else {
    choke("Internal error: couldn't strip \"$old\" from the end of $path");
  }
}

  ###
  #
  #  WM_VERSIONOK
  #
  ###

sub wm_versionok {
  1;
}

sub confirm_engine_install {
  read_userconfig();
  if ($config_wm{install_gtk_engines} eq 'yes') {
    1;
  } elsif ($config_wm{install_gtk_engines} eq 'no') {
    0;
  } else {
    print "This theme has a custom engine.  Do you want to install it? [Y/n] ";
    if (<STDIN> =~ /^\s*[nN]/) {
      finish("Installation cancelled.");
    }
    1;
  }
}

sub install_engined_gtk {
  my ($location, $themename) = @_;
  my $cwd = cwd();
  my $tmp = "$location/gtktheme-install-tmp.$$";
  my $enginedir = "$tmp/lib/gtk/themes/engines";
  my ($themedir, $entry, $linkage);

  chdir $location or choke("Can't chdir to $location: $!");

    # Build that sucker

  chmod 0755, 'configure' or choke("Oops, couldn't chmod 755 configure");
  syscmd('./configure') and choke("Looks like configuration failed.");
  syscmd('make') and choke("Shucks, couldn't build this sucker.");
  mkdir $tmp, 0755 or choke("Can't mkdir $tmp: $!");

    # Install to this temporary spot so we can munge it in a moment

  syscmd('make', 'install', "prefix=$tmp", "exec_prefix=$tmp") and
    choke("Too bad.  make install failed.");

    # Check out the results of installation

  unless (-d $enginedir) {
    choke("Um, it didn't seem to install to $enginedir.",
      "That's just not acceptable!");
  }
  $themedir = findsubdirwithfile("$tmp/share/themes", 'gtkrc');
  unless (-d $themedir) {
    choke("I can't find a gtkrc in $tmp/share/themes,",
      "so where'd it go?  I quit.");
  }
  $themedir =~ s!/gtk$!! or
    choke("The theme directory, $themedir, is too malformed.",
      "Installation failed.");
  insistdir($modulepath);

    # Gallantly try to move object files!

  opendir DH, $enginedir or choke("Can't opendir $enginedir: $!");
  while (defined ($entry = readdir DH)) {
    next if $entry =~ /^\.\.?$/;
    if (-l "$enginedir/$entry") {
      if ($linkage = readlink "$enginedir/$entry") {
        if ($linkage =~ m!^/!) {
          complain("Warning: skipping evil symlink $enginedir/$entry",
            "pointing to $linkage");
        } else {
          symlink $linkage, "$modulepath/$entry" or
            choke("Can't symlink $linkage to $modulepath/$entry: $!");
        }
      } else {
        complain("Warning: can't deal with symlink $enginedir/$entry");
      }
    } elsif (-f "$enginedir/$entry") {
      syscmd('mv', "$enginedir/$entry", $modulepath);
    } # yup, we're skipping dirs and other folks
  }
  closedir DH;

    # Now move the ordinary theme directory.

  syscmd('mv', $themedir, "$localthemedir/$themename");
}

1;

