<commit_before>package com.marklalor.javasim.simulation;

import java.awt.Desktop;
import java.awt.FileDialog;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.Transferable;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

import com.apple.eawt.Application;
import com.apple.eawt.FullScreenUtilities;
import com.marklalor.javasim.JavaSim;
import com.marklalor.javasim.home.Home;
import com.marklalor.javasim.menu.menus.JavaSimMenu;
import com.marklalor.javasim.misc.MiscUtil;
import com.marklalor.javasim.misc.image.TransferableImage;
import com.marklalor.javasim.simulation.control.Control;
import com.marklalor.javasim.simulation.frames.FrameHolder;
import com.marklalor.javasim.simulation.frames.HomeHolder;
import com.marklalor.javasim.simulation.frames.subframes.Animate;
import com.marklalor.javasim.simulation.frames.subframes.Controls;
import com.marklalor.javasim.simulation.frames.subframes.Resize;
import com.marklalor.javasim.simulation.image.Image;
import com.marklalor.javasim.simulation.manager.play.PlayManager;
import com.marklalor.javasim.simulation.preset.BlankImageSimulation;

/**
 * <p>
 * Master simulation class, containing components such as the {@link SimulationInfo}, the {@link Image}, and the
 * {@link Controls}. A simulation subclass is responsible for implementing the {@link #initialize()}, {@link #reset()},
 * and {@link #draw(Graphics2D, Graphics2D)} methods.
 * </p>
 * <p>
 * For even more bare-bones implementations of a simulation, see presets such as {@link BlankImageSimulation}, which are
 * Simulations designed for simple target behavior, such as creating an image with a white background.
 * </p>
 * 
 * @see <a href = "https://github.com/MarkLalor/JavaSim#example">https://github.com/MarkLalor/JavaSim#example</a>
 * @see #initialize()
 * @see #reset()
 * @see #draw(Graphics2D, Graphics2D)
 */
public abstract class Simulation implements ClipboardOwner, HomeHolder
{
    public static final int DEFAULT_IMAGE_WIDTH = 500, DEFAULT_IMAGE_HEIGHT = 500;
    public static final int DEFAULT_CONTROL_WIDTH = 100, DEFAULT_CONTROL_HEIGHT = 500;
    
    private Home home;
    private SimulationInfo info;
    private Integer jarId;
    
    private File contentDirectory;
    
    private boolean fullscreen = false;
    
    //Controllers / Managers
    private PlayManager playManager;
    
    // Main Frames
    private Image image;
    private Controls controls;
    
    // Other Frames
    private Animate animate;
    private Resize resize;
    
    // Simulation abstract methods:
    
    /**
     * <p>
     * Called by {@link Home#run(Home, SimulationInfo)} when a simulation is ran via the home screen. This is called
     * after most of the core initialization is done by {@link #preInitialize(SimulationInfo)}. And before any
     * initialization-reliant tasks done in {@link #postInitialize()}. This is an appropriate time to do things such as:
     * </p>
     * <p>
     * <ul>
     * <li>initialize your own fields (like a regular constructor).</li>
     * <li>initialize JavaSim controls (see {@link Control}).</li>
     * <li>show, set size of, and set location of panels (e.g. {@link #getImage()}, {@link #getControls()}).</li>
     * </ul>
     * </p>
     * <p>
     * For clarification, this method is called in {@link Home#run(SimulationInfo)} like so:
     * 
     * <pre>
     * {@code
     * simulation.preInitialize(home, info);
     * simulation.initialize();
     * simulation.postInitialize();
     * simulation.resetAction();
     * }
     * </pre>
     * 
     * </p>
     */
    public abstract void initialize();
    
