#!/usr/bin/env perl
use strict;

my $node_now;
my $command_line  = 'pcle' or $ARGV[1];
my $system_editor = 'vim'; #change this to suit your needs
my $color_system = '33;1';  # yellow, bold
my $color_header = '34;1';  # blue, bold
my $color_link = '4';  # underline
my @node_info;
my @visited_nodes;
my $pcle_ver = '0.3';

my $help = << "__HELP__";
\x1b[${color_system}m
This is Personal Command-Line Everything version $pcle_ver
created by lenz, updated by raincomplex

Commands are as follows:
 - 'help' prints this message
 - 'quit' or 'bye' exits PCLE
 - 'latest' shows latest nodes ('latest 3' shows latest 3 nodes)
 - 'history' shows node history ('history 3' shows latest 3 entries)
 - 'new' creates a node
 - 'edit' edits a node
 - enter node number (like '3' or '#3') or name to reach it.
 - enter '-1', '-2' to navigate backwards 
\x1b[0m
__HELP__

print $help;
print loadNode( $command_line );

for(;;) {
	print "> ";
	$command_line = lc <>;
	
	exit if $command_line =~ /^quit|bye/i;
    
    if ($command_line =~ /^(edit|new) (.+?)$/i) {
    	createNode( $2 );
    	$command_line = $2;	
    };

	if ($command_line =~ /^latest\s*(\d*)$/i) {
		latestNodes( $1 || 99999 );
    	$command_line = '';	
	}
	
	if ($command_line =~ /^history\s*(\d*)$/i) {
		showHistory( $1 || 99999 );
    	$command_line = '';	
	}
	
	
	
	if ($command_line =~ /^help$/i) {
		print $help;
    	$command_line = '';	
	}
	
	if ($command_line =~ /^#*\s*(\d+)/i) {
		$command_line = $node_info[$1];
	}
	
	if ($command_line =~ /^-(\d+)/i) {
		$command_line = $visited_nodes[-$1 - 1];
	}
	
		
	print loadNode( $command_line );
}




sub loadNode() {
	my ($nodeName) = @_;
	chomp $nodeName;
	
	return if length($nodeName) == 0;
		
	my $nodePath = lc $nodeName . ".node";
	my $n = "\x1b[${color_header}mNode '$nodeName' - ";
	my $dt;
		
	if ( -f $nodePath ) {
		undef @node_info;
		open F, $nodePath or die "$! $nodePath";
		$n .= localtime( (stat( $nodePath ))[9] ) . "\n";
		$n .= ('-' x (-8 + length $n)) . "\x1b[0m\n";
		
		while (<F>) {
			$n .= $_;
		}
		close F;
		
		# replace and number bracketed stuff
		$n =~ s/\[([^\[\]]+?)(\|[^\[\]]+?)?\]/doSubst($1, $2)/gime;
		
		push @visited_nodes, $nodeName;
	} else {
		$n = "\x1b[${color_system}mThe node '$nodeName' does not exist\nType 'new $nodeName' to create it.\x1b[0m\n";
	}
	return $n . "\n";
}

sub doSubst() {
	my ($n, $t) = @_;
	if (!$t) { $t = $n; }  # regular links: display text = link text
	else { $t = substr $t, 1; }  # remove pipes from display text
	push @node_info, $n;
	return "\x1b[${color_link}m$t\x1b[0m[" . $#node_info . "]";
}
	


sub createNode() {
	my ($nodeName) = @_;
	chomp $nodeName;
	my $nodePath = lc $nodeName . ".node";
	
	system( "$system_editor $nodePath" );

}

sub latestNodes() {
	my ($howMany) = @_;
	
	my @files = glob( '*.node' );
	my %dtupd;
	my $n = 0;
	
	foreach my $f (@files) {
		my $tm = (stat( $f ))[9] ;
		$dtupd{ $tm . ':' . $n++ } = $1 if $f =~ /(.+)\.node/i;
	}	

	$n = 0;
	foreach my $f (reverse sort keys %dtupd ) {
		last if ($n++ >= $howMany);
		my ($d) = split /:/, $f;
		print localtime( $d ) . "  - " . $dtupd{$f} . "\n";
	}
}

sub showHistory() {
	my ($howMany) = @_;
	my @cmd = reverse @visited_nodes;
	my $i = 0;
	
	foreach my $n (@cmd[0..$howMany]) {
		last if length($n) == 0;
		print "-$i: $n\n";
		$i++;
	}
}

