<commit_before>package com.ray3k.skincomposer.dialog.scenecomposer;

import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.ui.*;
import com.badlogic.gdx.utils.*;
import com.badlogic.gdx.utils.reflect.ClassReflection;
import com.badlogic.gdx.utils.reflect.ReflectionException;
import com.ray3k.skincomposer.Main;
import com.ray3k.skincomposer.data.ColorData;
import com.ray3k.skincomposer.data.DrawableData;
import com.ray3k.skincomposer.data.StyleData;
import com.ray3k.skincomposer.dialog.scenecomposer.DialogSceneComposer.View;
import com.ray3k.skincomposer.dialog.scenecomposer.DialogSceneComposerModel.Interpol;
import com.ray3k.skincomposer.dialog.scenecomposer.undoables.SceneComposerUndoable;

import java.util.Locale;

import static com.ray3k.skincomposer.dialog.scenecomposer.DialogSceneComposer.dialog;

public class DialogSceneComposerModel {
    private transient Main main;
    public transient Array<SceneComposerUndoable> undoables;
    public transient Array<SceneComposerUndoable> redoables;
    public static SimRootGroup rootActor;
    public transient Stack preview;
    private static Json json;
    
    public enum Interpol {
        LINEAR(Interpolation.linear, "Linear", "linear"), SMOOTH(Interpolation.smooth, "Smooth", "smooth"), SMOOTH2(
                Interpolation.smooth2, "Smooth 2", "smooth2"),
        SMOOTHER(Interpolation.smoother, "Smoother", "smoother"), FADE(Interpolation.fade, "Fade", "fade"), POW2(
                Interpolation.pow2, "Pow 2", "pow2"),
        POW2IN(Interpolation.pow2In, "Pow 2 In", "pow2In"), SLOW_FAST(Interpolation.slowFast, "Slow Fast",
                "slowFast"), POW2OUT(Interpolation.pow2Out, "Pow 2 Out", "pow2Out"),
        FAST_SLOW(Interpolation.fastSlow, "Fast Slow", "fastSlow"), POW2IN_INVERSE(Interpolation.pow2In,
                "Pow 2 In Inverse", "pow2In"),
        POW2OUT_INVERSE(Interpolation.pow2OutInverse, "Pow 2 Out Inverse", "pow2OutInverse"), POW3(Interpolation.pow3,
                "Pow 3", "pow3"), POW3IN(Interpolation.pow3In, "Pow 3 In", "pow3In"),
        POW3OUT(Interpolation.pow3Out, "Pow 3 Out", "pow3Out"), POW3IN_INVERSE(Interpolation.pow3InInverse,
                "Pow 3 In Inverse", "pow3InInverse"),
        POW3OUT_INVERSE(Interpolation.pow3OutInverse, "Pow 3 Out Inverse", "pow3OutInverse"), POW4(Interpolation.pow4,
                "Pow 4", "pow4"), POW4IN(Interpolation.pow4In, "Pow 4 In", "pow4In"),
        POW4OUT(Interpolation.pow4Out, "Pow 4 Out", "pow4Out"), POW5(Interpolation.pow5, "Pow 5", "pow5"), POW5IN(
                Interpolation.pow5In, "Pow 5 In", "pow5In"),
        POW5OUT(Interpolation.pow5Out, "Pow 5 Out", "pow5Out"), SINE(Interpolation.sine, "Sine", "sine"), SINE_IN(
                Interpolation.sineIn, "Sine In", "sineIn"),
        SINE_OUT(Interpolation.sineOut, "Sine Out", "sineOut"), EXP10(Interpolation.exp10, "Exp 10", "exp10"), EXP10_IN(
                Interpolation.exp10In, "Exp 10 In", "exp10In"),
        EXP10_OUT(Interpolation.exp10Out, "Exp 10 Out", "exp10Out"), EXP5(Interpolation.exp5, "Exp 5", "exp5"), EXP5IN(
                Interpolation.exp5In, "Exp 5 In", "exp5In"),
        EXP5OUT(Interpolation.exp5Out, "Exp 5 Out", "exp5Out"), CIRCLE(Interpolation.circle, "Circle",
                "circle"), CIRCLE_IN(Interpolation.circleIn, "Circle In", "circleIn"),
        CIRCLE_OUT(Interpolation.circleOut, "Circle Out", "circleOut"), ELASTIC(Interpolation.elastic, "Elastic",
                "elastic"), ELASTIC_IN(Interpolation.elasticIn, "Elastic In", "elasticIn"),
        ELASTIC_OUT(Interpolation.elasticOut, "Elastic Out", "elasticOut"), SWING(Interpolation.swing, "Swing",
                "swing"), SWING_IN(Interpolation.swingIn, "Swing In", "swingIn"),
        SWING_OUT(Interpolation.swingOut, "Swing Out", "swingOut"), BOUNCE(Interpolation.bounce, "Bounce",
                "bounce"), BOUNCE_IN(Interpolation.bounceIn, "Bounce In", "bounceIn"),
        BOUNCE_OUT(Interpolation.bounceOut, " Bounce Out", "bounceOut");
        
