package AmphetaDesk::ChannelsList;
###############################################################################
# AmphetaDesk                                           (c) 2000-2002 Disobey #
# morbus@disobey.com                      http://www.disobey.com/amphetadesk/ #
###############################################################################
# ABOUT THIS PACKAGE:                                                         #
#   This package controls the listing in the "Add a Channel" portion, from    #
#   parsing through the OPML file (gleaned from syndic8.com) to actually      #
#   turning it into something suitable for HTML display.                      #
#                                                                             #
# LIST OF ROUTINES BELOW:                                                     #
#   get_sorted_channels_list - get arrays of various sorted channel options.  #
#   load_channel_list_letter - loads channels that start with the $letter.    #
###############################################################################
#     "16x or 4x? 5 minutes or 20 minutes? I just don't know, Mr. Bond."      #
###############################################################################

use strict; $|++;
use AmphetaDesk::Settings;
use AmphetaDesk::Utilities;
use XML::Parser;
require Exporter;
use vars qw( @ISA @EXPORT );
@ISA = qw( Exporter );
@EXPORT = qw( get_sorted_channels_list load_channels_by_letter );

# yadda, yadda.
my $letter = '';
my $total_count = 0;
my $letter_count = 0;

# where we store our
# in-memory channel letter.
my %CHANNELS;

###############################################################################
# get_sorted_channels_list - get arrays of various sorted channel options.    #
###############################################################################
# USAGE:                                                                      #
#    # returns our channel list data, sorted by title.                        #
#    my @array = get_sorted_channels_list("title", "data");                   #
#                                                                             #
#    # returns 'l' data, reversed sorted by title.                            #
#    my @array = get_sorted_channels_list("title", "reversed_data");          #
#                                                                             #
# NOTES:                                                                      #
#    This routine goes through our currently stored syndic8 channel list in   #
#    %CHANNELS, and returns an array based on how the data should be sorted   #
#    as well as how the data is returned. Sorting can be done on ANY          #
#    attribute stored in %CHANNELS, and the returned array could be sorted    #
#    normally or reversed.                                                    #
#                                                                             #
# RETURNS:                                                                    #
#    @array; the sorted array of channel ids.                                 #
###############################################################################

sub get_sorted_channels_list {

   my ($sort_by, $return) = @_;

   # prepare our various arrays
   # and return the format requested.
   my @names = sort { uc( $CHANNELS{$a}{$sort_by} ) cmp uc ( $CHANNELS{$b}{$sort_by} ) } keys %CHANNELS;
   my @names_r = sort { uc( $CHANNELS{$b}{$sort_by} ) cmp uc ( $CHANNELS{$a}{$sort_by} ) } keys %CHANNELS;
   my @data; foreach (@names) { push(@data, $CHANNELS{$_}); }
   my @data_r; foreach (@names_r) { push(@data_r, $CHANNELS{$_}); }

   return @data if $return eq "data"; return @data_r if $return eq "reversed_data";

}

###############################################################################
# load_channels_by_letter - loads channels that start with the $letter.       #
###############################################################################
# USAGE:                                                                      #
#    $channel_list = load_channels_by_letter( $letter );                      #
#                                                                             #
# NOTES:                                                                      #
#    This channel uses XML::Parser to load our channel list opml and then     #
#    returns a data structure of all the channels that match said letter.     #
#                                                                             #
# RETURNS:                                                                    #
#    $channel_list; a data structure of matching letters.                     #
###############################################################################

sub load_channels_by_letter {

   ($letter, my $language) = @_;

   # if our letter isn't defined, or 
   # else, is a number, rewrite to 
   # be \d so that our regexp will get 'em.
   $letter = '\d' unless $letter;
   $letter = '\d' if $letter =~ /\d/;

   # start over with
   # our letter carrier
   # and our counts.
   undef %CHANNELS;
   $total_count = 0;
   $letter_count = 0;

   # my logfile is aroused.
   note("Loading our channel list from " .
        get_setting("names_file_services_channels") . ".");

   # get an new instance of the parser,
   # register handlers, then parse.
   my $p = new XML::Parser;
   $p->setHandlers( Start => \&_start );
   $p->parsefile( get_setting("files_services_channels") );

   # creates the
   # data struct.
   sub _start {
      my ($p, $tag_name, %attrs) = @_;

      # if there are no text attributes, return,
      # else, return if the letter doesn't match.
      return unless $attrs{text}; $total_count++;
      return if $attrs{text} !~ /^$letter/i; $letter_count++;
      while ( my ($key,$value) = each(%attrs) ) {

         # change syndic8.com's "text" to "title". this just allows
         # us to match the similar attribute from the myChannels.opml.
         $CHANNELS{$attrs{text}}{title} = $value
            if $key eq "text"; next if $key eq "text";

         # assign other attributes normally. note
         # that we lowercase the attribute name. this
         # is another syndic8 to ampheta change.
         $CHANNELS{$attrs{text}}{lc($key)} = $value;

      }
      return 1;
   }

   # silly blurbage to the log file.
   $letter = "0-9" if $letter eq '\d';
   note("There was a total of $total_count channels, with $letter_count matches for '$letter'.");

   return 1;

}

1;
