#!/usr/bin/perl
use strict;
use warnings;
use File::Copy;

my ( $kde3home, $kde4home );
my $HOME = $ENV{HOME};

# Process arguments
if( @ARGV == 1 )
{
  # if it ends with "help" or a question mark
  if( $ARGV[0] =~ /(?:help|\?)$/i )
  {
    print usage();
    exit 1;
  }

  $kde3home = $ARGV[0];
}
elsif( @ARGV == 2 )
{
  # if either of the two ends with "help" or a question mark
  if( $ARGV[0] =~ /(?:help|\?)$/i || $ARGV[1] =~ /(?:help|\?)$/i )
  {
    print usage();
    exit 1;
  }

  $kde3home = $ARGV[0];
  $kde4home = $ARGV[1];
}
elsif( @ARGV > 2 )
{
  # too many arguments
  print usage();
  exit 1;
}

# Find the old KDE3 directory
if( !defined( $kde3home ) )
{
  my @kdeconfig = `kde-config --version 2>/dev/null`;
  if( !@kdeconfig || $kdeconfig[1] !~ /^KDE: 3\./ )
  {
    # not KDE3 kde-config. Try kde3-config
    @kdeconfig = `kde3-config --version 2>/dev/null`;
    if( !@kdeconfig || $kdeconfig[1] !~ /^KDE: 3\./ )
    {
      # no kde3-config. Check ~/.kde3
      if( ! -e "$HOME/.kde3" || !is_kde3_kmessrc( "$HOME/.kde3/share/config/kmessrc" ) )
      {
        # ~/.kde3 doesn't exist or is not kde3
        # (we assume the kde3 install has a valid kmessrc file)
        # check ~/.kde
        if( ! -e "$HOME/.kde" || !is_kde3_kmessrc( "$HOME/.kde/share/config/kmessrc" ) )
        {
          # Can't find kde3 homedir.
          warn("Could not find the KDE3 home directory.\n");
          warn("Please re-run this script with the KDE3 home directory as the first argument, or install kde-config / kde3-config.\n");
          die("See $0 --help for more information.\n");
        }
        else
        {
          $kde3home = "$HOME/.kde";
        }
      }
      else
      {
        $kde3home = "$HOME/.kde3";
      }
    }
    else
    {
      $kde3home = `kde3-config --localprefix`;
      1 while chomp $kde3home;
    }
  }
  else
  {
    $kde3home = `kde-config --localprefix`;
    1 while chomp $kde3home;
  }
}

# Find the new KDE4 directory
if( !defined( $kde4home ) )
{
  my @kdeconfig = `kde4-config --version 2>/dev/null`;
  if( !@kdeconfig || $kdeconfig[1] !~ /^KDE: 4\./ )
  {
    # no kde4-config. Try kde-config
    @kdeconfig = `kde-config --version 2>/dev/null`;
    if( !@kdeconfig || $kdeconfig[1] !~ /^KDE: 4\./ )
    {
      # not KDE4 kde-config. Check ~/.kde4
      if( ! -e "$HOME/.kde4" || ! -e "$HOME/.kde4/share" )
      {
        # ~/.kde4 doesn't exist
        # check ~/.kde
        if( ! -e "$HOME/.kde" || ! -e "$HOME/.kde/share" )
        {
          # Can't find kde4 homedir.
          warn("Could not find the KDE4 home directory.\n");
          warn("Please re-run this script with the KDE4 home directory as the second\n");
          warn("argument, or install kde-config / kde4-config. If you re-run the\n");
          warn("script, this is what was detected as the first argument:\n$kde3home\n");
          die("See $0 --help for more information.\n");
        }
        else
        {
          if( $kde3home eq "$HOME/.kde" || $kde3home eq "$HOME/.kde/" )
          {
            warn("WARNING: I have not detected a seperate directory for KDE 4. I did,\n");
            warn("however, find .kde in your home directory, but that was also detected as\n");
            warn("your KDE3 directory. If you haven't installed KDE4 or run any KDE4\n");
            warn("application yet, please press Ctrl+C and do so now, then re-run this\n");
            warn("script afterwards; alternatively, try installing kde4-config to make\n");
            warn("sure. If you don't press Ctrl+C, I will assume the home directory for\n");
            warn("both your KDE3 and KDE4 installation is ~/.kde.\n");
            sleepCounter( 30 );
            $kde4home = "$HOME/.kde";
          }
        }
      }
      else
      {
        $kde4home = "$HOME/.kde4";
      }
    }
    else
    {
      $kde4home = `kde-config --localprefix`;
      1 while chomp $kde4home;
    }
  }
  else
  {
    $kde4home = `kde4-config --localprefix`;
    1 while chomp $kde4home;
  }
}

# Confirm
print "KDE 3 local prefix: $kde3home\n";
print "KDE 4 local prefix: $kde4home\n";
print "If this is incorrect, please press Ctrl-C within 5 seconds...\n";
sleepCounter( 5 );
print "Okay, going on with the merge.\n";

