#!/usr/bin/perl
#
#
#
##############################################
#                                            #
#     YPlib 0.3 - Your Personal Library      #
#         written by Jan Schaumann           #
#                                            #
#     YPlib 0.3 is published under the       #
#     GPL and comes with no warranty         #
#                 whatsoever                 #
#                                            #
#     You can obtain YPlib 0.3 (or maybe     #
#      even more recent versions) from       #
#         http://www.netmeister.org          #
#                                            #
#       Please send all Bug-Reports to       #
#          <jschauma@netmeister.org>         #
#                                            #
#     This is "yplib" - the Personal         #
#   Library main program.  You need to       #
# run yplib before you put yplibd into your  #
#                 crontab.                   #
#                                            #
##############################################
my $Version = "0.3";

##############################################
#  Standard arguments:                       #
##############################################

if (($ARGV[0] eq "-h") || ($ARGV[0] eq "--help")) {
    print "\n\"yplib\" is part of \"YPLib\", Your Personal Library.\n";
    print "Please see yplib(1), yplibd(1) and\/or\n";
    print "http:\/\/www.netmeister.org\/apps\/yplib\/index.html for further information.\n\n";
    print "Usage: yplibd [OPTION]\n";
    print "OPTIONS:\n";
    print "   -h, --help      print out this screen and exit\n";
    print "   -v, --version   print out version number and exit\n\n";
    exit(0);
}

if (($ARGV[0] eq "-v") || ($ARGV[0] eq "--version")) {
    print "yplib version: $Version\n";
    exit(0);
}
     

use Shell qw(date touch mkdir);

# Initialize some variables
my $home = $ENV{HOME};

my $thepath = "$home/.yplib";
my $prefs = "$thepath/yplib.prefs";
my $libs = "$thepath/libs";
my $outbooks = "$thepath/out";
my $returnflag = 0;

# sub-declaration
sub editPrefs;
sub showPrefs;
sub enterLibs;
sub deleteLibs;
sub enterEmail;
sub rentBook;
sub listBooks;
sub returnBook;

# let's see if all files are there
-d $thepath or mkdir $thepath;
touch $libs;
touch $prefs;
touch $outbooks;

# open a bunch of files
open(PREFS, "$prefs") or die "Cannot open file $prefs!\n"; 
open(LIBS, "$libs") or die "Cannot open file $libs for reading!\n";
open(OUTBOOKS, "$outbooks") or die "Cannot opn $outbooks for reading!\n";

# some initial values
my $choice = 1;
my $days =0;
my $numoflibs=0;
my $firstbook = 0;
my $numoutbooks = 0;
my $tmp = "";


# check existing preferences
my @allprefs = split /:/, <PREFS>;

$days = $allprefs[1];
chomp($days);
if ($days eq "") {
  $tmp = 1;
  $days=3;
}

while ($lines = <LIBS>) {
  $numoflibs++;
}

my $email = $allprefs[5];
chomp($email);
if ($email eq "") {
  $email = $ENV{LOGNAME} . "@" . $ENV{HOSTNAME};
}

$numoutbooks = $allprefs[7];
chomp($numoutbooks);
if ($numoutbooks eq "") {
  $numoutbooks = 0;
}

