#!/usr/bin/perl

use warnings;
use File::Basename qw(basename dirname);

#################
# configuration #
#################

# vars prompted in interactive mode - edit those for sure if you don't use --interactive
#
$default{"tmp_dir"}    = ".";    # dir where your pictures are
$default{"base_dir"}  = "/home/linuxbrit.co.uk/pics";  # dir to put finished product in
$default{"subdirname"}  = "";
$default{"thumb_size"}  = "130x130";    # size for the thumbnails
$default{"convert_sizes"}  = "640x480 800x600 1024x768 1600x1200"; # first size is thumb size

#############

# general config vars that are not prompted in --interactive mode
#
$config{"convert_xoptions"}  = "-quality 75";  # extra options for conver program

# do a couple general things
#
$version = "0.2";  # set version number
$| = 1;      # autoflush output (for progress meter)

###################
# user prefs code #
###################

#
# sets all the user's prefs
#
sub thumbs_get_prefs {
  print "###################\n";
  print "## configuration ##\n";
  print "###################\n\n";
  
  print "* hit enter for [default] *\n\n";

  # tmp dir where image are located
  #
  print "Directory with images to be 'thumbed' [$default{tmp_dir}]\n";
  print "\t\t\t\t: ";
  $user{"tmp_dir"} = <STDIN>;
  chomp($user{"tmp_dir"});
  
  if (!$user{"tmp_dir"}) {
    $user{"tmp_dir"} = $default{"tmp_dir"};
  }
  
  # dir base to put finished product in
  #
  print "Directory to put converted images [$default{base_dir}]\n";
  print "\t\t\t\t: ";
  $user{"base_dir"} = <STDIN>;
  chomp($user{"base_dir"});

  if (!$user{"base_dir"}) {
    $user{"base_dir"} = $default{"base_dir"};
  }
  
    print "Subdirectory name [$default{subdirname}]\n";
    print "\t\t\t\t: ";
    $user{"subdirname"} = <STDIN>;
    chomp($user{"subdirname"});

    if (!$user{"subdirname"}) {
        $user{"subdirname"} = $default{"subdirname"};
    }

  # pref thumb size
  #
  print "Thumb image size (wxh) [$default{thumb_size}]\n";
  print "\t\t\t\t: ";
  $user{"thumb_size"} = <STDIN>;
  chomp($user{"thumb_size"});

  if (!$user{"thumb_size"}) {
    $user{"thumb_size"} = $default{"thumb_size"};
  }

  # convert size prefs
  #
  print "Conversion sizes [$default{convert_sizes}]\n";
  print "\t\t\t\t: ";
  $user{"convert_sizes"} = <STDIN>;
  chomp($user{"convert_sizes"});
  
  if (!$user{"convert_sizes"}) {
    $user{"convert_sizes"} = $default{"convert_sizes"};
  }
}

#
# verify the user's prefs
#
sub thumbs_verify_prefs {
  my(@error, $err);

  # verify valid dirs
  #

  if (! -d $user{"tmp_dir"}) {
    push(@error, "invalid tmp dir");
  }
  if (! -d $user{"base_dir"}) {
    push(@error, "invalid base dir");
  }
    if (! $user{"subdirname"}) {
    push(@error, "need a subdir");
    }

  # check thumb size
  #
  if (!$user{"thumb_size"}) {
    push(@error, "need a thumb size");
  }
    
  # check the conversion sizes (format: wxh wxh wxh)
  #
  if ($user{"convert_sizes"}) {
    @convert_sizes = split(" ", $user{"convert_sizes"});

    foreach $size (@convert_sizes) {
      if ($size !~ /^(\d{1,4}x\d{1,4})$/) {
        push(@error, "conversion sizes in bad format");
        last;
      }
    }
  } else {
    push(@error, "must have conversion sizes");
  }
  
  if (@error) {
    print "\n";
    print "Errors encountered in your preferences:\n";
    foreach $err (@error) {
      print "* $err\n";
    }
    
    print "\n\n";

    exit;
  }
}


##############
# conversion #
##############

