/*
 * Copyright (C) 2018 Andrew Gegg
 *
 *	This file is part of the Garden Notebook application
 *
 * The Garden Notebook application 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 3 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, see <http://www.gnu.org/licenses/>.
 */
package uk.co.gardennotebook;

import java.text.MessageFormat;
import java.util.ResourceBundle;
import java.util.function.UnaryOperator;
import javafx.geometry.Bounds;
import javafx.scene.Node;
import javafx.scene.control.Label;
import javafx.scene.control.TextFormatter;
import javafx.scene.control.TextFormatter.Change;
import javafx.stage.Popup;

/**
	*	A TextFormatter which limits the number of characters allowed to be input
	* into a text field.
	* 
	* (Technique derived from various StackOverflow solutions)
	*
	*	@author Andy Gegg
	*	@version	1.0
	*	@since	1.0
 */
final class MaxLengthTextFormatter {
	
	private MaxLengthTextFormatter()
	{	}
	
	static TextFormatter<String> getFormatter(final int length)
	{
		UnaryOperator<Change> rejectChange = c -> {
			// check if the change might effect the validating predicate
			if (c.isContentChange()) {
				// check if change is valid
				if (c.getControlNewText().length() > length) {
					// invalid change
					// sugar: popup an error message
					final Popup tellem = new Popup();
					ResourceBundle resources = ResourceBundle.getBundle("notebook");
					String lblTxt = MessageFormat.format(resources.getString("alert.texttoolong"), length);
					tellem.getContent().add(new Label(lblTxt));
					tellem.setAutoHide(true);
					Node control = c.getControl();
					Bounds bounds = control.localToScreen(control.getBoundsInLocal());
					tellem.show(control, bounds.getMinX(), bounds.getMaxY());
					// return null to reject the change
					return null;
				}
			}
			// valid change: accept the change by returning it
			return c;
		};
		return new TextFormatter<>(rejectChange);
	}
}