#this is the first time, we need to write the initial data
if ($tmp==1) {
  open(PREFS, ">$prefs") or die "Cannot open $prefs for writing!\n";
  print PREFS "Remind:$days:Number of Libraries:$numoflibs:Email:$email:Number of books:0:";
}
if ($numoflibs==0) {
  print "\nWelcome to YPlib 0.3!";
  print "\nI already gathered some information, but I still need a Library.\n";
  print "\nPlease enter the name of your Library: ";
  chomp($libname=<STDIN>);
  while ($libname eq "") {
    print "\nPlease enter the name of your Library: ";
    chomp($libname=<STDIN>);
  }
  print "\nPlease enter the street of your Library: ";
  chomp($libstreet=<STDIN>);
  while ($libstreet eq "") {
    print "\nPlease enter the street of your Library: ";
    chomp($libstreet=<STDIN>);
  }
  print "\nPlease enter the City, State and Zip-Code of your Library: ";
  chomp($libstate=<STDIN>);
  while ($libstate eq "") {
    print "\nPlease enter the City, State and Zip-Code of your Library: ";
    chomp($libstate=<STDIN>);
  }
  print "\nWhat is the late-fee at $libname per book (cents per day)? Enter 0 if unknown. ";
  chomp($fee = <STDIN>);
  while ($fee eq "") {
    print "\nWhat is the late-fee at $libname per book (cents per day)? Enter 0 if unknown. ";
    chomp($fee = <STDIN>);
  }
  $numoflibs++;
  open(LIBS, ">$libs") or die "Cannot open $libs for writing!\n";
  print LIBS "1:$libname:$libstreet:$libstate:$fee:\n";
  # want some more?
  enterLibs;
}
# begin main menu
while ($choice!=7) {
  print "\nYPlib 0.3 -- Main Menu\n";
  print "----------------------------";
  print "\nPlease choose from the following menu.\n";
  print "\n1. Change User Preferences";
  print "\n2. Show current settings";
  print "\n3. Rent a book";
  print "\n4. List all books you checked out";
  print "\n5. Return a book";
  print "\n6. About YPlib 0.3";
  print "\n7. Quit";
  print "\n\nYour choice: ";
  
  $firstbook = 0;
  $returnflag = 0;
  
  $choice = <STDIN>;
  chomp($choice);
  
  # we want to edit the preferences
  if ($choice==1) {
    editPrefs;
  }
  
  # let's see what our preferences are
  elsif ($choice==2) {
    showPrefs;
  }
  
  # we want to rent a book
  elsif ($choice==3) {
    rentBook;
  }
  
  # list all the books that are checked out
  elsif ($choice==4) {
    listBooks;
  }
  
  # return a book
  elsif ($choice==5) {
    returnBook;
  }
  
  # what is YPlib?
  elsif ($choice==6) {
    print "\nAbout YPlib ";
    print "\n------------------------";
    print "\nThis is Version 0.3 of \"YPlib\" - your Personal Library.";
    print "\nYPlib is written by Jan Schaumann <jschauma\@netmeister.org> and published under the GNU Public License and thus comes without any warranty whatsoever. You can feel free to modify and\/or redistribute this code as specified in the GPL. YPlib is available for free from http:\/\/www.netmeister.org.\nPlease send Bug-reports to <jschauma\@netmeister.org>.\nFor more information, please see the man-pages (yplib(1)).\n";
  }
  
  # we're done - write some data and say bye bye
  elsif ($choice==7) {
    open(PREFS, "$prefs") or die "Cannot open $prefs for writing!\n";
    $_ = <PREFS>;	
    if (m/Number of books:\d/) {
      s/Number of books:\d/"Number of books:$numoutbooks"/e;
      open(PREFS, ">$prefs") or die "Cannot open $prefs for writing!\n";
      print PREFS "$_";
    }
    if (m/Number of Libraries:\d/) {
      s/Number of Libraries:\d/"Number of Libraries:$numoflibs"/e;
      open(PREFS, ">$prefs") or die "Cannot open $prefs for writing!\n";
      print PREFS "$_";
    }
  }	
}

sub editPrefs {
  open(PREFS, ">$prefs") or die "Cannot open $prefs for writing!\n";
  print "\n\nYPlib 0.3 -- Edit User Preferences:\n";
  print "-----------------------------------------\n";
  print "\nHow many days in advance would you like to be reminded that your book is due? [current setting: $days]";
  $days = <STDIN>;
  chomp($days);
  while (($days<=0)||($days eq "")) {
    print "\nHow many days in advance would you like to be reminded that your book is due? [current setting: $days]";
    $days = <STDIN>;
    chomp($days);
  }
  
  print PREFS "Remind:$days:";
  
  # want some more?
  enterLibs;

  # wanna getrid of one?
  if ($numoflibs>1) {
    deleteLibs;
  }

  print PREFS "Number of Libraries:$numoflibs:";
  enterEmail;
  print PREFS "Email:$email:Number of books:$numoutbooks:";
}

sub showPrefs {
  print "\nYPlib 0.3 -- Show current settings\n";
  print "---------------------------------------";
  print "\n\nYour current settings are:";
  print "\nEmail-Address: $email";
  print "\nDays you are reminded in advance: $days";
  print "\nNumber of Libraries: ";
  print $numoflibs;
  print "\n";
  open(LIBS, "$libs") or die "Cannot open $libs for reading!\n";  
  while($line = <LIBS>) {
    ($num, $name, $street, $state, $cost) = split(":", $line);
    print "\nLibrary Nr. $num:";
    print "\n$name\n$street\n$state\n";
    if ($cost>0) {
      chomp($cost);
      print "Late fee: $cost cent (per book / per day)\n";
    }
  }
  
}