#
# creates the dir for the new set
# returns: the dir created on success
#
sub thumbs_dir_prepare {
  my($set_dir);
  
  $set_dir = "$user{base_dir}/$user{subdirname}";
    if (mkdir($set_dir, 0755)) {
        chmod(0755, $set_dir);
        mkdir("$set_dir/thumbs", 0755);
        chmod(0755, "$set_dir/thumbs");
        foreach $size (@convert_sizes) {
          mkdir("$set_dir/$size", 0755);
          chmod(0755, "$set_dir/$size");
        }
        return($set_dir, $user{"subdirname"});
    } else {
        die("Error making new set dir: $!");
    }
}

#
# convert the images and place them in the proper location
# also populate the $images hash with info we'll need throughout
#
sub thumbs_convert_images {
  my($image_count, $image_num, $image_file, $image_file_newname);
  
  $image_count = 0;
  
  print "\n######################\n";
  print "## image conversion ##\n";
  print "######################\n\n";
  
  print "Converting images";
  
  foreach $image_file (<$user{"tmp_dir"}/*>) {
    # check if binary... probably an image =)
    if (-B $image_file) {
      $image_num = $image_count + 1;
      $images[$image_count]{"filename"} = $image_file;
      $images[$image_count]{"base_name"} = basename($image_file);
      $images[$image_count]{"image_num"} = $image_num;
      
      $_ = $image_file;
      /.{1}\.([a-zA-Z]{3,4})/;
      $images[$image_count]{"file_suffix"} = $1;
      $images[$image_count]{"thumb_file"}  = $image_file;
      thumbs_convert_image_sizes($images[$image_count]);
      
      ++$image_count;
    }
  }

  print "Done\n";
}

#
# convert the image to all the different sizes
#
sub thumbs_convert_image_sizes {
  my($image) = @_;
  my($size, $image_name);  
  
  # convert to each size
  foreach $size (@convert_sizes) {
    $size =~ m/(\d+)x(\d+)/;
    my $width = $1;
    my $height = $2;
    # Make the geometry square so convert does the right thing.
    my $max = ($width > $height) ? $width : $height;
    my $geom = $max . "x" . $max;
    $image_name = $image->{"base_name"};
    system("convert $config{convert_xoptions} -geometry $geom $image->{filename} " . "$set_dir/$size/$image_name\n");
  }

  # create a thumbnail
  system("convert $config{convert_xoptions} -geometry $user{thumb_size} ".
        "$image->{filename} $set_dir/thumbs/$image->{thumb_file}");

  # progress meter =)
  print ".";
  
}


#####################
# general functions #
#####################

#
# make the default prefs, the user prefs
#
sub thumbs_default_prefs {
  my($pref_option);

  foreach $pref_option (keys(%default)) {
    $user{$pref_option} = $default{$pref_option};
  }
}

#
# print out program usage, exit
#
sub thumbs_usage {
  print "Usage: thumbs.pl [OPTION]\n\n";
  print "\t-i, --interactive\t\tsome config settings prompted\n";
  print "\t-d, --default\t\t\tdefault mode, uses defaults within file\n";
  print "\t-h, --help\t\t\tdisplay help (this menu) and exit\n";
  print "\t-v, --version\t\t\toutput version and exit\n\n";
  exit;
}

#
# print out the version number, exit
#
sub thumbs_version {
  print "\nthumbs.pl version $version\n\n";
  exit;
}

#
# print out little intro ascii
#
sub thumbs_intro {
  print "\n";
  print "################################\n";
  print "#### ---- webthumbs.pl ---- ####\n";
  print "################################\n";
  print "\t[version $version]\n\n";
}

#
# check ARGV for options
#
sub thumbs_option_check {
  my($arg_count);

  $arg_count = @ARGV;

  if ($arg_count == 1) {
    $_ = $ARGV[0];
    if (/^-{1,2}i/) {
      $mode_interactive = 1;
    } elsif  (/^-{1,2}d/) {
      $mode_interactive = 0;
    } elsif  (/^-{1,2}h/) {
      thumbs_usage();
    } elsif  (/^-{1,2}v/) {
      thumbs_version();
    } else {
      thumbs_usage();
    }
  } else {
      $mode_interactive = 1;
  }
}


################
#         #
# main control #
#         #
################

# check ARGV
thumbs_option_check();

# print intro =)
thumbs_intro();

# user prefs
if ($mode_interactive) {
  thumbs_get_prefs();
} else {
  thumbs_default_prefs();
}
thumbs_verify_prefs();

# make the new set dir
($set_dir, $set_name) = thumbs_dir_prepare();

# convert images and place them in the new set dir
thumbs_convert_images();