    public void preInitialize(Home home, Integer id, SimulationInfo info)
    {
        // Don't allow anyone to use this method a second time… just… no.
        if(getInfo() != null)
            throw new RuntimeException("Do not call method com.marklalor.javasim.simulation.Simulation#preInitialize more than once (it is called once automatically by JavaSim Home)");
        
        // Set the Home this simulation was launched from.
        this.home = home;
        
        this.jarId = id;
        
        // Inherit the info read from its file earlier.
        this.info = info;
        
        this.playManager = new PlayManager(this);
        
        // Set the simulation's content directory and (make sure it exists).
        contentDirectory = new File(getHome().getApplicationPreferences().getSaveDirectory(), info.getName());
        contentDirectory.mkdirs();
        
        // Create and set up the main image that goes with this simulation.
        image = new Image(this);
        image.setImageSize(DEFAULT_IMAGE_WIDTH, DEFAULT_IMAGE_HEIGHT);
        image.getFrame().setLocationRelativeTo(null);
        resolveTitle();
        
        // Create and set up the main control panel for this simulation.<commit_msg>Added support for the OS X document proxy icon.<commit_after>package com.marklalor.javasim.simulation;

import java.awt.Desktop;
import java.awt.FileDialog;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.Transferable;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;

import com.apple.eawt.Application;
import com.apple.eawt.FullScreenUtilities;
import com.marklalor.javasim.JavaSim;
import com.marklalor.javasim.home.Home;
import com.marklalor.javasim.menu.menus.JavaSimMenu;
import com.marklalor.javasim.misc.MiscUtil;
import com.marklalor.javasim.misc.image.TransferableImage;
import com.marklalor.javasim.simulation.control.Control;
import com.marklalor.javasim.simulation.frames.FrameHolder;
import com.marklalor.javasim.simulation.frames.HomeHolder;
import com.marklalor.javasim.simulation.frames.subframes.Animate;
import com.marklalor.javasim.simulation.frames.subframes.Controls;
import com.marklalor.javasim.simulation.frames.subframes.Resize;
import com.marklalor.javasim.simulation.image.Image;
import com.marklalor.javasim.simulation.manager.play.PlayManager;
import com.marklalor.javasim.simulation.preset.BlankImageSimulation;

/**
 * <p>
 * Master simulation class, containing components such as the {@link SimulationInfo}, the {@link Image}, and the
 * {@link Controls}. A simulation subclass is responsible for implementing the {@link #initialize()}, {@link #reset()},
 * and {@link #draw(Graphics2D, Graphics2D)} methods.
 * </p>
 * <p>
 * For even more bare-bones implementations of a simulation, see presets such as {@link BlankImageSimulation}, which are
 * Simulations designed for simple target behavior, such as creating an image with a white background.
 * </p>
 * 
 * @see <a href = "https://github.com/MarkLalor/JavaSim#example">https://github.com/MarkLalor/JavaSim#example</a>
 * @see #initialize()
 * @see #reset()
 * @see #draw(Graphics2D, Graphics2D)
 */
public abstract class Simulation implements ClipboardOwner, HomeHolder
{
    public static final int DEFAULT_IMAGE_WIDTH = 500, DEFAULT_IMAGE_HEIGHT = 500;
    public static final int DEFAULT_CONTROL_WIDTH = 100, DEFAULT_CONTROL_HEIGHT = 500;
    
    private Home home;
    private SimulationInfo info;
    private Integer jarId;
    
    private File contentDirectory;
    
    private boolean fullscreen = false;
    
    //Controllers / Managers
    private PlayManager playManager;
    
    // Main Frames
    private Image image;
    private Controls controls;
    
    // Other Frames
    private Animate animate;
    private Resize resize;
    
    // Simulation abstract methods:
    
    /**
     * <p>
     * Called by {@link Home#run(Home, SimulationInfo)} when a simulation is ran via the home screen. This is called
     * after most of the core initialization is done by {@link #preInitialize(SimulationInfo)}. And before any
     * initialization-reliant tasks done in {@link #postInitialize()}. This is an appropriate time to do things such as:
     * </p>
     * <p>
     * <ul>
     * <li>initialize your own fields (like a regular constructor).</li>
     * <li>initialize JavaSim controls (see {@link Control}).</li>
     * <li>show, set size of, and set location of panels (e.g. {@link #getImage()}, {@link #getControls()}).</li>
     * </ul>
     * </p>
     * <p>
     * For clarification, this method is called in {@link Home#run(SimulationInfo)} like so:
     * 
     * <pre>
     * {@code
     * simulation.preInitialize(home, info);
     * simulation.initialize();
     * simulation.postInitialize();
     * simulation.resetAction();
     * }
     * </pre>
     * 
     * </p>
     */
    public abstract void initialize();
    
    public void preInitialize(Home home, Integer id, SimulationInfo info)
    {
        // Don't allow anyone to use this method a second time… just… no.
        if(getInfo() != null)
            throw new RuntimeException("Do not call method com.marklalor.javasim.simulation.Simulation#preInitialize more than once (it is called once automatically by JavaSim Home)");
        
        // Set the Home this simulation was launched from.
        this.home = home;
        
        this.jarId = id;
        
        // Inherit the info read from its file earlier.
        this.info = info;
        
        this.playManager = new PlayManager(this);
        
        // Set the simulation's content directory and (make sure it exists).
        contentDirectory = new File(getHome().getApplicationPreferences().getSaveDirectory(), info.getName());
        contentDirectory.mkdirs();
        
        // Create and set up the main image that goes with this simulation.
        image = new Image(this);
        image.setImageSize(DEFAULT_IMAGE_WIDTH, DEFAULT_IMAGE_HEIGHT);
        image.getFrame().setLocationRelativeTo(null);
        image.getFrame().getRootPane().putClientProperty("Window.documentFile", getInfo().getFile());
        image.getFrame().getRootPane().putClientProperty("Window.documentModified", false);
        resolveTitle();
        
        // Create and set up the main control panel for this simulation.
{'fraction_non_alphanumeric': 0.10605778191985088, 'fraction_numerical': 0.003168685927306617, 'mean_word_length': 3.4398014067025238, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 47, 'https://': 4, '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': '4550365', 'n_tokens_mistral': 3192, 'n_tokens_neox': 3141, 'n_words': 865}