        public Interpolation interpolation;
        public String text;
        public String code;
        
        Interpol(Interpolation interpolation, String text, String code) {
            this.interpolation = interpolation;
            this.text = text;
            this.code = code;
        }
    
        @Override
        public String toString() {
            return text;
        }
    }
    
    public DialogSceneComposerModel() {
        undoables = new Array<>();
        redoables = new Array<>();
        preview = new Stack();
        main = Main.main;
    
        json = new Json();
        json.setSerializer(ColorData.class, new Json.Serializer<>() {
            @Override
            public void write(Json json, ColorData object, Class knownType) {
                json.writeValue(object.getName());
            }

            @Override
            public ColorData read(Json json, JsonValue jsonData, Class type) {
                return Main.main.getJsonData().getColorByName(jsonData.asString());
            }
        });
        json.setSerializer(DrawableData.class, new Json.Serializer<>() {
            @Override
            public void write(Json json, DrawableData object, Class knownType) {
                json.writeValue(object.name);
            }

            @Override
            public DrawableData read(Json json, JsonValue jsonData, Class type) {
                return Main.main.getAtlasData().getDrawable(jsonData.asString());
            }
        });
        json.setSerializer(StyleData.class, new Json.Serializer<>() {
            @Override
            public void write(Json json, StyleData object, Class knownType) {
                json.writeObjectStart();
                json.writeValue("clazz", object.clazz.getName());
                json.writeValue("name", object.name);
                json.writeObjectEnd();
            }

            @Override
            public StyleData read(Json json, JsonValue jsonData, Class type) {
                try {
                    return Main.main.getJsonData().findStyle(ClassReflection.forName(jsonData.getString("clazz")), jsonData.getString("name"));
                } catch (ReflectionException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        });
        json.setOutputType(JsonWriter.OutputType.json);
        json.setUsePrototypes(false);
        json.addClassTag("Actor", SimActor.class);
        json.addClassTag("Button", SimButton.class);
        json.addClassTag("Cell", SimCell.class);
        json.addClassTag("CheckBox", SimCheckBox.class);
        json.addClassTag("Container", SimContainer.class);
        json.addClassTag("HorizontalGroup", SimHorizontalGroup.class);
        json.addClassTag("Image", SimImage.class);
        json.addClassTag("ImageButton", SimImageButton.class);
        json.addClassTag("ImageTextButton", SimImageTextButton.class);
        json.addClassTag("Label", SimLabel.class);
        json.addClassTag("List", SimList.class);
        json.addClassTag("Node", SimNode.class);
        json.addClassTag("ProgressBar", SimProgressBar.class);
        json.addClassTag("Root", SimRootGroup.class);
        json.addClassTag("ScrollPane", SimScrollPane.class);
        json.addClassTag("SelectBox", SimSelectBox.class);
        json.addClassTag("Slider", SimSlider.class);
        json.addClassTag("SplitPane", SimSplitPane.class);
        json.addClassTag("Stack", SimStack.class);
        json.addClassTag("Table", SimTable.class);
        json.addClassTag("TextArea", SimTextArea.class);
        json.addClassTag("TextButton", SimTextButton.class);
        json.addClassTag("TextField", SimTextField.class);
        json.addClassTag("TouchPad", SimTouchPad.class);
        json.addClassTag("Tree", SimTree.class);
        json.addClassTag("VerticalGroup", SimVerticalGroup.class);
        
        if (rootActor == null) rootActor = new SimRootGroup();
        assignParentRecursive(rootActor);
    }
    
    public static void saveToJson(FileHandle saveFile) {
        if (!saveFile.extension().toLowerCase(Locale.ROOT).equals("json")) {
            saveFile = saveFile.sibling(saveFile.nameWithoutExtension() + ".json");
        }
        saveFile.writeString(json.prettyPrint(rootActor), false);
    }
    
    public static void loadFromJson(FileHandle loadFile) {
        rootActor = json.fromJson(SimRootGroup.class, loadFile);
        assignParentRecursive(rootActor);
    }
    
    public void undo() {
        if (undoables.size > 0) {
            var undoable = undoables.pop();
            redoables.add(undoable);
            
            undoable.undo();
        }
    }
    
    public void redo() {
        if (redoables.size > 0) {
            var undoable = redoables.pop();
            undoables.add(undoable);
    <commit_msg>Added pop up with undoes in Scene Composer.<commit_after>package com.ray3k.skincomposer.dialog.scenecomposer;

import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.*;
import com.badlogic.gdx.utils.*;
import com.badlogic.gdx.utils.reflect.ClassReflection;
import com.badlogic.gdx.utils.reflect.ReflectionException;
import com.ray3k.skincomposer.Main;
import com.ray3k.skincomposer.data.ColorData;
import com.ray3k.skincomposer.data.DrawableData;
import com.ray3k.skincomposer.data.StyleData;
import com.ray3k.skincomposer.dialog.scenecomposer.DialogSceneComposer.View;
import com.ray3k.skincomposer.dialog.scenecomposer.DialogSceneComposerModel.Interpol;
import com.ray3k.skincomposer.dialog.scenecomposer.undoables.SceneComposerUndoable;

import java.util.Locale;

import static com.ray3k.skincomposer.dialog.scenecomposer.DialogSceneComposer.dialog;

public class DialogSceneComposerModel {
    private transient Main main;
    public transient Array<SceneComposerUndoable> undoables;
    public transient Array<SceneComposerUndoable> redoables;
    public static SimRootGroup rootActor;
    public transient Stack preview;
    private static Json json;
    private final static Vector2 temp = new Vector2();
    
    public enum Interpol {
        LINEAR(Interpolation.linear, "Linear", "linear"), SMOOTH(Interpolation.smooth, "Smooth", "smooth"), SMOOTH2(
                Interpolation.smooth2, "Smooth 2", "smooth2"),
        SMOOTHER(Interpolation.smoother, "Smoother", "smoother"), FADE(Interpolation.fade, "Fade", "fade"), POW2(
                Interpolation.pow2, "Pow 2", "pow2"),
        POW2IN(Interpolation.pow2In, "Pow 2 In", "pow2In"), SLOW_FAST(Interpolation.slowFast, "Slow Fast",
                "slowFast"), POW2OUT(Interpolation.pow2Out, "Pow 2 Out", "pow2Out"),
        FAST_SLOW(Interpolation.fastSlow, "Fast Slow", "fastSlow"), POW2IN_INVERSE(Interpolation.pow2In,
                "Pow 2 In Inverse", "pow2In"),
        POW2OUT_INVERSE(Interpolation.pow2OutInverse, "Pow 2 Out Inverse", "pow2OutInverse"), POW3(Interpolation.pow3,
                "Pow 3", "pow3"), POW3IN(Interpolation.pow3In, "Pow 3 In", "pow3In"),
        POW3OUT(Interpolation.pow3Out, "Pow 3 Out", "pow3Out"), POW3IN_INVERSE(Interpolation.pow3InInverse,
                "Pow 3 In Inverse", "pow3InInverse"),
        POW3OUT_INVERSE(Interpolation.pow3OutInverse, "Pow 3 Out Inverse", "pow3OutInverse"), POW4(Interpolation.pow4,
                "Pow 4", "pow4"), POW4IN(Interpolation.pow4In, "Pow 4 In", "pow4In"),
        POW4OUT(Interpolation.pow4Out, "Pow 4 Out", "pow4Out"), POW5(Interpolation.pow5, "Pow 5", "pow5"), POW5IN(
                Interpolation.pow5In, "Pow 5 In", "pow5In"),
        POW5OUT(Interpolation.pow5Out, "Pow 5 Out", "pow5Out"), SINE(Interpolation.sine, "Sine", "sine"), SINE_IN(
                Interpolation.sineIn, "Sine In", "sineIn"),
        SINE_OUT(Interpolation.sineOut, "Sine Out", "sineOut"), EXP10(Interpolation.exp10, "Exp 10", "exp10"), EXP10_IN(
                Interpolation.exp10In, "Exp 10 In", "exp10In"),
        EXP10_OUT(Interpolation.exp10Out, "Exp 10 Out", "exp10Out"), EXP5(Interpolation.exp5, "Exp 5", "exp5"), EXP5IN(
                Interpolation.exp5In, "Exp 5 In", "exp5In"),
        EXP5OUT(Interpolation.exp5Out, "Exp 5 Out", "exp5Out"), CIRCLE(Interpolation.circle, "Circle",
                "circle"), CIRCLE_IN(Interpolation.circleIn, "Circle In", "circleIn"),
        CIRCLE_OUT(Interpolation.circleOut, "Circle Out", "circleOut"), ELASTIC(Interpolation.elastic, "Elastic",
                "elastic"), ELASTIC_IN(Interpolation.elasticIn, "Elastic In", "elasticIn"),
        ELASTIC_OUT(Interpolation.elasticOut, "Elastic Out", "elasticOut"), SWING(Interpolation.swing, "Swing",
                "swing"), SWING_IN(Interpolation.swingIn, "Swing In", "swingIn"),
        SWING_OUT(Interpolation.swingOut, "Swing Out", "swingOut"), BOUNCE(Interpolation.bounce, "Bounce",
                "bounce"), BOUNCE_IN(Interpolation.bounceIn, "Bounce In", "bounceIn"),
        BOUNCE_OUT(Interpolation.bounceOut, " Bounce Out", "bounceOut");
        
        public Interpolation interpolation;
        public String text;
        public String code;
        
        Interpol(Interpolation interpolation, String text, String code) {
            this.interpolation = interpolation;
            this.text = text;
            this.code = code;
        }
    
        @Override
        public String toString() {
            return text;
        }
    }
    
    public DialogSceneComposerModel() {
        undoables = new Array<>();
        redoables = new Array<>();
        preview = new Stack();
        main = Main.main;
    
        json = new Json();
        json.setSerializer(ColorData.class, new Json.Serializer<>() {
            @Override
            public void write(Json json, ColorData object, Class knownType) {
                json.writeValue(object.getName());
            }

            @Override
            public ColorData read(Json json, JsonValue jsonData, Class type) {
                return Main.main.getJsonData().getColorByName(jsonData.asString());
            }
        });
        json.setSerializer(DrawableData.class, new Json.Serializer<>() {
            @Override
            public void write(Json json, DrawableData object, Class knownType) {
                json.writeValue(object.name);
            }

            @Override
            public DrawableData read(Json json, JsonValue jsonData, Class type) {
                return Main.main.getAtlasData().getDrawable(jsonData.asString());
            }
        });
        json.setSerializer(StyleData.class, new Json.Serializer<>() {
            @Override
            public void write(Json json, StyleData object, Class knownType) {
                json.writeObjectStart();
                json.writeValue("clazz", object.clazz.getName());
                json.writeValue("name", object.name);
                json.writeObjectEnd();
            }

            @Override
            public StyleData read(Json json, JsonValue jsonData, Class type) {
                try {
                    return Main.main.getJsonData().findStyle(ClassReflection.forName(jsonData.getString("clazz")), jsonData.getString("name"));
                } catch (ReflectionException e) {
                    e.printStackTrace();
                    return null;
                }
            }
        });
        json.setOutputType(JsonWriter.OutputType.json);
        json.setUsePrototypes(false);
        json.addClassTag("Actor", SimActor.class);
        json.addClassTag("Button", SimButton.class);
        json.addClassTag("Cell", SimCell.class);
        json.addClassTag("CheckBox", SimCheckBox.class);
        json.addClassTag("Container", SimContainer.class);
        json.addClassTag("HorizontalGroup", SimHorizontalGroup.class);
        json.addClassTag("Image", SimImage.class);
        json.addClassTag("ImageButton", SimImageButton.class);
        json.addClassTag("ImageTextButton", SimImageTextButton.class);
        json.addClassTag("Label", SimLabel.class);
        json.addClassTag("List", SimList.class);
        json.addClassTag("Node", SimNode.class);
        json.addClassTag("ProgressBar", SimProgressBar.class);
        json.addClassTag("Root", SimRootGroup.class);
        json.addClassTag("ScrollPane", SimScrollPane.class);
        json.addClassTag("SelectBox", SimSelectBox.class);
        json.addClassTag("Slider", SimSlider.class);
        json.addClassTag("SplitPane", SimSplitPane.class);
        json.addClassTag("Stack", SimStack.class);
        json.addClassTag("Table", SimTable.class);
        json.addClassTag("TextArea", SimTextArea.class);
        json.addClassTag("TextButton", SimTextButton.class);
        json.addClassTag("TextField", SimTextField.class);
        json.addClassTag("TouchPad", SimTouchPad.class);
        json.addClassTag("Tree", SimTree.class);
        json.addClassTag("VerticalGroup", SimVerticalGroup.class);
        
        if (rootActor == null) rootActor = new SimRootGroup();
        assignParentRecursive(rootActor);
    }
    
    public static void saveToJson(FileHandle saveFile) {
        if (!saveFile.extension().toLowerCase(Locale.ROOT).equals("json")) {
            saveFile = saveFile.sibling(saveFile.nameWithoutExtension() + ".json");
        }
        saveFile.writeString(json.prettyPrint(rootActor), false);
    }
    
    public static void loadFromJson(FileHandle loadFile) {
        rootActor = json.fromJson(SimRootGroup.class, loadFile);
        assignParentRecursive(rootActor);
    }
    
    public void undo() {
        if (undoables.size > 0) {
            var undoable = undoables.pop();
            redoables.add(undoable);
            
            undoable.undo();
            var fadeLabel = new FadeLabel(undoable.getUndoString(), main.getSkin(), "scene-edit-tip");
            temp.set(dialog.previewTable.getWidth() / 2, dialog.previewTable.getHeight() / 2);
            dialog.previewTable.localToStageCoordinates(temp);
            fadeLabel.setPosition(temp.x - (int) fadeLabel.getWidth() / 2, temp.y - (int) fadeLabel.getHeight() / 2);
            main.getStage().addActor(fadeLabel);
        }
    }
    
    public void redo() {
        if (redoables.size > 0) {
            var undoable = redoables.pop();
            undoables.add(undoable);
    
{'fraction_non_alphanumeric': 0.12334754222198241, 'fraction_numerical': 0.013057788809151243, 'mean_word_length': 2.841243523316062, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1922400', 'n_tokens_mistral': 5685, 'n_tokens_neox': 5520, 'n_words': 1016}