#!/usr/bin/perl -w
#
# Program to interface with a Kodak Digital camera.
#
#  http://www.berkhirt.com/HomerProductions/
#  bhirt@berkhirt.com
#
# Copyright (c) 1998 by Brian Hirt, all rights reserved.
#
# 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#
# 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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
#


use strict;

# Include supported cameras
use DC50;
use DC120;
use DC210;

use DCUtils;
use DCHandle;

if (scalar(@ARGV) < 4)
{
  print STDERR "usage:\n  $0 camera port speed command [ command arguments ]\n";
  exit;
}

my $camera  = shift @ARGV;
my $port    = shift @ARGV;
my $speed   = shift @ARGV; 
my $command = shift @ARGV;

$camera =~ tr/[a-z]/[A-Z]/;

my $cameraClass = {};
$cameraClass->{'DC40'} = 'DC50';
$cameraClass->{'DC50'} = 'DC50';
$cameraClass->{'DC120'} = 'DC120';
$cameraClass->{'DC200'} = 'DC210';
$cameraClass->{'DC210'} = 'DC210';

if ($camera eq "DC40")
{
  print STDERR "DC40 has not been tested, trying DC50 protocol...\n";
}

if ($camera eq "DC50")
{
  print STDERR "If you know information about the DC50 file format, please mail\nbhirt\@berkhirt.com and I will work on supporting it.\n";
}

if (($camera eq "DC220") || ($camera eq 'DC260'))
{
  print STDERR "Kodak refuses to release the DC220/DC260 protocol, please send mail to \ndrg\@kodak.com asking them the release the specs.  If you have information \nabout the protocol, please let me know. (bhirt\@berkhirt.com)\n";
  exit;
}

if (!defined($cameraClass->{$camera}))
{
  print STDERR "$camera is not supported.  Supported cameras are: DC50, DC120, DC200, DC210\n";
}


if ( ! -e $port )
{
  print STDERR "$port does not exist.\n";
  exit;
}

if (( ! -r $port ) || ( ! -w $port ))
{
  print STDERR "You do not have permission to read/write $port\n";
  exit;
}


my $dc = $cameraClass->{$camera}->new($port,$speed);

if (!defined($dc))
{
  print STDERR "could not initialize camera $port, $speed\n";
  print STDERR "try turning camera off and then back on\n";
  print STDERR "and check port settings.\n";
  exit;
}

if ($command eq 'status')
{
  cameraStatus($dc);
}
elsif ($command eq 'delete')
{
  if ((scalar(@ARGV) ==1 ) && ($ARGV[0] eq 'all'))
  {
    $dc->deleteAllPictures;
  }
  else
  {
    foreach (@ARGV)
    {
      deletePicture($dc,$_);
    }
  }
}
elsif ($command eq 'set')
{
  my $setting = shift @ARGV;
  my $value = shift @ARGV;

  if ($setting eq 'cameraid')
  {
    $dc->setCameraIdentification($value);
  }
  else
  {
    print STDERR "unknown set command\n";
  }
}
elsif ($command eq 'snap')
{
  takePicture($dc);
}
elsif ($command eq 'list')
{
  listPictures($dc);
}
elsif ($command eq 'dumpthumb')
{
  my @pictures;

  if ((scalar(@ARGV) == 1) && ($ARGV[0] eq 'all'))
  {
    @pictures = (1 .. $dc->status->numberOfPictures);
  }
  else
  {
    @pictures = @ARGV;
  }

  foreach (@pictures)
  {
    dumpThumbnail($dc,$_);
  }
}
elsif ($command eq 'dump')
{
  my @pictures;

  if ((scalar(@ARGV) ==1 ) && ($ARGV[0] eq 'all'))
  {
    @pictures = (1 .. $dc->status->numberOfPictures);
  }
  else
  {
    @pictures = @ARGV;
  }

  foreach (@pictures)
  {
    dumpPicture($dc,$_);
  }
}
else
{
  print STDERR "$0: unkown command\n";
  print STDERR "implemented commands:\n";
  print STDERR "  dumpthumb - downloads thumbnails from the camera\n";
  print STDERR "  dump      - downloads picture(s) from the camera\n";
  print STDERR "  delete    - deletes picture(s) from the camera\n";
  print STDERR "  status    - displays the cameras status\n\n";
  print STDERR "  list      - lists name and sizes of pictures in the camera\n\n";
  print STDERR "  snap      - takes a picture\n\n";
  print STDERR "  set       - sets information about the camera\n\n";
}

exit;

sub takePicture
{
  my $dc = shift;
 
  $dc->takePicture;
}

sub listPictures
{
# lists the pictures in the camera
  my $dc = shift;

  printf STDERR "%3s %-12s %7s %10s %11s %8s\n","#","File Name","Size","Resolution","Compression","Format";
  printf STDERR "--- ------------ ------- ---------- ----------- --------\n","#","File Name","Size","Resolution","Compression","Format";
  foreach (1 .. $dc->status->numberOfPictures)
  {
    my $info = $dc->pictureInfo($_);

    if (defined($info))
    {
      printf STDERR "%3d %-12s %7d %10s %11s %8s\n",
	$info->pictureNumber,
	$info->fileName,
	$info->fileSize,
	$info->resolution,
	$info->compressionMode,
	$info->pictureFormat;
    }
    else
    {
      print STDERR "unable to get picture information\n";
    }
  }
}

sub deletePicture
{
# deletes the requested picture.
  my $dc = shift;
  my $pictureNumber = shift;

  my $info = $dc->pictureInfo($pictureNumber);

  if (defined($info))
  {
    $dc->deletePicture($pictureNumber);
  }
  else
  {
    print STDERR "bad picture number supplied or comminucations failure\n";
  }
}

sub dumpThumbnail
{
# downloads the requested thumbnail.
  my $dc = shift;
  my $pictureNumber = shift;

  my $info = $dc->pictureInfo($pictureNumber);

  if (defined($info))
  {
    my $fileName = $info->fileName;
    $fileName =~ s/\.JPG$/.BMP/i;

    open(BMP,">T$fileName");
#    print BMP $dc->thumbnail($pictureNumber,$DC210::HIGH_RES_THUMBNAIL);
    close(BMP);
  }
  else
  {
    print STDERR "bad picture number supplied or comminucations failure\n";
  }
}

sub pictureDownloadStatus
{
# This method gets called during the download and prints an update.
  my $pictureInfo = shift;
  my $bytesRead = shift;

  printf STDERR "\r%-2d   %12s   %-6d of %-6d", 
		$pictureInfo->pictureNumber,
		$pictureInfo->fileName,
		$bytesRead,
		$pictureInfo->fileSize;
	
}

sub dumpPicture
{
# downloads the requested picture.
  my $dc = shift;
  my $pictureNumber = shift;

  my $info = $dc->pictureInfo($pictureNumber);

  if (defined($info))
  {
    $dc->{'downloadNotify'} = \&pictureDownloadStatus;

    open(JPG,">" . $info->fileName);
    print JPG $dc->picture($pictureNumber);
    close(JPG);

    $dc->{'downloadNotify'} = undef;

    print STDERR "\n";
  }
  else
  {
    print STDERR "bad picture number supplied or comminucations failure\n";
  }
}

sub cameraStatus
{
  my $dc = shift;

  my $status = $dc->status;
  my $attribute;

  printf STDERR "%-30s %-49s\n","Attribute","Value";
  printf STDERR "%-30s %-49s\n",'-' x 30, '-' x 49;
  foreach $attribute ($status->attributes)
  {
    printf STDERR "%-30s %-49s\n",$attribute,$status->$attribute();
  }
}

exit;

