#!/usr/bin/perl

use strict;
use warnings;

use vars qw($VERSION);
$VERSION = '0.64';

use Tk;
require Tk::CodeText;
require Tk::YAMessage;
use Getopt::Long;
use File::Path qw(make_path);
use File::Spec;
use Config;
my $mswin = $Config{osname} eq 'MSWin32';

my $filename = '';

my $configfolder;
my $autoindent;
my $font;
my $help = 0;
my $match;
my $indentstyle;
my $shownumbers;
my $showfolds;
my $showstatus;
my $tabs;
my $themefile;
my $version = 0;
my $wrap;
my $xmlfolder;

#main help text
my $help_text = <<__EOF;
Usage: codetext [options] [filename]
Options:
-a -autoindent    1 or 0. Autoindent
-c -config:       Config folder.
-f -font:         'font string' Specify the editing font.
-h -help:         Displays this message.
-m -match:        By default '{}()[]'. 
-n -shownumbers:  1 or 0. By default 1. 
-o -showfolds:    1 or 0. By default 1 
-s -indentstyle:  By default 'tab'. Or a number of spaces.
-t -tabs:         Tab size. By default '8m' (8 milimeters') 
   -themefile:    Load a theme file with color and font definitions 
-u -showstatus:   1 or 0. By default 1 
                  for syntax highlighting 
-w -wrap:         By default 'none'. Can also be 'word' or 'char'. 
-x -xmlfolder:    Specifies the XML directory for syntax highlighting.
__EOF

# hard coded defaults
my %options = (
	-autoindent => 1,
	-font => 'Courier 12',
	-indentstyle => 'tab',
#	-logcall => sub { my $m = shift; print STDERR "$m\n" },
	-match => '{}()[]',
	-showfolds => 1,
	-shownumbers => 1,
	-showstatus => 1,
	-tabs => '8m',
	-wrap => 'none',
	-xmlfolder => undef,
);

#load command line options
GetOptions(
	#autoindent
	'a=s' => \$autoindent,
	'autoindent=s' => \$autoindent,
	#autoindent
	'c=s' => \$configfolder,
	'config=s' => \$configfolder,
	#font
	'f=s' => \$font,
	'font=s' => \$font,
	#help
	'h' => \$help,
	'help' => \$help,
	#match
	'm=s' => \$font,
	'match=s' => \$font,
	#shownumbers
	'n=s' => \$shownumbers,
	'shownumbers' => \$shownumbers,
	#showfolds
	'o=s' => \$showfolds,
	'showfolds=s' => \$showfolds,
	#showfolds
	'o=s' => \$showfolds,
	'showfolds=s' => \$showfolds,
	#indentstyle
	's=s' => \$indentstyle,
	'indentstyle=s' => \$indentstyle,
	#tabs
	't=s' => \$tabs,
	'tabs=s' => \$tabs,
	#themefile
	'themefile' => \$themefile,
	#showstatus
	'u=s' => \$showstatus,
	'showstatus=s' => \$showstatus,
	#version
	'v' => \$version,
	'version' => \$version,
	#wrap
	'w=s' => \$wrap,
	'wrap=s' => \$wrap,
	#xmlfolder
	'x=s' => \$xmlfolder,
	'xmlfolder=s' => \$xmlfolder,
) or die $help_text;

if ($help) {
	print $help_text;
	exit;
}

if ($version) {
	print "CodeText version ", Tk::CodeText->VERSION, "\n";
	exit;
}

unless (defined $configfolder) {
	if ($mswin) {
		$configfolder = $ENV{LOCALAPPDATA} . '/codetext' 
	} else {
		$configfolder = $ENV{HOME} . '/.local/share/codetext'
	}
}
unless (-e $configfolder) {
	unless (make_path($configfolder)) {
		die "Could not create path $configfolder";
	}
}
my $settingsfile = "$configfolder/settingsrc";

#load user settings
my @usersettings = ('-acpopsize', 'acscansize', '-activedelay', '-autobrackets',
	'-autocomplete', '-autoindent', '-indentstyle', '-match', '-showfolds',
	'-shownumbers', '-showstatus', '-tabs', '-wrap'
);
&loadSettings if -e $settingsfile;

$options{'-autoindent'} = $autoindent if defined $autoindent;
$options{'-font'} = $font if defined $font;
$options{'-indentstyle'} = $indentstyle if defined $indentstyle;
$options{'-match'} = $match if defined $match;
$options{'-showfolds'} = $showfolds if defined $showfolds;
$options{'-shownumbers'} = $shownumbers if defined $shownumbers;
$options{'-showstatus'} = $showstatus if defined $showstatus;
$options{'-tabs'} = $tabs if defined $tabs;
$options{'-wrap'} = $wrap if defined $wrap;
$options{'-xmlfolder'} = $xmlfolder if defined $xmlfolder;




my $app = MainWindow->new(-title => 'Codetext');

$app->protocol('WM_DELETE_WINDOW'=> \&quit);



my $txt = $app->CodeText(%options,
	-configdir => $configfolder,
	-width => 6,
	-height => 3,
)->pack(-expand => 1, -fill => 'both');

$app->bind('<Control-b>', [$txt, 'bookmarkNew']);
$app->bind('<Control-B>', [$txt, 'bookmarkRemove']);
$app->bind('<Control-n>', \&emptyDoc);
$app->bind('<Control-o>', \&loadDoc);
$app->bind('<Control-s>', \&saveDoc);
$app->bind('<Control-q>', \&quit);

my $menu;
$menu = $app->Menu(
	-menuitems => [
		['cascade' => '~File',
			-menuitems => [
				['command' => '~New',
					-command => \&emptyDoc,
					-accelerator => 'CTRL+N',
				],
				['command' => '~Open',
					-command => \&loadDoc,
 					-accelerator => 'CTRL+O',,
				],
				['separator' => '-'],
				['command' => '~Save',
					-command => \&saveDoc,
					-accelerator => 'CTRL+S',
				],
				['command' => 'S~ave as',
					-command => \&saveDocAs,
				],
				['separator' => '-'],
				['command' => '~Quit',
					-command => \&quit,
					-accelerator => 'CTRL+Q',
				],
			],
		],
		['cascade' => '~Edit',
			-menuitems => [ $txt->EditMenuItems	],
		],
		['cascade' => '~Tools',
			-menuitems => [ 
				['command' => '~Find',
					-accelerator => 'CTRL+F',
					-command => ['FindPopUp', $txt],
				],
				['command' => '~Replace',
					-accelerator => 'CTRL+R',
					-command => ['FindAndReplacePopUp', $txt],
				],
				['separator' => '-'],
				['command' => '~Collapse all folds',
					-command => ['foldCollapseAll', $txt],
				],
				['command' => '~Expand all folds',
					-command => ['foldExpandAll', $txt],
				],
				['separator' => '-'],
				$txt->ViewMenuItems,
				['separator' => '-'],
				['command' => 'Sa~ve settings',
					-command => \&saveSettings,
				],
			],
		],
		['cascade' => '~Bookmarks',
			-menuitems => [	
				['command' => '~Add bookmark',
					-command => ['bookmarkNew', $txt],
					-accelerator => 'CTRL+B',
				],
				['command' => '~Remove bookmark',
					-command => ['bookmarkRemove', $txt],
					-accelerator => 'CTRL+SHIFT+B',
				],
				['command' => 'Re~move all bookmarks',
					-command => ['bookmarkRemoveAll', $txt],
				],
				['separator' => '-'],
				['command' => '~Next bookmark',
					-command => ['bookmarkNext', $txt],
				],
				['command' => '~Previous bookmark',
					-command => ['bookmarkPrev', $txt],
				],
				['separator' => '-'],
			],
			-postcommand => sub { $txt->bookmarkMenuPop($menu, 'Bookmarks') },
		],
	],
);
$app->configure(-menu => $menu);

$app->after(300, sub {
	if (@ARGV) {
		my $file = File::Spec->rel2abs(shift @ARGV);
		unless (-e $file) {
			warn "File $_ does not exit";
			return;
		}
		if (-d $file) {
			warn "'$file' is a folder";
			return;
		}
		&loadDoc($file)
	}
});
# my $screenwidth = $app->vrootwidth;
# print "width $screenwidth\n";
# my $posx = int($app->vrootwidth / 2) - 400;
# my $posy = int($app->vrootheight / 2) - 300;
# print "popping at $posx, $posy\n";
$app->geometry(sprintf('%dx%d+%d+%d', 800, 600, 250, 250));
	
$app->MainLoop;

sub docSaved {
	if ($txt->editModified) {
		my $msg = $app->YAMessage(
			-text => "Text has been modified. Would you\nlike to save?",
			-justify => 'left',
			-buttons => ['Yes', 'No', 'Cancel'],
			-defaultbutton => 'Yes',
		);
		my $but = $msg->Show(-popover => $app);
		if ($but eq 'Yes') {
			return &saveDoc
		} elsif ($but eq 'No') {
			return 1
		} else {
			return 0
		}
	}
	return 1;
}

sub emptyDoc {
	if (&docSaved) {
		$txt->clear;
		$filename = '';
		$app->configure(-title => "Codetext");
		return 1
	}
	return 0
}

sub loadDoc {
	my $file = shift;
 	$file = $app->getOpenFile(
# 		-popover => 'mainwindow',
	) unless defined $file;
	return 0 unless defined $file;
	if ((&emptyDoc) and ($txt->load($file))) {
		$filename = $file;
		$app->configure(-title => "Codetext - $file");
		return 1
	}
	return 0
}

sub loadSettings {
	if (open(OFILE, "<", $settingsfile)) {
		while (<OFILE>) {
			my $line = $_;
			chomp $line;
			if ($line =~ s/^([^=]+)=//) {
				my $option = $1;
				$options{$option} = $line;
			}
		}
		close OFILE;
		return 1
	}
}

sub saveDoc {
	if ($filename eq '') {
		return &saveDocAs;
	}
	return $txt->save($filename);
}

sub saveDocAs {
 	my $file = $app->getSaveFile(
# 		-popover => 'mainwindow',
	);
	return 0 unless defined $file;
	if ($txt->save($file)) {
		$filename = $file;
		$app->configure(-title => "Codetext - $file");
		return 1
	}
	return 0
}

sub saveSettings {
	if (open(OFILE, ">", $settingsfile)) {
		for (@usersettings) {
			my $option = $_;
			my $value = $txt->cget($option);
			print OFILE $option, '=', $value, "\n";
		}
		close OFILE;
		return 1
	} else {
		warn "Could not open '$settingsfile'"
	}
	return 0
}

sub quit {
	$app->destroy if &docSaved
}

__END__

