# 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::PartnerVersions;

use Glib qw(TRUE FALSE);
use Gtk2;

use base qw(Gtk2::TreeView);

use ArchWay::Util::TreeVersions;

use constant FIELDS => qw(archive version type kinship role label);
use constant LABELS => qw(Archive Version Type Kinship Role Label);

sub new ($$$) {
	my $class = shift;
	my $tree = shift || die "No tree given";
	my $window = shift || die "No window given";

	my $model = Gtk2::ListStore->new(('Glib::String') x scalar(LABELS));
	my $self = bless Gtk2::TreeView->new_with_model($model), $class;

	$self->{tree} = $tree;
	$self->{window} = $window;
	$self->{version_store} = ArchWay::Util::TreeVersions->new($tree);
	$self->_init;

	return $self;
}

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

	$self->set_border_width(3);

	for (my $col = 0; $col < scalar(LABELS); ++$col) {
		my $title = (LABELS)[$col];
		my $column = Gtk2::TreeViewColumn->new_with_attributes(
			(LABELS)[$col], Gtk2::CellRendererText->new(),
			text => $col,      
		);
		$column->set_resizable(TRUE);
		$column->set_sort_column_id($col);

		$self->append_column($column);
		$self->{(FIELDS)[$col]} = $col;
	}

	my $model = $self->get_model;
	my $version_entries = $self->{version_store}->all;
	my @versions = sort keys %$version_entries;
	$self->{versions} = { map { $_ => 1 } @versions };

	foreach my $version (@versions) {
		my $entry = $version_entries->{$version};
		$version =~ s!^(.*)/!! || die "Invalid version $version";
		my $archive = $1;

		my $values = {
			archive => $archive,
			version => $version,
			type    => $entry->{type},
			kinship => $entry->{kinship},
			role    => $entry->{role},
			label   => $entry->{label} || "(none)",
		};
		my $iterator = $model->append;
		for my $field (FIELDS) {
			$model->set($iterator, $self->{$field}, $values->{$field});
		}
	}
}

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

	my $model = $self->get_model;
	my @versions = map {
		join('/', $model->get($model->get_iter($_), $self->{archive}, $self->{version}))
	} $self->get_selection->get_selected_rows;

	return @versions;
}

sub select_all ($) {
	my $self = shift;
	my $selection = $self->get_selection;
	if ($selection->count_selected_rows == keys %{$self->{versions}}) {
		$selection->unselect_all;
	} else {
		$selection->select_all;
	}
}

sub hide_selected ($) {
	my $self = shift;
	my @selected_rows = $self->get_selection->get_selected_rows;
	my $window = $self->{window};

	unless (@selected_rows >= 1) {
		$window->set_status("No partner version(s) selected");
		return;
	}
	my $s = @selected_rows > 1? "s": "";
	return unless $window->confirm(
		"The selected partner version$s will be hidden by default.\n"
		. "Please confirm.", "Hide partner version$s",
	);
	my $model = $self->get_model;
	foreach my $row (@selected_rows) {
		$model->set($model->get_iter($row), $self->{type}, 'hidden')
	}
	$self->{is_changed} = 1;
}

sub create_choice ($$$) {
	my $self = shift;
	my $name = shift;
	my $current_value = shift;
	my $menu = Gtk2::Menu->new;
	my $method = "${name}_choices";
	my @choice_pairs = $self->{version_store}->$method($current_value);
	my $index = 0;
	my $my_index;
	my $values = [];
	while (@choice_pairs) {
		my $value = shift @choice_pairs;
		my $changeable = shift @choice_pairs;
		my $menuitem = Gtk2::MenuItem->new_with_label($value);
		$menu->append($menuitem);
		$menuitem->set_sensitive(FALSE) unless $changeable;
		$my_index = $index if $value eq $current_value;
		$index++;
		push @$values, $value;
	}
	my $choice = Gtk2::OptionMenu->new;
	$choice->set_menu($menu);
	$choice->set_history($my_index) if $my_index;
	return $choice, $values;
}

