#------------------------------------------------------------
# Copyright (C) 2006 RoyaltyShare, Inc.   All Rights Reserved
#------------------------------------------------------------

package Common::Parser::Iterator;

#
# Common::Parser::Iterator
#
# This class is used by class parser to read datafiles.  It
# is intended to be overloaded for each format to be read.
# For example Excel 97 (xls), CSV text file, or TSV text file.
# The iterator it used to read through the file line (record)
# by line.
#
# Usage:
#
#  	if( $formatClass->CanParse( filename => $filename ) ) {
#       $iterator = $formatClass->new( filename => $filename );
#   }
#
# Private Methods:
#
#  string _itemClass()   - Define class of return object for parsed record.
#  string _clean( $val ) - Read a value in and "clean" it.  Currently this method
#                          does a UTF-8 conversion.
#
# Virtual Methods:
#
#  bool CanParse( filename => $file )
#  bool open( $file )
#  void close()
#  void rewind()
#  bool hasNext()
#  Common::Parser::Item next()
#

use strict;

use lib '/app/tools/common/lib';
use Common::Assert;

sub _itemClass { 'Common::Parser::Item::Row' }
sub fileType   { 'table' }

# new
#
# my $parser = new Common::Parser( filename => $file )
#
# Constructor.  Filename is a required field.
#
sub new {
    my $class = shift;

    my $self = {};
    bless $self, $class;

    return $self->_init(@_);
}

# DESTROY
#
# Destructor.  Close any open files.  Most subclasses won't do anything because
#              the close is implicit.
#
sub DESTROY {
    my $self = shift;
    $self->close();
}

# _init
#
# Store the filename during construction.
sub _init {
    my ( $self, %args ) = @_;

    eval "require " . $self->_itemClass();
    die $@ if ($@);

    $self->open( $args{filename} ) if ( $args{filename} );

    return $self;
}

# _clean
#
# Clean up a value read from a file, UTF8 encode it.
sub _clean {
    my $self = shift;
    my $val = shift || return;

    return Common::UTF8::Encode($val);
}

###
#   Accessors
###
sub filename {
    return shift->{_filename};
}

###
#   Virtual Methods
###
sub CanParse { assert( 0, "Must be overloaded" ); }

sub open { assert( 0, "Must be overloaded" ); }
sub close    { }
sub rewind   { assert( 0, "Must be overloaded" ); }
sub hasNext  { assert( 0, "Must be overloaded" ); }
sub next     { assert( 0, "Must be overloaded" ); }
sub rowCount { assert( 0, "Must be overloaded" ); }

###
1;    # Play nicely.
###
