package Kephra::Edit::Format;
our $VERSION = '0.26';

use strict;
use warnings;

sub _ep_ref { Kephra::App::EditPanel::_ref() }
sub _config { Kephra::API::settings()->{editpanel} }

# change indention width of selected text
sub _indent_selection {
	my $width = shift || 0;
	my $ep    = _ep_ref();
	$ep->BeginUndoAction;
	for (    $ep->LineFromPosition($ep->GetSelectionStart)
	      .. $ep->LineFromPosition($ep->GetSelectionEnd)   ) {
		$ep->SetLineIndentation( $_, $ep->GetLineIndentation($_) + $width )
			unless $ep->PositionFromLine($_) == $ep->GetLineEndPosition($_);
	}
	$ep->EndUndoAction;
}

sub autoindent {
	my $ep  = _ep_ref();
	my $line = $ep->GetCurrentLine;

	$ep->BeginUndoAction;
	$ep->CmdKeyExecute(&Wx::wxSTC_CMD_NEWLINE);
	my $indent = $ep->GetLineIndentation( $line );
	$ep->SetLineIndentation( $line + 1, $indent);
	$ep->GotoPos( $ep->GetLineIndentPosition( $line + 1 ) );
	$ep->EndUndoAction;
}

sub blockindent_open {
	my $ep         = _ep_ref();
	my $tabsize    = Kephra::Document::Data::attr('tab_size');
	my $line       = $ep->GetCurrentLine;
	my $first_cpos = $ep->PositionFromLine($line)
		+ $ep->GetLineIndentation($line); # position of first char in line
	my $matchfirst = $ep->BraceMatch($first_cpos);

	$ep->BeginUndoAction;

	# dedent a "} else {" correct
	if ($ep->GetCharAt($first_cpos) == 125 and $matchfirst > -1) {
		$ep->SetLineIndentation( $line, $ep->GetLineIndentation(
				$ep->LineFromPosition($matchfirst) ) );
	}
	# grabbing
	my $bracepos   = $ep->GetCurrentPos - 1;
	my $leadindent = $ep->GetLineIndentation($line);
	my $matchbrace = $ep->BraceMatch( $bracepos );
	my $matchindent= $ep->GetLineIndentation($ep->LineFromPosition($matchbrace));

	# make newl line
	$ep->CmdKeyExecute(&Wx::wxSTC_CMD_NEWLINE);

	# make new brace if there is missing one
	if (_config()->{auto}{brace}{make} and
		($matchbrace == -1 or $ep->GetLineIndentation($line) != $matchindent )){
		$ep->CmdKeyExecute(&Wx::wxSTC_CMD_NEWLINE);
		$ep->AddText('}');
		$ep->SetLineIndentation( $line + 2, $leadindent );
	}
	$ep->SetLineIndentation( $line + 1, $leadindent + $tabsize );
	$ep->GotoPos( $ep->GetLineIndentPosition( $line + 1 ) );

	$ep->EndUndoAction;
}

sub blockindent_close {
	my $ep = _ep_ref();
	my $bracepos = shift;
	unless ($bracepos) {
		$bracepos = $ep->GetCurrentPos - 1;
		$bracepos-- while $ep->GetCharAt($bracepos) == 32;
	}

	$ep->BeginUndoAction;

	# 1 if it not textend, goto next line
	my $match = $ep->BraceMatch($bracepos);
	my $line  = $ep->GetCurrentLine;
	unless ($ep->GetLineIndentPosition($line)+1 == $ep->GetLineEndPosition($line)
		or  $ep->LineFromPosition($match) == $line ) {
		$ep->GotoPos($bracepos);
		$ep->CmdKeyExecute(&Wx::wxSTC_CMD_NEWLINE);
		$ep->GotoPos( $ep->GetCurrentPos + 1 );
		$line++;
	}

	# 2 wenn match dann korrigiere einrückung ansonst letzte - tabsize
	if ( $match > -1 ) {
		$ep->SetLineIndentation( $line,
			$ep->GetLineIndentation( $ep->LineFromPosition($match) ) );
	} else {
		$ep->SetLineIndentation( $line,
			$ep->GetLineIndentation( $line - 1 )
				- Kephra::Document::Data::attr('tab_size') );
	}

	# make new line
	_config()->{auto}{indent}
		? autoindent()
		: $ep->CmdKeyExecute(&Wx::wxSTC_CMD_NEWLINE);

	# 3 lösche dubs wenn in nächster zeile nur spaces bis dup
	#if ( _config()->{auto}{brace}{join} ) {
		#my $delbrace = $ep->PositionFromLine( $line + 2 )
			#+ $ep->GetLineIndentation( $line + 1 );
		#if ( $ep->GetCharAt($delbrace) == 125 ) {
			#$ep->SetTargetStart( $ep->GetCurrentPos );
			#$ep->SetTargetEnd( $delbrace + 1 );
			#$ep->ReplaceTarget('');
		#}
	#}

	$ep->EndUndoAction;
}