sub edit_selected ($) {
	my $self = shift;
	my $selection = $self->get_selection;
	my $window = $self->{window};

	unless ($selection->count_selected_rows == 1) {
		$window->set_status("No single partner version selected");
		return;
	}

	my $model = $self->get_model;
	my $iter = $model->get_iter($selection->get_selected_rows);
	my @values = $model->get($iter);

	my $dialog = Gtk2::Dialog->new_with_buttons(
		'Partner Version Info',
		$window, [ 'modal', 'destroy-with-parent' ],
		'gtk-ok', 'ok', 'gtk-cancel', 'cancel',
	);
	$dialog->set_border_width(4);

	my $hbox = Gtk2::HBox->new(FALSE, 8);
	$hbox->set_border_width(8);
	$dialog->vbox->pack_start($hbox, FALSE, FALSE, 0);

	my $icon = Gtk2::Image->new_from_stock('gtk-dialog-question', 'dialog');
	$hbox->pack_start($icon, FALSE, FALSE, 0);

	my $table = Gtk2::Table->new(2, 3, FALSE);
	$table->set_row_spacings(4);
	$table->set_col_spacings(4);
	$hbox->pack_start($table, TRUE, TRUE, 0);

	my $label = Gtk2::Label->new_with_mnemonic("_Type");
	$label->set_alignment(0.0, 0.5);
	$table->attach_defaults($label, 0, 1, 0, 1);
	my ($choice1, $values1) = $self->create_choice('type', $values[$self->{type}]);
	$table->attach_defaults($choice1, 1, 2, 0, 1);
	$label->set_mnemonic_widget($choice1);

	$label = Gtk2::Label->new_with_mnemonic("_Kinship");
	$label->set_alignment(0.0, 0.5);
	$table->attach_defaults($label, 0, 1, 1, 2);
	my ($choice2, $values2) = $self->create_choice('kinship', $values[$self->{kinship}]);
	$table->attach_defaults($choice2, 1, 2, 1, 2);
	$label->set_mnemonic_widget($choice2);

	$label = Gtk2::Label->new_with_mnemonic("_Role");
	$label->set_alignment(0.0, 0.5);
	$table->attach_defaults($label, 0, 1, 2, 3);
	my ($choice3, $values3) = $self->create_choice('role', $values[$self->{role}]);
	$table->attach_defaults($choice3, 1, 2, 2, 3);
	$label->set_mnemonic_widget($choice3);

	$label = Gtk2::Label->new_with_mnemonic("_Label");
	$label->set_alignment(0.0, 0.5);
	$table->attach_defaults($label, 0, 1, 3, 4);
	my $entry = Gtk2::Entry->new;
	$entry->set_text($values[$self->{label}]);
	$table->attach_defaults($entry, 1, 2, 3, 4);
	$label->set_mnemonic_widget($entry);

	$hbox->show_all;
	my $response = $dialog->run;

	if ($response eq 'ok') {
		my $type = $values1->[$choice1->get_history];
		$model->set($iter, $self->{type}, $type);
		my $kinship = $values2->[$choice2->get_history];
		$model->set($iter, $self->{kinship}, $kinship);
		my $role = $values3->[$choice3->get_history];
		$model->set($iter, $self->{role}, $role);
		$model->set($iter, $self->{label}, $entry->get_text);
		$self->{is_changed} = 1;
	}
	$dialog->destroy;
}

sub is_changed ($) {
	my $self = shift;
	return $self->{is_changed};
}

sub save ($) {
	my $self = shift;
	# not really
	$self->{version_store}->save;
	$self->{is_changed} = 0;
}

sub reload ($) {
	my $self = shift;
	# not really
	$self->{version_store}->load;
	$self->{is_changed} = 0;
}

sub rescan ($) {
	my $self = shift;
	$self->{version_store}->sync;
}

1;

__END__
