#!/usr/bin/perl -w
# rss viewer aka newsticker for the console
#
# written by Thorsten Gunkel <tgunkel@gmx.de>
# inspired by rss2html (Jonathan Eisenzopf)
#
# Syntax: rss_newsticker.pl SECONDS_TO_WAIT RDF_SOURCE [ RDF_SOURCE ... ]
#

# --- 12.04.2003 Thorsten Gunkel <tgunkel@gmx.de> ---
# --- Initial Release ---
#

# INCLUDES
use strict;
use XML::RSS;
use LWP::Simple;
use Term::ReadKey;
use Text::Iconv;

# Declare variables
my $content;
my $file;

# MAIN
# check for command-line argument
my $todo_nr = @ARGV;
#FIXME
if (($todo_nr<2) && ($ARGV[0]>0) && ($ARGV[0]<=600))
  {
    die "SECONDS_TO_WAIT RDF_SOURCE RDF_SOURCE RDF_SOURCE ...?\n";
  }
else
  {
    #loop forever
    while (1>0)
      {
	my $wait_time=$ARGV[0];
	for(my $i1=1; $i1<=@ARGV ; $i1++)
	  {
	    my $arg=$ARGV[$i1];
	    #foreach my $arg (@ARGV)
	    # create new instance of XML::RSS
	    my $rss = new XML::RSS;
	    my $rss_error=0;
	    if ($arg=~ /http:/i)
	      {
		# argument is a URL
		$content = get($arg);
		$rss_error=1 unless $content;
		# parse the RSS content
		if ($rss_error==0)
		  {
		    # FIXME: Fehler abfangen
		    $rss->parse($content);
		  }
	      }
	    else
	      {
		# argument is a file
		$file = $arg;
		$rss_error=1 unless -e $file;
		# parse the RSS file
		if ($rss_error==0)
		  {
		    $rss->parsefile($file);
		  }
	      }
	    # No error
	    if ($rss_error==0)
	      {
		# print the HTML channel
		&get_text($wait_time,$rss);
	      }
	    else
	      {
		print_text($wait_time,"ERROR: Broken RDF File", $arg);
	      }
	  }
      }
  }


# SUBROUTINES
sub replace_newline
  {
    my $line=shift;
    $line=~ s/\015\012|\015|\012//g;
    return($line);
  }

sub print_text
  {
    # Convert from utf8 FIXME?
    my $wait_time=shift;
    my $converter = Text::Iconv->new("utf8", "ISO-8859-1");
    my $text = shift; $text=replace_newline($text); $text = $converter->convert($text);
    my $link = shift; $link=replace_newline($link);
    # Print word by word and add linebreaks if postion requires
    my $xpos=0; my $ypos=0;
    my @words = split(/ /,$text);
    foreach my $word (@words)
      {
	# Get screen size
	(my $wchar, my $hchar, my $wpixels, my $hpixels) = GetTerminalSize();
	$word=$word." ";
	# As long as word does not fit in line print substring or/and add linebreak
	my $wordl=length($word);
	while (($xpos+$wordl)>$wchar)
	  {
	    if ($xpos>0)
	      {
		$xpos=0;
		print "\n";
	      }
	    else
	      {
		print substr($word,0,$wchar)."\n";
		$word=substr($word,$wchar,$wordl);
		$wordl=length($word);
	      }
	    $ypos=$ypos+1;
	  }
	# Next word will fit in line
	$xpos=$xpos+$wordl;
	print $word;
      }
    print "\n"; $ypos=$ypos+1;
    # Get screen size
    (my $wchar, my $hchar, my $wpixels, my $hpixels) = GetTerminalSize();
    $ypos=$ypos+(int((length($link))/$wchar)+1);
    $ypos=$ypos+1;
    print "\n";
    print $link."\n";
    while ($ypos+1<$hchar)
      {
	$ypos=$ypos+1;
	print "\n";
      }
    sleep($wait_time);
  }

sub get_text
  {
    my $wait_time = shift;
    my $rss = shift;
    # print the channel items
    &print_text($wait_time,$rss->{'channel'}->{'title'}, $rss->{'channel'}->{'link'});
    foreach my $item (@{$rss->{'items'}})
      {
	next unless defined($item->{'title'}) && defined($item->{'link'});
	&print_text($wait_time,$item->{'title'},$item->{'link'});
      }
  }