# create $kde4home/share/apps/kmess
foreach( "$kde4home", "$kde4home/share", "$kde4home/share/apps", "$kde4home/share/apps/kmess" )
{
  if( ! -d $_ ) {
    mkdir $_ or die("Couldn't create directory $_: $!");
  }
}
my $kmess2dir = "$kde4home/share/apps/kmess";

# Find customImageIndex for every profile
my $kmessrc = "$kde3home/share/config/kmessrc";
open my $kmessrchandle, $kmessrc or die("Couldn't open KDE3 kmessrc ($kmessrc): $!");

my @accounts;
my %customimages;
my $in_profile;
while( <$kmessrchandle> )
{
  # Find [Profile
  if( /^\[Profile_(.+)\]$/ )
  {
    $in_profile = $1;
    push @accounts, $1;
    next;
  }
  elsif( /^\[/ )
  {
    undef $in_profile;
    next;
  }

  if( !$in_profile )
  {
    next;
  }

  if( /^customimageindex=(\d+)$/i )
  {
    $customimages{ $in_profile } = $1;
    next;
  }
}

close $kmessrchandle;

foreach my $handle ( keys %customimages )
{
  my $imageid = $customimages{$handle};
  my $accountdir = "$kmess2dir/$handle";
  # Create an account directory for this account if it doesn't exist yet
  if( ! -e $accountdir )
  {
    mkdir $accountdir or die "Couldn't create directory for handle $handle ($accountdir): $!";
  }

  if( ! -e "$accountdir/displaypics" )
  {
    mkdir "$accountdir/displaypics" or die "Couldn't create displaypics directory for handle $handle: $!";
  }

  # Move the display picture to a new nice location
  my $oldPicturePath = "$kde3home/share/apps/kmess/msnpicture-$handle-$imageid.png";
  if( -e $oldPicturePath )
  {
    my $newPicturePath = "$accountdir/displaypics/merged-msnpicture-$imageid.png";
    copy( $oldPicturePath, $newPicturePath ) or die("Couldn't copy $oldPicturePath to $newPicturePath: $!\n");

    # add it to the settings
    my $accountsettings = "$accountdir/settings";
    open my $accountsettingshandle, '>>', $accountsettings or die("Couldn't open $accountsettings: $!");
    print $accountsettingshandle "displayPicturePath=$newPicturePath\n";
  }
  else
  {
    warn("Couldn't merge your avatar: $oldPicturePath doesn't exist.\n");
  }
}

# merge custom emoticons
foreach my $handle (@accounts)
{
  my $olddir = "$kde3home/share/apps/kmess/customemoticons/$handle";
  if( -e $olddir )
  {
    my $newdir = "$kde4home/share/apps/kmess/$handle/customemoticons";
    if( ! -e $newdir )
    {
      mkdir $newdir or die("Couldn't create $newdir: $!");
    }

    opendir my($dirh), $olddir;
    while( my $file = readdir( $dirh ) )
    {
      next if( $file eq "." || $file eq ".." );
      copy( "$olddir/$file", $newdir ) or warn("Couldn't copy $olddir/$file to $newdir: $!\n");
    }
    closedir $dirh;
  }
}

print "The merge is complete.\n";
print "You can now continue installing KMess 2.0. When you log in, your display\n";
print "picture and custom emoticons should be preserved.\n";

exit 0;

# Helper methods
sub usage
{
"Syntax:
   $0 [kde3home [kde4home]]

This script merges some of the data from KMess 1.5 (KDE3) to KMess 2.0 (KDE4).

If kde3home is not given, the script will check with kde-config; if that script
does not exist or it's not for KDE3 it checks with kde3-config, and falls back
to ~/.kde3 then ~/.kde. If kde4home is not given, the script will check with
kde4-config; if that script does not exist it will check with kde-config if
it's for KDE4, and fall back to ~/.kde4 then ~/.kde.

In any case, it will tell you what directories it's going to use, and it will
give you time to cancel the script if they are incorrect.
";
}

sub is_kde3_kmessrc
{
  my( $kmessrc ) = @_;

  # We check whether the given kmessrc is for KMess 1.5 or 2.0, simply by
  # checking if we can find a "[Contact_" in it. KMess 2.0 doesn't have that
  # anymore, so if no '[Contact_' is found in the file, we assume it's not
  # KMess 1.5. (by the way, this assumes the user ever logged in to KMess and
  # had "remember account" enabled - if he didn't, there's no merging anyway)

  my $result = 0;
  my $handle;
  if( !open $handle, $kmessrc )
  {
    warn "Failed to open KMessRC file $kmessrc: $!";
    return 0;
  }

  while(<$handle>) {
    if( /^\[Contact_/ )
    {
      close $handle;
      return 1;
    }
  }

  close $handle;
  return 0;
}

sub sleepCounter
{
  my ($seconds) = @_;

  $| = 1;

  if( $seconds <= 0 )
  {
    print "\r0             \n";
    return;
  }

  print "\r" . $seconds . "        ";
  sleep 1;
  sleepCounter( $seconds - 1 );
}