sub enterLibs {
  print "\nWould you like to add another Library?[y/n] ";
  $input = <STDIN>;
  chomp($input);
  while (!(($input eq "y") || ($input eq "n") || ($input eq "Y") || ($input eq "N"))) {
    print "\nWould you like to add another Library? [y/n] ";
    chomp($input = <STDIN>);
  }
 
  open (LIBS, ">>$libs") or die "Cannot open $libs for appending\n";
  
  while (($input eq "y")||($input eq "Y")) {
    $numoflibs++;
    print "\nPlease enter the name of Library Nr $numoflibs: ";
    chomp($libname=<STDIN>);
    while ($libname eq "") {
      print "\nPlease enter the name of your Library: ";
      chomp($libname=<STDIN>);
    }
    print "\nPlease enter the street of your Library: ";
    chomp($libstreet=<STDIN>);
    while ($libstreet eq "") {
      print "\nPlease enter the street of your Library: ";
      chomp($libstreet=<STDIN>);
    }
    print "\nPlease enter the City, State and Zip-Code of your Library: ";
    chomp($libstate=<STDIN>);
    while ($libstate eq "") {
      print "\nPlease enter the City, State and Zip-Code of your Library: ";
      chomp($libstate=<STDIN>);
    }
    print "\nWhat is the late-fee at \"$libname\" per book (cents per day)? Enter 0 if unknown. ";
    chomp($fee = <STDIN>);
    while ($fee eq "") {
      print "\nWhat is the late-fee at \"$libname\" per book (cents per day)? Enter 0 if unknown. ";
      chomp($libname=<STDIN>);
    }

    print LIBS "$numoflibs:$libname:$libstreet:$libstate:$fee:\n";

    print "\nWould you like to add another Library? [y/n]";
    $input = <STDIN>;
    chomp($input);
    while (!(($input eq "y") || ($input eq "n") || ($input eq "Y") || ($input eq "N"))) {
      print "\nWould you like to add another Library? [y/n] ";
      chomp($input = <STDIN>);
    }
    
  }
  
}

sub deleteLibs {
  print "\nWould you like to delete a Library?[y/n] ";
  $input = <STDIN>;
  chomp($input);
  while (!(($input eq "y") || ($input eq "n") || ($input eq "Y") || ($input eq "N"))) {
    print "\nWould you like to delete a Library? [y/n] ";
    chomp($input = <STDIN>);
  }
  
  while ((($input eq "y")||($input eq "Y"))&&($numoflibs>1)) {
    open (LIBS, "$libs") or die "Cannot open $libs for appending\n";
    print "\nLibraries on file:\n";
    while($line = <LIBS>) {
      ($num, $name, $street, $state, $cost) = split(":", $line);
      print "\n\nLibrary Nr. $num:";
      print "\n$name\n$street\n$state\n";
      if ($cost>0) {
	chomp($cost);
	print "Late fee: $cost cent (per book / per day)\n";
      }
    }
    
    print "\nPlease enter the number of the library you wish to delete from your record [enter 0 if you do not want to delete any]: ";
    chomp($libnum=<STDIN>);
    $_ = $libnum;

    while ( (!(m/^\d/))||($_ eq "\n")||($libnum>$numoflibs)) {
      print "\nPlease enter the number of the library you wish to delete from your record [enter 0 if you do not want to delete any]: ";
      chomp($libnum=<STDIN>);
      $_ = $libnum;
    }

    if ($libnum eq "0") {
      print "Foo";
    }
    unless ($libnum eq "0") {
      $tmp = "";
      open (LIBS, "$libs") or die "Cannot open $libs for reading\n";
      while ($line = <LIBS>) {
	($num, $name, $street, $state, $cost) = split(":", $line);
	unless ($num eq $libnum) {
	  $tmp = $tmp . $line;
	}	
      }
      open(LIBS, ">$libs") or die "Cannot open $outbooks for writing!\n";
      print LIBS "$tmp";
      close LIBS;
      # now we need to re-arrange the numbers
      open (LIBS, "$libs") or die "Cannot open $libs for reading\n";
      $num = 1;
      $tmp = "";
      while ($line = <LIBS>) {
	$_ = $line;
	s/^\d:/"$num:"/e;
	$num++;
	$tmp = $tmp . $_;
      }
      print "\nLibary Nr. $libnum deleted from record!\n";
      open(LIBS, ">$libs") or die "Cannot open $libs for writing!\n";
      print LIBS "$tmp";

    }
    $numoflibs--;
    if ($numoflibs<2) {
      $input = "n";
    }
    else {
      print "\nWould you like to delete a Library?[y/n] ";
      $input = <STDIN>;
      chomp($input);
      while (!(($input eq "y") || ($input eq "n") || ($input eq "Y") || ($input eq "N"))) {
	print "\nWould you like to delete a Library? [y/n] ";
	chomp($input = <STDIN>);
      }
    }
    
  }
  close LIBS;
}

