#!/usr/bin/perl

# ipodreader 2.0
#
#       Concept and Specifications: Jesse Endahl
#                                   rystic@rystic.com
#                                   http://rystic.com/
#
#                      Programming: Lasar Liepins
#                                   lasar@liepins.net
#                                   http://liepins.net/ , http://liepins.de/
#
# Changes to accomodate Gen3 iPods: Tim Fox
#                                   timmo@alphalink.com.au
#                                   http://www.alphalink.com.au/~timmo/

# Version history:
#
# 2.0 - Third public release with lots of changes
#       Added support for generation 3 iPods.
#       New installer based on OSX package.
# 1.0 - First public release. Virtually identical to 0.4.
# 0.4 - (Hopefully) last fixes, rewrite of a piece of the code.
# 0.3 - A couple of smaller changes.
# 0.2 - Several fixes, new switches and new "docs".
# 0.1 - First version.

use Getopt::Std;
use File::Basename;

getopts ( "123t:d:f:hv" );

my $gen = 0;
if ( $opt_1 ) {
	$gen = 1;
} elsif ( $opt_2 ) {
	$gen = 2;
} elsif ( $opt_3 ) {
	$gen = 3;
}

# If -h was called
if ( $opt_h )
	{
		print <<END;
Usage: ipodreader [-x] [-t 'Title'] [-d target_dir] [-f filename] textfile

ipodreader is used to convert etexts of any kind into a bunch of files which
can be imported into Apple's iPod (http://www.apple.com/ipod/).

Options:
-1, -2, -3            The iPod version the files are meant for. The generation 3
                      players use a different format. Defaults to version 1.
-t 'Title of Book'    The title to be used in the resulting files.
-d targetdirectory    The directory where all files will be stored.
                      Will be created if it does not exist.
-f filename           The name of the files to be created. Note that this
                      is only the start of the filename. The resulting files
                      will be called filename-0001.vcf, filename-0002.vcf etc.
-v                    Displays version info.
-h                    Displays this.

ipodreader creates a directory with either the specified name or the default
textfile+"_ipod", which it fills with text files by default called
filename-0001.vcf or filename-0001.txt. The -t switch is used to give the files
proper titles, otherwise this will also default to the name of the text file.

The resulting files can be imported into your iPod by copying them to the
Contacts folder on your generation 1 and 2 iPods, to the Notes folder if you
have a generation 3 iPod.
END
;
exit;
	}

if ( $opt_v ) {
	print "2.0\n";
}

if ( $gen < 1 ) {
	$gen = 1;
	print "No iPod version specified. Defaulting to $gen\n";
}

print "iPod version: $gen\n";

my $file = shift;

# Die if no file is specified
if ( !length($file) )
	{ &quit ( "Error: You must specify a file to convert. Try ipodreader -h for help." ); }

# Number of characters per file.
	my $cutoff = 1000;
if ( $gen eq 3 ) {
	$cutoff = 4000;
}

my $filecount = 0;

# Attempt to get the file, otherwise die.
if ( open(IN,"<$file") )
	{
		print "Reading file $file... ";
		my @in = <IN>;
		close ( IN );
		$text = join ( "", @in );
		if ( $gen eq 3 ) {
			$text =~ s/\n|\r\n|\r/\<P>/g;
		} else {
			$text =~ s/\n|\r\n|\r/\\n/g;
		}
		print $#in." lines.\n";
	}
else
	{ &quit ( "Error: The file you specified could not be opened." ); }

# Set title
my $title = basename($file);
if ( length($opt_t)>0 )
	{ $title = $opt_t; }

print "Title: $title\n";

# Set filename
if ( $gen eq 3 ) {
	my $fname = basename($file);
	if ( length($opt_f)>0 )
		{ $fname = $opt_f; }
	print "Filename: $fname\n";
}

# Create directory.
my $dir = $file."_ipod";
if ( length($opt_d) )
	{ $dir = $opt_d; }
if ( ! -e $dir )
	{ system ( "mkdir", "-p", $dir ); }
if ( ! -e $dir )
	{ &quit ( "Could not create the directory $dir." ); }

print "Directory: $dir\n";

# Define true cutoff point.
$cutoff = $cutoff - length ( &vcardify("1234") );
print "Allowed characters per file: $cutoff\n";

$working = 1;

print "Please wait";

# Get to it!
while ( $working )
	{
		# Go to next file.
		$filecount++;

		# Generate new filename.
		if ( $gen eq 3 ) {
			$fname = basename($file)."-".&zeropad($filecount,4).".txt";
			$fname_next = $fname."-".&zeropad($filecount+1,4).".txt";
		} else {
			$fname = basename($file)."-".&zeropad($filecount,4).".vcf";
		}

		# We now continue with taking apart $text...

		# Maybe the remaining text is < $cutoff?
		# If so, then we are done.
		if ( length($text) < $cutoff )
			{
				$part = $text;
				$ok = 1;
				$working = 0;
			}
		else # Retrieve text part.
			{ $part = substr ( $text, 0, $cutoff ); }

		# . , linebreak space

		# Find next cut point.
		if ( $part =~ /\./ ) # Find last "."
			{
				my @temp = split ( /\./, $part );
				my $piece = pop ( @temp );
				$part = substr ( $text, 0, length($part)-length($piece) );
			}
		elsif ( $part =~ /,/ ) # Find last ","
			{
				my @temp = split ( /\,/, $part );
				my $piece = pop ( @temp );
				$part = substr ( $text, 0, length($part)-length($piece) );
			}
		elsif ( $part =~ /\\n/ ) # Find last "\\n"
			{
				if ( $gen eq 3 ) {
					my @temp = split ( /<p>/, $part );
				} else {
					my @temp = split ( /\\n/, $part );
				}
				my $piece = pop ( @temp );
				$part = substr ( $text, 0, length($part)-length($piece) );
			}
		elsif ( $part =~ / / ) # Find last " "
			{
				my @temp = split ( / /, $part );
				my $piece = pop ( @temp );
				$part = substr ( $text, 0, length($part)-length($piece) );
			}

		# Write out file
		if ( open(OUT,">$dir/$fname") )
			{
				print OUT &vcardify ( $filecount, $part );
				close ( OUT );
				print ".";
			}
		else
			{ &quit ( "Error: The output file $dir/$fname could not be opened." ); }

		# Remove $part from $text.
		$text = substr ( $text, length($part) );
	}

print "\nDone.\n";

# Return stuff in correct format
sub vcardify
	{
		my $page = $_[0];
		my $text = $_[1];

		if ( $gen eq 3 ) {
			$next_file = $_[2];
			$ret = "<meta name=\"LineWrap\" content\=\"true\">";
			$ret .="<title>$title ".$page."<\/title>";
			if ($working) {
				$ret .= "<a href=\"$next_file\">Next (Page ".($page+1).")<\/a><br>"; }
			$ret .= "$text<br>";
			if ($working) {
				$ret .= "<a href=\"$next_file\">Next (Page ".($page+1).")<\/a>"; }
		} else {
			$ret = "begin:vcard\n";
			$ret .= "version:3.0\n";
			$ret .= "fn:".$title.", Page ".$page."\n";
			$ret .= "n:".$title.", Page ".&zeropad($page,4).";;;;\n";
			$ret .= "title:$text\n";
			$ret .= "end:vcard\n";
		}

		return $ret;
	}

sub quit
	{
		print $_[0]."\n";
		exit;
	}

sub zeropad
	{
		my $ret = "";
		$ret .= "0" x ($_[1]-length($_[0]));
		$ret .= $_[0];
		return $ret;
	}
