package Tape;

# Dobrica Pavlinusic, <dpavlin@rot13.org> 08/03/07 11:11:56 CEST

use strict;
use warnings;

use base qw/Class::Accessor/;
__PACKAGE__->mk_accessors(qw(tape tape_pos tape_rate));

use File::Slurp;
use Carp qw/confess/;

=head1 NAME

Tape - implement tape reader/recorder

=cut

=head2 read_tape

  $self->read_tape;

=cut

my $last_warn = '';

sub _warn {
	my $msg = shift;
	if ( $msg ne $last_warn ) {
		warn "$msg\n";
		$last_warn = $msg;
	}
}

my @tape_bits;

sub read_tape {
	my $self = shift;
	if ( ! $self->tape ) {
		_warn "please load tape!";
		return 0;
	}
	my $pos = $self->tape_pos;
	my $tape = $self->tape;
	if ( $pos > length( $tape ) ) {
		_warn "end of tape [$pos]";
		return -1;
	}

	if ( ! @tape_bits ) {
		my $byte = ord( substr($self->tape,$pos,1) );
		warn sprintf("tape pos %d = %02x\n", $pos, $byte);

		$pos++;
		$self->tape_pos( $pos );

		@tape_bits = split(//, unpack("B8",$byte) );
	}
	my $bit = shift @tape_bits ? 0xff : 0x00;
	warn "\t$bit\n";
	return $bit;
}

=head2 load_tape

  $self->load_tape( '/path/to/file' );

=cut

sub load_tape {
	my $self = shift;
	my $path = shift || return;

	my $tape = read_file( $path ) || confess "can't load $path: $!";

	$self->tape_pos( 0 );
	$self->tape( $tape );
	$self->tape_rate( 512 );
	warn "loaded tape $path ", -s $path, " bytes rate ", $self->tape_rate, "\n";
	return 1;
}


1;