sub indent_space { _indent_selection( 1) }
sub dedent_space { _indent_selection(-1) }
sub indent_tab   { _indent_selection( Kephra::Document::Data::attr('tab_size') ) }
sub dedent_tab   { _indent_selection(-Kephra::Document::Data::attr('tab_size') ) }

#
sub align_indent {
	my $ep = _ep_ref();
	my $firstline = $ep->LineFromPosition( $ep->GetSelectionStart );
	my $align = $ep->GetLineIndentation($firstline);
	$ep->BeginUndoAction();
	$ep->SetLineIndentation($_ ,$align)
		for $firstline + 1 .. $ep->LineFromPosition($ep->GetSelectionEnd);
	$ep->EndUndoAction();
}

# deleting trailing spaces on line ends
sub del_trailing_spaces {
	&Kephra::Edit::_save_positions;
	my $ep = _ep_ref();
	my $text = Kephra::Edit::_select_all_if_none();
	$text =~ s/[ \t]+(\r|\n|\Z)/$1/g;
	$ep->BeginUndoAction;
	$ep->ReplaceSelection($text);
	$ep->EndUndoAction;
	Kephra::Edit::_restore_positions();
}

#
sub join_lines {
 my $ep = _ep_ref();
 my $text = $ep->GetSelectedText();
	$text =~ s/[\r|\n]+/ /g; # delete end of line marker
	$ep->BeginUndoAction;
	$ep->ReplaceSelection($text);
	$ep->EndUndoAction;
}

sub blockformat{
	return unless Scalar::Util::looks_like_number($_[0]);
	my $width     = (int shift) + 1;
	my $ep        = _ep_ref();
	my ($begin, $end) = $ep->GetSelection;
	my $bline     = $ep->LineFromPosition($begin);
	my $tmp_begin = $ep->PositionFromLine($bline);
	my $bspace    = ' ' x $ep->GetLineIndentation($bline);
	my $space     = _config()->{auto}{indention} ? $bspace : '';
	chop $bspace;

	$ep->SetSelection($tmp_begin, $end);
	require Text::Wrap;
	$Text::Wrap::columns  = $width;
	$Text::Wrap::unexpand = Kephra::Document::Data::attr('tab_use');
	$Text::Wrap::tabstop  = Kephra::Document::Data::attr('tab_size');

	my $text = $ep->GetSelectedText;
	$text =~ s/[\r|\n]+/ /g;
	$ep->BeginUndoAction();
	$ep->ReplaceSelection( Text::Wrap::fill($bspace, $space, $text) );
	$ep->EndUndoAction();
}

sub blockformat_LLI{
	blockformat( _config()->{indicator}{right_margin}{position} );
}

sub blockformat_custom {
	my $l18n = Kephra::Config::Localisation::strings()->{dialog}{edit};
	my $width = Kephra::Dialog::get_text(
		$l18n->{wrap_width_input}, 
		$l18n->{wrap_custom_headline}
	);
	blockformat( $width ) if defined $width;
}



# breaking too long lines into smaller one
sub line_break {
	return unless Scalar::Util::looks_like_number($_[0]);
	my $width        = (int shift) + 1;
	my $ep           = _ep_ref();
	my ($begin, $end)= $ep->GetSelection;
	my $tmp_begin    = $ep->LineFromPosition( $ep->PositionFromLine($begin) );

	$ep->SetSelection($tmp_begin, $end);
	require Text::Wrap;
	$Text::Wrap::columns  = $width;
	$Text::Wrap::unexpand = Kephra::Document::Data::attr('tab_use');
	$Text::Wrap::tabstop  = Kephra::Document::Data::attr('tab_size');

	$ep->BeginUndoAction();
	$ep->ReplaceSelection( Text::Wrap::wrap('', '', $ep->GetSelectedText) );
	$ep->EndUndoAction();
}

sub linebreak_custom {
	my $l10n = Kephra::Config::Localisation::strings()->{dialog}{edit};
	my $width = Kephra::Dialog::get_text
			($l10n->{wrap_width_input}, $l10n->{wrap_custom_headline} );
	line_break( $width ) if defined $width;
}

sub linebreak_LLI {
	line_break( _config()->{indicator}{right_margin}{position} );
}

sub linebreak_window {
	my $app = Kephra::App::Window::_ref();
	my $ep  = _ep_ref();
	my ($width) = $app->GetSizeWH();
	my $pos = $ep->GetColumn( $ep->PositionFromPointClose(100, 67) );
	Kephra::Dialog::msg_box( $pos, '' );
	#line_break($width);
}

1;
__END__

=head1 NAME

Kephra::App::Format - functions that play with indention and length of lines

=head1 DESCRIPTION