package App::POS::Hardware::PrinterLogo;
use Mouse;

use App::POS::Hardware::PrinterLogo::BitArray;

has image => (
  is => 'ro',
  required => 1,
);

has use_cache => (
  is => 'rw',
  default => 1,
);

sub image_data {
  my $self = shift;
  my $dots = shift || 24; #Can be 8 OR 24

  my $path = $self->image();
  my $content = "";

  return unless -e $path;

  my $fsize = -s $path;

  my( $fname ) = $path =~ /^.*\/(.*?)$/;
  my $cache_f = "/tmp/printerlogo_img_".$fname."_".$fsize.".txt";

  if (-e $cache_f && $self->use_cache()) {
    local $/ = undef;
    open(F, "< $cache_f");
    my $cnt = <F>;
    close(F);
    return $cnt;
  }

  my $bit_array = "";

  eval {
    $bit_array = App::POS::Hardware::PrinterLogo::BitArray->new(path => $path);
  };

  return if $@;

  $content = $self->kbyte(27) . "3" . $self->kbyte(24);
  
  my $nlow = $bit_array->width() % 256;
  my $nhigh  = ($bit_array->width() >> 8) % 256;
  
  my $offset = 0;
  my $line_size = 0;
  
  while($offset < $bit_array->height()) {
    $content .= $self->kbyte(27) . "*";

    if ($dots == 24) {
      $content .= $self->kbyte(33);
    }
    else {
      $content .= $self->kbyte(8);
    }

    $content .= $self->kbyte($nlow) . $self->kbyte($nhigh);

    for (my $x = 0; $x < $bit_array->width(); ++$x) {
      for (my $k = 0; $k < $dots/8; ++$k) {
        my $byte = 0;

        for (my $b = 0; $b < 8; ++$b) {
          my $y = ((($offset / 8) + $k) * 8) + $b;
          my $i = ($y * $bit_array->width()) + $x;

          my $bit = 0;

          if ( defined $bit_array->dots()->[$i] ) {
            $bit = $bit_array->dots()->[$i] ? 1 : 0;
          } else {
            $bit = 0;
          }

          $byte |= $bit << (7 - $b);
        }

        $content .= chr($byte);
        $line_size++;
      }
    }

    $offset += $dots;
    $content .= $self->kbyte(10);
    $line_size = 0;
  }

  #$content .= chr(0x1B) . chr(0x32);

  if ($self->use_cache()) {
    open(F, "> $cache_f");
    print F $content;
    close(F);
  }

  return $content;
}

sub kbyte {
  my $self = shift;
  my $val = shift;

  return pack('C', $val);
}

__PACKAGE__->meta->make_immutable();

