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

use Glib qw(TRUE FALSE);
use Gtk2;
use Gtk2::Pango;

use base qw(Gtk2::TextView);

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

	my $self = bless Gtk2::TextView->new, $class;

	$self->_init;

	return $self;
}

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

	$self->set_wrap_mode('none');

	my $fd = Gtk2::Pango::FontDescription->new;
	$fd->set_family('monospace');
	$self->modify_font($fd);

	my $buffer = $self->get_buffer;

	$buffer->create_tag('header_name', weight => 700);
	$buffer->create_tag('header_value', weight => 0);

	$buffer->signal_connect('begin-user-action' => sub {
		$self->{user_count} = $_[0]->get_char_count;
		$self->{user_where} =
			$_[0]->get_iter_at_mark($_[0]->get_insert)->get_offset;
	});

	$buffer->signal_connect('delete-range' => sub {
		$self->{user_where} = $_[1]->get_offset;
	});
	$buffer->signal_connect('insert-text' => sub {
		$self->{user_where} = $_[1]->get_offset;
	});

	$buffer->signal_connect('end-user-action' => sub {
		$self->changed(
			$self->{user_where},
			$_[0]->get_char_count - $self->{user_count}
		);

		delete $self->{user_count};
		delete $self->{user_where};
	});
}

sub set_tag ($$@) {
	my $self = shift;
	my ($tag, @props) = @_;

	my $table = $self->get_buffer->get_tag_table;
	my $texttag = $table->lookup($tag);
	$table->remove($texttag);
	$self->get_buffer->create_tag($tag, @props);
}

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

	$self->get_buffer->set_text('');
	$self->{header_end} = 0;
}

sub show ($$) {
	my $self = shift;
	my $text = shift;

	$self->clear;

	my $buffer = $self->get_buffer;
	$buffer->set_text($text);
	$self->changed(0, $buffer->get_char_count);
}

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

	my $buffer = $self->get_buffer;
	return $buffer->get_text($buffer->get_start_iter, $buffer->get_end_iter, FALSE);
}

sub changed ($$$) {
	my $self = shift;
	my ($location, $count) = @_;

	return if $location > $self->{header_end};
	
	my $buffer = $self->get_buffer;

	my $from = $location;
	my $to   = $count > 0 ? $location + $count : $location;

	# header/body separator has been deleted
	if (($location + abs($count)) >= $self->{header_end}) {
		$self->{header_end} = $to = $buffer->get_char_count;
	} else {
		$self->{header_end} += $count;
	}

	my $iter = $buffer->get_iter_at_offset($from);
	$iter->set_line_offset(0);

	do {
		if (($iter->get_chars_in_line == 1) && ($iter->get_char eq "\n")) {
			$to = $self->{header_end}
				if $self->{header_end} > $to;
			$self->{header_end} = $iter->get_offset
				if $iter->get_offset < $self->{header_end};

		} else {
			$self->reformat_line($iter);
		}
	} while $iter->forward_line && $iter->get_offset <= $to;
}

sub reformat_line ($$) {
	my $self = shift;
	my $line_start = shift;

	return if $line_start->get_chars_in_line == 0;

	my $line_end = $line_start->copy;
	$line_end->forward_to_line_end;

	my $buffer = $line_start->get_buffer;
	$buffer->remove_all_tags($line_start, $line_end);

	if ($line_start->get_offset < $self->{header_end}) {
		my $col_pos = index($buffer->get_text($line_start, $line_end, TRUE), ':');

		if ($col_pos != -1) {
			my $colon = $line_start->copy;
			$colon->forward_chars($col_pos + 1);
			$buffer->apply_tag_by_name('header_name', $line_start, $colon);
#			$colon->forward_char;
#			$buffer->apply_tag_by_name('header_value', $colon, $line_end);
#		} else {
#			$buffer->apply_tag_by_name('header_value', $line_start, $line_end);
		}
	}
}	

1;

__END__