sub enterEmail {
  print "\nWould you like me to send the reminding emails to $email? [y/n] ";
  chomp($input = <STDIN>);
  while (!(($input eq "y") || ($input eq "n") || ($input eq "Y") || ($input eq "N"))) {
    print "\nWould you like me to send the reminding emails to $email? [y/n] ";
    chomp($input = <STDIN>);
  }
  
  if (($input eq "n") || ( $input eq "N")) {
    print "\nPlease enter the email-address you would like the reminders to be sent to now: ";
    chomp($email = <STDIN>);
    while ($email eq "") {
      print "\nPlease enter the email-address you would like the reminders to be sent to now: ";
      chomp($email = <STDIN>);
    }
  }
}

sub rentBook {
  open(OUTBOOKS, ">>$outbooks") or die "Cannot open $outbooks for appending!\n";
  my $whichlib = 0;
  open(LIBS, "$libs") or die "Cannot open $libs for reading!\n";
  unless ($firstbook>0) {
    print "\n\nYPlib 0.3 -- Checkout\n";
    print "-----------------------------";
  }
  print "\nPlease enter the title of the book [enter CANCEL to abort]: ";
  chomp($title = <STDIN>);
  while ($title eq "") {
  	print "\nPlease enter the title of the book [enter CANCEL to abort]: ";
    chomp($title = <STDIN>);
  }
  unless ($title eq "CANCEL") {
  	print "\nPlease enter the due date for this book (mm/dd/yy): ";
  	chomp($date = <STDIN>);
	@currdate = split /\//, `date +%D`;
  	@thedate = split //, $date;
  	$mm = $thedate[0] . $thedate[1];
  	$dd = $thedate[3] . $thedate[4];
  	$yy = $thedate[6] . $thedate[7];
  	while (($thedate[8]) || ($mm>12) || ($dd>31) || ($mm<=0) || ($dd<=0) || ($yy<0) || ($yy>99) || ($thedate[2] eq "")||($thedate[3] eq "") || ($thedate[4] eq "") || ($thedate[5] eq "") || ($thedate[6] eq "") || ($thedate[7] eq "")) {
    	print "\nNot a balid Date!\nPlease enter the due date for this book (mm/dd/yy): ";
    	chomp($date = <STDIN>);
    	@thedate = split //, $date;
    	$mm = $thedate[0] . $thedate[1];
    	$dd = $thedate[3] . $thedate[4];
    	$yy = $thedate[6] . $thedate[7];
  	}
	if ( (($yy==$currdate[2])&&($mm<$currdate[0]))||($yy<$currdate[2])) {
		print "That book is already overdue - I can't accept that!\n";
		$norent = 1;
	}
	if (($yy==$currdate[2])&&($mm==$currdate[0])&&($dd==$currdate[1])) {
		print "That book is due TODAY - I can't accept that!\n";
		$norent = 1;
	}

	unless ($norent) {
		print "\nPlease enter the name of the author: ";
		chomp($author = <STDIN>);
  		if ($numoflibs>1) {
    		print "\nThe following libraries are set in your preferences:";
    		while($line = <LIBS>) {
      			($num, $name, $street, $state, $cost) = split(":", $line);
      			print "\n\nLibrary Nr. $num:";
      			print "\n$name\n$street\n$state";
      			if ($cost>0) {
					chomp($cost);
					print "\nLate fee: $cost cent (per book / per day)\n";
      			}
    		}
    		print "\nPlease enter the library number from which you borrowed this book: ";
    		chomp($whichlib = <STDIN>);
    		while($numoflibs eq "") {
      			print "\nPlease enter the library number from which you borrowed this book: ";
      			chomp($whichlib = <STDIN>);
    		}
  		}
  		if ($numoflibs==1) {
    		$whichlib = $numoflibs;
  		}
  		$numoutbooks++;
  		print OUTBOOKS "Title:$title:DueDate:$date:Library:$whichlib:Author:$author\n";
	}
  	print "\nWould you like to rent another book? [y/n] ";
  	chomp($input = <STDIN>);
  	while (!(($input eq "y") || ($input eq "n") || ($input eq "Y") || ($input eq "N"))) {
    	print "\nWould you like to rent another book? [y/n] ";
    	chomp($input = <STDIN>);
  	}
  
  	if (($input eq "y")||($input eq "Y")) {
    	$firstbook=1;
    	rentBook;
    	close OUTBOOKS;
  	}
  	close OUTBOOKS;
  }
}

