package Ddtc::Package;


use strict;
use Exporter;
use IO::File;
use MIME::Words;
use Ddtc::Common;

use vars  qw(@ISA);

@ISA	= qw(Exporter);

# Ddtc::Package data structure:
# +-> name
# +-> language
# +-> message id
# +-> translator
# +-> reviewers
#     +-> reviewer 1
#     +-> reviewer 2
#     +-> ...
# +-> bugs
#     +-> bug number 1
#     +-> bug number 2
#     +-> ...
# +-> description
#     +-> short description
#     +-> line 1
#     +-> line 2
#     +-> ...
# +-> translation
#     +-> short translation
#     +-> line 1
#     +-> line 2
#     +-> ...
# +-> old description
#     +-> short description
#     +-> line 1
#     +-> line 2
#     +-> ...
# +-> old translation
#     +-> short translation
#     +-> line 1
#     +-> line 2
#     +-> ...


# new
#
# create new empty data structure
#
# output:
#   Ddtc object
sub new ($) {
	shift;						# class

	my $self = bless {};

	return $self;
}


# get_file
#
# create data structure from a file
#
# input:
#   filename
# output:
#   Ddtc object
sub get_file ($$) {
	my $self = shift;				# Ddtc object
	my $file = shift;				# filename

	my @lines;

	debug 3;
	debug 4, "filename:     $file\n";

	return undef	unless -e $file;		# return error if file doesn't exist

	my $handle;					# file handle
	$handle = new IO::File($file, '<')	or suicide __("Cannot read `%s': %s\n"), $file, $!;
	@lines = $handle -> getlines;
	$handle -> close;
	chomp @lines;

	while (@lines) {
		$_ = shift @lines;
		debug 5, $_."\n";
		
		if	(/^# package:\s*(.*)/i) {
			$self->name ($1);

			debug 4, "package:      $1\n";
			next;
		} elsif (/^# ddts id:\s*(.*)/i) {
			$self->message_id ($1);

			debug 4, "message-id:   $1\n";
			next;
		} elsif (/^# translator:\s*(.*)/i) {
			my $n = MIME::Words::decode_mimewords($1);
			$self->translator ($n);

			debug 4, "translator:   $n\n";
			next;
		} elsif (/^# reviewer:\s*(.*)/i) {
			my $n = MIME::Words::decode_mimewords($1);
			$self->add_reviewer ($n);

			debug 4, "reviewer:     $n\n";
			next;
		} elsif (/^# bug number:\s*(\d+)/i ||
			 /^# bug nb:\s*(\d+)/i      ) {
			$self->add_bug ($1);

			debug 4, "bug number:   $1\n";
			next;
		} elsif (/^(# -)?Description: (.*)/) {
			my   @void;
			push @void, $_;
			while (@lines) {
				$_ = shift (@lines);
				last unless /^#? ./;
				push @void, $_;
			}
			unshift @lines, $_;
			$self->description (@void);

			debug 5, "description\n".
				 $self->description;
			next;
		} elsif (/^(\S*?)Description-(..(_..)?): (.*)/) {
			$self->language ($2);

			my   @void;
			push @void, $_;
			while (@lines) {
				$_ = shift (@lines);
				push @void, $_;
			}
			$self->translation (@void);

			debug 5, "translation\n".
				 "language:     ".$self->language."\n".
				 $self->translation;
			next;
		}

		suicide __("%s: unknown line:\n%s\nThis is a BUG, please report it to the maintainer.\n"), $file, $_;
	}

	unless (exists $self->{'description'}) {
		suicide __("%s: malformed description file:\nno description found!\n"), $file;
	}
	unless (exists $self->{'language'}    &&
		exists $self->{'translation'}   ) {
		suicide __("%s: malformed description file:\nno translation and/or no language found!\n"), $file;
	}

	return $self;
}


# name
#
# get / set package name
#
# input:
#   Ddtc object
#   package name	[ set ]
# output
#   package name
sub name {
	my $self = shift;

	$self->{'name'} = shift	if @_;				# set if value provided

	return undef unless defined $self->{'name'};
	$self->{'name'};
}


# message_id
#
# get / set message id
#
# input:
#   Ddtc object
#   message id		[ set ]
# output
#   message id
sub message_id {
	my $self = shift;

	$self->{'message id'} = shift	if @_;			# set if value provided

	return undef unless defined $self->{'message id'};
	$self->{'message id'};
}


# language
#
# get / set language
#
# input:
#   Ddtc object
#   language		[ set ]
# output
#   language
sub language {
	my $self = shift;

	$self->{'language'} = shift	if @_;			# set if value provided

	return undef unless defined $self->{'language'};
	$self->{'language'};
}


# translator
#
# get / set translator address
#
# input:
#   Ddtc object
#   transaltor address	[ set ]
# output
#   transaltor address
sub translator {
	my $self = shift;

	$self->{'translator'} = shift	if @_;			# set if value provided

	return undef unless defined $self->{'translator'};
	$self->{'translator'};
}


# reviewer
#
# get reviewer address
#
# input:
#   Ddtc object
#   reviewer index
# output
#   reviewer address
sub reviewer {
	my $self = shift;

	return undef unless defined $self->{'reviewers'};
	@{ $self->{'reviewers'} }[shift];
}


# reviewers
#
# get / set reviewer list
#
# input:
#   Ddtc object
#   reviewer list	[ set ]
# output
#   reviewer list
sub reviewers {
	my $self = shift;
	my @revs = @_;

	$self->{'reviewers'} = \@revs	if @_;			# set if value provided

	return () unless defined $self->{'reviewers'};
	@{ $self->{'reviewers'} };
}


# add_reviewer
#
# add a reviewer address
#
# input:
#   Ddtc object
#   reviewer address
sub add_reviewer {
	my $self = shift;

	push @{ $self->{'reviewers'} }, shift;
}


# bug
#
# get bug
#
# input:
#   Ddtc object
#   bug index
# output
#   bug number
sub bug {
	my $self = shift;

	return undef unless defined $self->{'bugs'};
	@{ $self->{'bugs'} }[shift];
}


# bugs
#
# get / set bug list
#
# input:
#   Ddtc object
#   bug list		[ set ]
# output
#   bug list
sub bugs {
	my $self = shift;
	my @bugs = @_;

	$self->{'bugs'} = \@bugs	if @_;			# set if value provided

	return () unless defined $self->{'bugs'};
	@{ $self->{'bugs'} };
}


# add_bug
#
# add a bug number
#
# input:
#   Ddtc object
#   bug number		[ set ]
sub add_bug {
	my $self = shift;

	push @{ $self->{'bugs'} }, (shift);
}


# description
#
# get / set description
#
# input:
#   Ddtc object
#   description		[ set ]
# output
#   description
sub description {
	my $self = shift;
	my @desc = @_;

	$self->{'description'} = \@desc	if @_;			# set if value provided

	return undef unless defined $self->{'description'};
	wantarray ?		 @{ $self->{'description'} }:
		      join("\n", @{ $self->{'description'} })."\n";
}


# old_description
#
# get / set old description
#
# input:
#   Ddtc object
#   old description		[ set ]
# output
#   old description
sub old_description {
	my $self = shift;
	my @desc = @_;

	$self->{'old description'} = \@desc	if @_;		# set if value provided

	return undef unless defined $self->{'old description'};
	wantarray ?		 @{ $self->{'old description'} }:
		      join("\n", @{ $self->{'old description'} })."\n";
}


# translation
#
# get / set translation
#
# input:
#   Ddtc object
#   translation		[ set ]
# output
#   translation
sub translation {
	my $self = shift;
	my @tran = @_;

	$self->{'translation'} = \@tran	if @_;			# set if value provided

	return undef unless defined $self->{'translation'};
	wantarray ?		 @{ $self->{'translation'} }:
		      join("\n", @{ $self->{'translation'} })."\n";
}


# old_translation
#
# get / set old translation
#
# input:
#   Ddtc object
#   old translation		[ set ]
# output
#   old translation
sub old_translation {
	my $self = shift;
	my @tran = @_;

	$self->{'old translation'} = \@tran	if @_;		# set if value provided

	return undef unless defined $self->{'old translation'};
	wantarray ?		 @{ $self->{'old translation'} }:
		      join("\n", @{ $self->{'old translation'} })."\n";
}


# header
#
# make pseudo-header
#
# input:
#   Ddtc object
# output
#   pseudo-header
sub header {
	my $self = shift;

	my @h;
	
	push @h, "# package:    ".$self->name;
	push @h, "# ddts id:    ".$self->message_id;

	push @h, "# translator: ".$self->translator	if $self->translator;

    if ($self->bugs) {
      for (my $i = 0; $i < ($self->bugs || 0); $i++) {
	push @h, "# bug number: ".$self->bug     ($i)." ".chr(97+$i);
	push @h, "# reviewer:   ".$self->reviewer($i);
      }
    }

	wantarray ? @h			:
		    join("\n", @h)."\n" ;
}

1;
