###########################################################################
#
# Code by Xin Gao based on the Ogg::Vorbis::Header::PurePerl module by
#   Andrew Molloy (GNU General Public Licensed)
#
# A component of the Greenstone digital library software
# from the New Zealand Digital Library Project at the 
# University of Waikato, New Zealand.
#
# Copyright (C) 2005 New Zealand Digital Library Project
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
###########################################################################

package rm::Header::PurePerl;

use 5.005;
use strict;
use warnings;

use Fcntl qw/SEEK_END/;

our $VERSION = '0.07';

sub new 
{
    my $class = shift;
    my $file = shift;

    return load($class, $file);
}

sub load 
{
    my $class    = shift;
    my $file     = shift;
    my $from_new = shift;
    my %data;
    my $self;

    # there must be a better way...
    if ($class eq 'rm::Header::PurePerl')
    {
	$self = bless \%data, $class;
    }
    else
    {
	$self = $class;
    }

    if ($self->{'FILE_LOADED'})
    {
	return $self;
    }

    $self->{'FILE_LOADED'} = 1;

    # check that the file exists and is readable
    unless ( -e $file && -r _ )
    {
	warn "File does not exist or cannot be read.";
	# file does not exist, can't do anything
	return undef;
    }
    # open up the file
    open FILE, $file;
    # make sure dos-type systems can handle it...
    binmode FILE;

    $data{'filename'} = $file;
    $data{'fileHandle'} = \*FILE;

    _loadInfo(\%data);

    close FILE;

    return $self;
}

sub info 
{
    my $self = shift;
    my $key = shift;

    # if the user did not supply a key, return the entire hash
    unless ($key)
    {
	return $self->{'INFO'};
    }

    # otherwise, return the value for the given key
    return $self->{'INFO'}{lc $key};
}

sub _loadInfo
{
    my $data = shift;
    my $start = 0;
    my $fh = $data->{'fileHandle'};
    my $buffer;
    my $byteCount = $start;
    my %info;
    
    # check that the first four bytes are '.RMF'
    read($fh, $buffer, 4);
    if ($buffer ne '.RMF')
    {
	warn "No RMF header?";
	return undef;
    }

$buffer='';
my $char;

#find the header
my $bytes = "DATA";
my @byteList = split //, $bytes;
my $numBytes = @byteList;
my $i;

LINE:   while (1){
  INNER:  for ($i = 0; $i < $numBytes; $i ++)
    {
  unless ( read($fh, $char, 1) ) {last LINE ;}
	# Find out all of char
	$buffer= $buffer.$char;  

if (ord($char) !=  ord($byteList[$i]) ) 
{last  INNER ;}
    }
if ($i == $numBytes) {last LINE ;} #jump out the while loop
        }

#find the tail
 $bytes = "INDX";
 @byteList = split //, $bytes;
 $numBytes = @byteList;

my $isrecord=0;
LINE:  while (read($fh, $char, 1)){
   if ($isrecord) {
	# Find out all of char
	$buffer= $buffer.$char;  
   }else
        {
         INNER:  for ($i = 0; $i < $numBytes; $i ++)
                     {
                      if (ord($char) !=  ord($byteList[$i]) ) {last  INNER ;}
                      unless ( read($fh, $char, 1) ) {last LINE ;}
                     }
if ($i == $numBytes) {$isrecord = 1;} #start record
        }
       }

my @cliptype = (

#add clip type here
"Comments",
"Keywords",
"Category",
"MimeType",# title
"Lyrics",
"Artist",
"CD Track #",
"Album",
"Extension",
"Genre",
"Statistics",
"PROP",
"MDPR",
"Target Audiences",
"Audio Format",
"Creation Date",
"Modification Date",
"Generated By",
"Abstract",
"Content Rating",
"File ID",
"CONT",
"Audio Stream",
"Video Stream",
"Title"
);

for my $j ( 1 .. scalar(@cliptype) ) {
$info{$cliptype[$j - 1]} = _loadInfor($buffer,$cliptype[$j - 1]);
}

    $data->{'INFO'} = \%info;
}

#search for the element name and value
sub _loadInfor
{my $data = shift;
my $item = shift;

my @byteList = split //, $data;
my $startbyte = 0;


my $isrecord;
my $data2 = "";
my $char;
my $item2 = "";
if ( $item eq "Title") {$item2 = $item; $item = "MimeType";}


OUT: while(index($data, $item, $startbyte) != -1){
$startbyte = index($data, $item, $startbyte);
$isrecord=0;

$startbyte += length($item);

if(ord($byteList[$startbyte]) == 0 or ord($byteList[$startbyte]) == 0x14){
  if ( $item eq "Album" or $item eq "Artist" or $item2 eq "Title"){
     if ( index($data,"Name",$startbyte) != -1) {
     $startbyte = index($data,"Name",$startbyte);
     $startbyte += length("Name");
     }else {next OUT;}
}

  if ($data2 ne "") {$data2 = $data2."; ";}

LINE:   while (1){
        $char = $byteList[++$startbyte];

	if (ord($char) >= 32 and ord($char) <= 126)
	{
        $isrecord=1; #record the string started
	$data2 = $data2.$char;  
	}else{
             if ( $isrecord == 1 ) {last LINE ;}# stop at the end of string
             }
        }# end LINE: while

 }# end if 
}# end while

return $data2;
}

1;