sub listBooks {
  my $library=0;
  my $found = 0;
  open(OUTBOOKS, "$outbooks") or die "Cannot open $outbooks for reading!\n";
  unless ($returnflag==1) {
    print "\nYPlib 0.3 -- List of rented books\n";
    print "---------------------------------------";
  }
  @theline = split /:/, <OUTBOOKS>;
  if ($theline[0] eq "") {
    print "\nYou do not seem to have rented any books.\n";
  }
  else {
    print "\nPlease enter a keyword or author name to search the list of rented books [none to view all rented books]: ";
    chomp($key = <STDIN>);
    open(OUTBOOKS, "$outbooks") or die "Cannot open $outbooks for reading!\n";
    while ($line = <OUTBOOKS>) {
      open(LIBS, "$libs") or die "Cannot open $libs for reading!\n";
      $_ = $line;
      if (m/$key/i) {
		($foo, $title, $foo, $duedate, $foo, $library, $foo, $author) = split /:/, $line;
		chomp($author);
		print "\nTitle:\t\t$title";
		print "\nAuthor:\t\t$author";
		print "\nDueDate:\t$duedate";
		while($line = <LIBS>) {
	  		($num, $name, $street, $state, $cost) = split(":", $line);
	  		if ($library == $num) {
	    		print "\nLibrary:\t$name";
	    		print "\n\t\t$street\n\t\t$state\n";
	    		if ($cost>0) {
	      			chomp($cost);
	      			print "\t\tLate fee: $cost cent (per book / per day)\n";
	    		}
	  		}
		}
		$found = 1;
      }
      close LIBS;
    }
    if ($found==0) {
      print "\nNo matches for the keyword \"$key\".\n";
    }
  }

  return $found;
}

sub returnBook {
  $tmp = "";
  $found = 0;
  if ($numoutbooks==0) {
    print "\nYou do not seem to have any rented any books.\n";
  }
  else {
    if ($firstbook==0) {
      print "\nYPlib   3 -- Return a book\n";
      print "---------------------------------";
    }
    $returnflag=1;
    $found = listBooks;
	if ($found) {
    	print "\nPlease enter the exact title of the book you wish to return.\nIf you have multiple books with the same title, please enter the exact name of the author. Enter CANCEL to abort, ALL to return all books: ";
    	chomp($thebook = <STDIN>);
		while ($thebook eq "") {
    		print "\nPlease enter the exact title of the book you wish to return.\n If you have multiple books with the same title, please enter the exact name of the author. EnterCANCEL to abort, ALL to return all books: ";
    		chomp($thebook = <STDIN>);
		}
		unless ($thebook eq "CANCEL") {
    		open(OUTBOOKS, "$outbooks") or die "Cannot open $outbooks for reading!\n";
    		while ($line = <OUTBOOKS>) {
      			$_ = $line;
				@record = split /:/, $line;
				chomp($record[7]);
          		if ($thebook eq "ALL") {
                	$numofbooks--;
                	$found = 1;
            	}
      			elsif (($record[1] eq $thebook)||($record[7] eq $thebook)) {
					print "\n\"$thebook\" found - record removed.";
					$numoutbooks--;
					$found = 1;
      			}
      			else {
					$tmp = $tmp . $line;
      			}
    		}
			if ($thebook eq "ALL") {
				print "\nAll books removed from your record!";
			}
    		if ($found==0) {
      			print "\n$thebook No such Book on file - please check the title for spelling!";
    		}
    		open(OUTBOOKS, ">$outbooks") or die "Cannot open $outbooks for writing!\n";
    		print OUTBOOKS "$tmp";
			unless ($thebook eq "ALL") {
    			print "\nWould you like to return another book? [y/n] ";
    			$input = <STDIN>;
    			chomp($input);
    			while (!(($input eq "y") || ($input eq "n") || ($input eq "Y") || ($input eq "N"))) {
      				print "\nWould you like to return another book? [y/n] ";
      				chomp($input = <STDIN>);
    			}
    			if (($input eq "y") || ($input eq "Y")) {
      				returnBook;
      				$firstbook = 1;
    			}
  			}
    	}
   }
 }
}
