# Arch Perl library, Copyright (C) 2004 Mikhael Goikhman, Enno Cramer
#
# 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

use 5.006;
use strict;
use warnings;

package ArchWay::Widget::Revisions;

use Glib qw(TRUE FALSE);
use Gtk2;

use base qw(Gtk2::TreeView);

use Arch::RevisionBunches;

use constant MODEL_COL_TYPES => qw(
	Glib::Boolean  
	Glib::String
	Glib::String
	Glib::String
	Glib::String
	Glib::String
	Glib::Boolean
	Glib::Uint
	Glib::Uint
);

use constant MODEL_COL_IS_REV   => 0;
use constant MODEL_COL_NAME     => 1;
use constant MODEL_COL_SUMMARY  => 2;
use constant MODEL_COL_DATE     => 3;
use constant MODEL_COL_CREATOR  => 4;
use constant MODEL_COL_REVISION => 5;
use constant MODEL_COL_STRIKE   => 6;
use constant MODEL_COL_WEIGHT   => 7;
use constant MODEL_COL_STYLE    => 8;

my @VIEW_COLUMNS = (
	{
		title      => 'Name',
		column     => MODEL_COL_NAME,
		attributes => {
			strikethrough => MODEL_COL_STRIKE,
			weight        => MODEL_COL_WEIGHT,
			style         => MODEL_COL_STYLE,
		},
	},
	{
		title      => 'Summary',
		column     => MODEL_COL_SUMMARY,
		attributes => {
			weight => MODEL_COL_WEIGHT,
			style  => MODEL_COL_STYLE,
		},
	},
	{
		title      => 'Date',
		column     => MODEL_COL_DATE,
		attributes => {
			weight => MODEL_COL_WEIGHT,
			style  => MODEL_COL_STYLE,
		},

	},
	{
		title      => 'Creator',
		column     => MODEL_COL_CREATOR,
		attributes => {
			weight => MODEL_COL_WEIGHT,
			style  => MODEL_COL_STYLE,
		},
	},
);

sub new ($) {
	my $class = shift;

	my $self = bless Gtk2::TreeView->new, $class;
	$self->set_model(Gtk2::TreeStore->new(MODEL_COL_TYPES));

	$self->_init;
	$self->{revision_bunches} = Arch::RevisionBunches->new(
		bunch_size => 25,
		cb_remove_all_bunches => sub { $self->cb_remove_all_bunches; },
		cb_add_new_bunch => sub { $self->cb_add_new_bunch(@_); },
	);
	# can't find how to do this from the model directly...
	$self->{num_bunches} = 0;

	return $self;
}

sub _init ($) {
	my $self = shift;

	$self->set_rules_hint(TRUE);
	$self->set_search_column(MODEL_COL_NAME);

	foreach my $col (@VIEW_COLUMNS) {
		my $column = Gtk2::TreeViewColumn->new_with_attributes(
			$col->{title}, Gtk2::CellRendererText->new,
			text => $col->{column},
			%{$col->{attributes}},
		);
		$column->set_resizable(TRUE);
		$column->set_sort_column_id($col->{column});

		$self->append_column($column);
	}
}

sub get ($$;@) {
	my $self = shift;
	my $iter = shift;

	return $self->get_model->get($iter, @_);
}

sub get_selected ($;@) {
	my $self = shift;

	my $iter = $self->get_selection->get_selected;

	return $iter ? $self->get($iter, @_) : undef;
}

sub get_selected_version ($) {
	my $self = shift;

	my $iter = $self->get_selection->get_selected;
	if ($iter) {
		my ($idx) = $self->get_model->get_path($iter)->get_indices;

		# TODO: fix this
		return $self->{revision_bunches}->{bunches}->[$idx]->{version};
	} else {
		return undef;
	}
}


sub get_selected_revision ($) {
	my $self = shift;

	return $self->get_selected(MODEL_COL_REVISION);
}

sub get_selected_is_revision ($) {
	my $self = shift;

	return $self->get_selected(MODEL_COL_IS_REV);
}

sub clear ($) {
	my $self = shift;

	# this invokes cb_remove_all_bunches callback
	$self->{revision_bunches}->clear;
}

sub cb_remove_all_bunches ($) {
	my $self = shift;

	my $model = $self->get_model;
	$model->clear;
	$self->{num_bunches} = 0;
}

sub add_revision_descs ($$;%) {
	my $self = shift;
	my $revision_descs = shift;
	my %args = @_;

	# this invokes cb_add_new_bunch callbacks
	$self->{revision_bunches}->add_revision_descs($revision_descs, %args)->rebunch;
}

sub cb_add_new_bunch ($$;$) {
	my $self = shift;
	my $bunch = shift;
	my $start_index = shift || 0;

	my $model = $self->get_model;

	my $parent = $start_index == 0?
		$model->append(undef):
		$model->iter_nth_child(undef, --$self->{num_bunches});
	$self->{num_bunches}++;

	$model->set($parent,
		MODEL_COL_IS_REV,   0,
		MODEL_COL_NAME,     $bunch->{name},
		MODEL_COL_SUMMARY,  $bunch->{summary},
		MODEL_COL_DATE,     $bunch->{date},
		MODEL_COL_CREATOR,  $bunch->{creator},
		MODEL_COL_REVISION, undef,
		MODEL_COL_STRIKE,   $bunch->{is_missing} ? TRUE : FALSE,
		MODEL_COL_WEIGHT,   700,       # bold
		MODEL_COL_STYLE,    0,
	);

	my @revision_descs = @{$bunch->{revision_descs}};
	splice(@revision_descs, 0, $start_index);
	foreach my $rd (@revision_descs) {
		my $iter = $model->append($parent);
		$model->set($iter,
			MODEL_COL_IS_REV,   1,
			MODEL_COL_NAME,     $rd->{name},
			MODEL_COL_SUMMARY,  $rd->{summary},
			MODEL_COL_DATE,     $rd->{date},
			MODEL_COL_CREATOR,  "$rd->{creator} <$rd->{email}>",
			MODEL_COL_REVISION, $rd->{version} ? $rd->{version} . '--' . $rd->{name} : $rd->{name},
			MODEL_COL_STRIKE,   $rd->{is_missing} ? TRUE : FALSE,
			MODEL_COL_WEIGHT,   0,
			MODEL_COL_STYLE,    $rd->{is_missing} ? 2 : 0,
		);
	}

	$self->get_selection->select_iter($parent)
		unless $self->get_selected_revision;
}

1;

__END__
