// Path: src/main/java/info/deskchan/gui_javafx/panes/sprite_drawers/ImageSprite.java
// public class ImageSprite extends Sprite {
// 
//     private String path = null;
// 
//     public static boolean canRead(File path){
//         try {
//             Image image = new Image(new FileInputStream(path));
//             return image.getHeight() > 0 && image.getWidth() > 0;
//         } catch (Exception e){
//             Main.log(e);
//             return false;
//         }
//     }
// 
//     public static ImageSprite create(File path) throws Exception {
//         Image image = new Image(new FileInputStream(path));
// 
//         Insets margin;
//         String textStyle;
//         try {
//             Document document = getDocument(path + ".config");
//             margin = getMarginFromFile(document);
//             textStyle = getTextStyle(document);
//         } catch (Exception e){
//             margin = getMarginFromFile(null);
//             textStyle = getTextStyle(null);
//         }
// 
//         ImageView view = new ImageView();
//         view.setImage(image);
// 
//         return new ImageSprite(view, textStyle, margin, path);
//     }
// 
//     private ImageSprite(Node sprite, String contentStyle, Insets margin, File path) {
//         super(sprite, contentStyle, margin);
//         this.path = path != null ? path.toString() : null;
//     }
// 
//     public double getOriginWidth(){
//         return toImageView().getImage() != null ? toImageView().getImage().getWidth() : 0;
//     }
// 
//     public double getOriginHeight(){
//         return toImageView().getImage() != null ? toImageView().getImage().getHeight() : 0;
//     }
// 
//     public double getFitWidth() {  return toImageView().getFitWidth();   }
// 
//     public double getFitHeight(){  return toImageView().getFitHeight();  }
// 
//     public void setFitWidth(double width)  {  toImageView().setFitWidth(width);    }
// 
//     public void setFitHeight(double height){  toImageView().setFitHeight(height);  }
// 
//     public ImageView toImageView(){ return (ImageView) sprite; }
// 
//     public String getSpritePath(){ return path; }
// 
// }


import info.deskchan.gui_javafx.*;
import info.deskchan.gui_javafx.panes.sprite_drawers.AnimatedSprite;
import info.deskchan.gui_javafx.panes.sprite_drawers.ImageSprite;
import info.deskchan.gui_javafx.panes.sprite_drawers.Sprite;
import info.deskchan.gui_javafx.skins.Skin;
import javafx.geometry.Point2D;
import javafx.geometry.Rectangle2D;
import javafx.scene.control.ContextMenu;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.Light;
import javafx.scene.effect.Lighting;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelReader;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.stage.Screen;
import java.io.File;
import java.util.*;
			boolean enabled = Main.getProperties().getBoolean("character.enable_context_menu", true);
			ContextMenu contextMenu = Menu.getInstance().getContextMenu();
			// We need to hide menu manually in both cases to avoid showing the menu with incorrect width.
			contextMenu.hide();
			if (enabled && event.getButton() == MouseButton.SECONDARY && event.isStillSincePress()) {
				contextMenu.show(this, event.getScreenX(), event.getScreenY());
			}
		});

		MouseEventNotificator mouseEventNotificator = new MouseEventNotificator(this, "character");
		mouseEventNotificator
				.setOnClickListener()
				.setOnMovedListener()
				.setOnScrollListener(event -> {
					Point2D characterPosition = getPosition();
					double charX = characterPosition.getX();
					double charY = characterPosition.getY();
					double x = event.getX();
					double y = event.getY();
					double x0 = x - charX;
					double y0 = y - charY;

					// just in case
					if (scaleFactor == 0) {
						Main.log("The scale factor of the image is equal to zero!");
						return false;
					}
					x0 /= scaleFactor;
					y0 /= scaleFactor;

// Path: src/main/java/info/deskchan/gui_javafx/panes/sprite_drawers/ImageSprite.java
// public class ImageSprite extends Sprite {
// 
//     private String path = null;
// 
//     public static boolean canRead(File path){
//         try {
//             Image image = new Image(new FileInputStream(path));
//             return image.getHeight() > 0 && image.getWidth() > 0;
//         } catch (Exception e){
//             Main.log(e);
//             return false;
//         }
//     }
// 
//     public static ImageSprite create(File path) throws Exception {
//         Image image = new Image(new FileInputStream(path));
// 
//         Insets margin;
//         String textStyle;
//         try {
//             Document document = getDocument(path + ".config");
//             margin = getMarginFromFile(document);
//             textStyle = getTextStyle(document);
//         } catch (Exception e){
//             margin = getMarginFromFile(null);
//             textStyle = getTextStyle(null);
//         }
// 
//         ImageView view = new ImageView();
//         view.setImage(image);
// 
//         return new ImageSprite(view, textStyle, margin, path);
//     }
// 
//     private ImageSprite(Node sprite, String contentStyle, Insets margin, File path) {
//         super(sprite, contentStyle, margin);
//         this.path = path != null ? path.toString() : null;
//     }
// 
//     public double getOriginWidth(){
//         return toImageView().getImage() != null ? toImageView().getImage().getWidth() : 0;
//     }
// 
//     public double getOriginHeight(){
//         return toImageView().getImage() != null ? toImageView().getImage().getHeight() : 0;
//     }
// 
//     public double getFitWidth() {  return toImageView().getFitWidth();   }
// 
//     public double getFitHeight(){  return toImageView().getFitHeight();  }
// 
//     public void setFitWidth(double width)  {  toImageView().setFitWidth(width);    }
// 
//     public void setFitHeight(double height){  toImageView().setFitHeight(height);  }
// 
//     public ImageView toImageView(){ return (ImageView) sprite; }
// 
//     public String getSpritePath(){ return path; }
// 
// }


// Path: src/main/java/info/deskchan/gui_javafx/panes/Character.java
import info.deskchan.gui_javafx.*;
import info.deskchan.gui_javafx.panes.sprite_drawers.AnimatedSprite;
import info.deskchan.gui_javafx.panes.sprite_drawers.ImageSprite;
import info.deskchan.gui_javafx.panes.sprite_drawers.Sprite;
import info.deskchan.gui_javafx.skins.Skin;
import javafx.geometry.Point2D;
import javafx.geometry.Rectangle2D;
import javafx.scene.control.ContextMenu;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.Light;
import javafx.scene.effect.Lighting;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.PixelReader;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.stage.Screen;
import java.io.File;
import java.util.*;

			boolean enabled = Main.getProperties().getBoolean("character.enable_context_menu", true);
			ContextMenu contextMenu = Menu.getInstance().getContextMenu();
			// We need to hide menu manually in both cases to avoid showing the menu with incorrect width.
			contextMenu.hide();
			if (enabled && event.getButton() == MouseButton.SECONDARY && event.isStillSincePress()) {
				contextMenu.show(this, event.getScreenX(), event.getScreenY());
			}
		});

		MouseEventNotificator mouseEventNotificator = new MouseEventNotificator(this, "character");
		mouseEventNotificator
				.setOnClickListener()
				.setOnMovedListener()
				.setOnScrollListener(event -> {
					Point2D characterPosition = getPosition();
					double charX = characterPosition.getX();
					double charY = characterPosition.getY();
					double x = event.getX();
					double y = event.getY();
					double x0 = x - charX;
					double y0 = y - charY;

					// just in case
					if (scaleFactor == 0) {
						Main.log("The scale factor of the image is equal to zero!");
						return false;
					}
					x0 /= scaleFactor;
					y0 /= scaleFactor;

					if (!(sprite.getCurrentSprite() instanceof ImageSprite))