Package aba

Source Code of aba.AnimsBrowser_Ant$MemStatus

package aba;

import java.applet.Applet;
import java.applet.AudioClip;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.dnd.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.io.*;
import java.lang.ref.ReferenceQueue;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.security.*;
import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.TitledBorder;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.filechooser.FileFilter;
import net.sf.jiga.xtended.impl.Animation;
import net.sf.jiga.xtended.impl.Sprite;
import net.sf.jiga.xtended.impl.SpriteTransferHandler;
import net.sf.jiga.xtended.impl.game.*;
import net.sf.jiga.xtended.impl.game.editor.ModelAnimBrowser;
import net.sf.jiga.xtended.impl.game.editor.ModelBrowser;
import net.sf.jiga.xtended.impl.system.JXAenvUtils2;
import net.sf.jiga.xtended.impl.system.input.KeyEventWrapper;
import net.sf.jiga.xtended.kernel.*;
import net.sf.jiga.xtended.ui.*;
import org.jdesktop.swingx.JXPanel;
import org.jdesktop.swingx.JXTaskPane;
import org.jdesktop.swingx.JXTaskPaneContainer;

/**
* ActiveApplet sub-class to load animation browser. It uses Animation object as
* main thread. Double Buffering is implemented in refresh Timer. *
*/
public class AnimsBrowser_Ant implements net.sf.jiga.xtended.ui.Menu, AntApplet {

    public final static ResourceBundle rb = ResourceBundle.getBundle("aba.aba");
    public static String[] _playerActions = new String[]{};

    static {
        Enumeration<String> keys = rb.getKeys();
        TreeSet<String> actions = new TreeSet<String>();
        for (; keys.hasMoreElements();) {
            String k = keys.nextElement();
            if (k.startsWith("animsID") && !k.equals("animsID_default")) {
                actions.add(rb.getString(k));
            }
        }
        _playerActions = actions.toArray(_playerActions);
    }
    public static String _defaultAction = rb.getString("animsID_default");
    public static String _linkedModelsArray = rb.getString("linkedModelsArrayAttributeName");
    public static String _linkedModel = rb.getString("linkedModelAttributeName");
    private JTextField sw_chr_name;
    private JSpinner sw_chr_floor;
    private JSpinner sw_chr_dim_ext_w, sw_chr_dim_ext_h;
    private JSpinner sw_chr_dim_int_w, sw_chr_dim_int_h;
    MediaTracker mt;
    Model character;
    String spritesDir = null, sfxDir = null;
    HashSet listeners = new HashSet();
    Sprite offscreen;
    boolean swap = true;
    JLabel swap_str;
    boolean compress = false; //
    JLabel compress_str;    // components
    JLabel debug_cache_str, debug_render_str;
    JXTaskPane panel;
    JButton sw_mirror_orientation;
    JButton sw_refresh;
    JLabel sw_currentFile;
    FileChooserPane dirSelect;
    JButton sw_anim_input;
    JLabel sw_state;
    JPanel statusBarPanel;
    Led rLed, wLed;
    JLabel statusBarLabel;
    JProgressMemory statusBar;
    String format;
    ReferenceQueue refQueue = new ReferenceQueue();
    JButton sw_anim_add;
    Stack<Map<String, JComponent>> sw_anim_added_st = new Stack<Map<String, JComponent>>();
    Stack<Map<String, JComponent>> sw_anim_added_end = new Stack<Map<String, JComponent>>();
    Stack<Map<String, JComponent>> sw_sfx_added = new Stack<Map<String, JComponent>>();
    JButton sw_sfx_add;
    javax.swing.JTextField sw_anim_input_prefix, sw_anim_input_suffix, sw_sfx_input;
    ModelBrowser modelPanel;
    JScrollPane modelPanelSp;
    /*
     * Thread t_loadModelPanel = null;
     */
    JSplitPane splitCfgNModel, splitAnimNCfg;
    List<Action> refreshProps;
    private JPanel viewerPanel;
    javax.swing.Timer animator = null;

    /**
     * Applet initialization @discussion All Swing components are loaded and
     * added to applet content. A config panel is instanced throughout a new
     * JFrame.
     */
    public void init() throws HeadlessException {
        if (initialized) {
            ThreadWorks.Swing.invokeLater(new Runnable() {

                public void run() {
                    refreshSpot(new ActionEvent(this, hashCode(), "refresh"));
                }
            });
            return;
        }
        JMenuBar menu = new JMenuBar();
        JMenu helpMenu = getHelpActionMenu();
        menu.add(getActionMenu());
        menu.add(helpMenu);
        applet.setJMenuBar(menu);
        refreshProps = Collections.synchronizedList(new ArrayList<Action>());
        refreshProps.add(new AbstractAction("current file") {

            public void actionPerformed(ActionEvent e) {
                if (currentFile instanceof File) {
                    sw_currentFile.setText(currentFile.getPath() + (character instanceof Model ? (Boolean.TRUE.equals(character.getAttribute(ATTR_CUSTOMIZED)) ? " *" : "") : ""));
                } else {
                    sw_currentFile.setText("new Model *");
                }
                if (character instanceof Custom) {
                    if (character.getAttribute("lastModificationMillis") != null) {
                        sw_currentFile.setText(sw_currentFile.getText() + " (Modified on : " + String.format("%1$tD - %1$tT", character.getAttribute("lastModificationMillis")) + ") ");
                    }
                }
                sw_currentFile.repaint();
            }
        });
        applet.setLayout(new BorderLayout());
        applet.add(sw_currentFile = new JLabel(currentFile == null ? "new Model *" : currentFile.getPath(), UIMessage._getIcon(UIMessage.MODEL_TYPE, false), SwingConstants.CENTER), BorderLayout.NORTH);
        // model panel
        applet.add(splitCfgNModel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true), BorderLayout.CENTER);
        modelPanelSp = new JScrollPane();
        modelPanel = new ModelBrowser(_playerActions, _defaultAction, character, SpritesChar.HIGH, modelPanelSp, sw_state = new JLabel("No state"));
        modelPanel.setOnRefreshAction(action_customize_fileMask);
        splitCfgNModel.setRightComponent(modelPanelSp);
        JXTaskPaneContainer XContainer = new JXTaskPaneContainer();
        // controller panel
        JXPanel controller = new JXPanel(true);
        controller.setBorder(new TitledBorder(BorderFactory.createEtchedBorder(), "controller", TitledBorder.RIGHT, TitledBorder.TOP));
        controller.setLayout(new BorderLayout());
        statusBarPanel = new JPanel(true);
        statusBarPanel.setLayout(new GridBagLayout());
        GridBagConstraints cl = new GridBagConstraints();
        cl.fill = cl.BOTH;
        cl.weightx = cl.weighty = 1;
        cl.weightx = .5;
        statusBarPanel.add(statusBarLabel = new JLabel(UIMessage._getIcon(UIMessage.ENABLED_TYPE, false)), cl);
        cl.weightx = 1;
        statusBarPanel.add(statusBar = new JProgressMemory(0, 100), cl);
        JPanel ledPanel = new JPanel(new GridLayout(0, 1), true);
        ledPanel.add(rLed = new Led(Led.READ));
        ledPanel.add(wLed = new Led(Led.WRITE));
        cl.weightx = .5;
        statusBarPanel.add(ledPanel, cl);
        controller.add(statusBarPanel, BorderLayout.NORTH);
        ((JProgressMemory) statusBar).setLabels("CACHE", "HEAP", "");
        applet.add(controller, BorderLayout.SOUTH);        // config panel

        panel = new JXTaskPane();
        /*
         * panel.setCollapsed(false);
         */
        if (System.getProperty("os.name").startsWith("Linux")) {
            try {
                SpritesCacheManager.callback("setCollapsed", panel, new Object[]{false}, new Class[]{boolean.class});
            } catch (Exception e) {
                if (JXAenvUtils._debug) {
                    e.printStackTrace();
                }
            }
        } else {
            try {
                SpritesCacheManager.callback("setExpanded", panel, new Object[]{true}, new Class[]{boolean.class});
            } catch (Exception e) {
                if (JXAenvUtils._debug) {
                    e.printStackTrace();
                }
            }
        }

        XContainer.add(panel);
        // init data to config
        // maps config panel
        XContainer.add(modelPanel.panelMaps);
        XContainer.add(modelPanel.panelFX);
        // play panel
        JPanel panelPlay = new JPanel(new GridLayout(2, 0), true);
        final JXPanel paramFrame = new JXPanel(true);
        paramFrame.setBorder(new TitledBorder(BorderFactory.createEtchedBorder(), "Parameters config.", TitledBorder.RIGHT, TitledBorder.TOP));
        paramFrame.add(XContainer);
        viewerPanel = new JPanel(new BorderLayout(), true);
        viewerPanel.setPreferredSize(_iconSize);
        viewerPanel.add(new JLabel(UIMessage._getIcon(UIMessage.DROPTARGET_TYPE, false)), BorderLayout.CENTER);
        viewerPanel.validate();
        viewerPanel.setBorder(new TitledBorder(BorderFactory.createEtchedBorder(), "Let's drag'n'drop a Model here !", TitledBorder.LEFT, TitledBorder.TOP));
        DnDHandler dnd = new DnDHandler(this);
        dnd.addDropTarget(viewerPanel);
        JScrollPane sp2 = new JScrollPane(paramFrame);
        sp2.getHorizontalScrollBar().setUnitIncrement(30);
        sp2.getVerticalScrollBar().setUnitIncrement(30);
        splitAnimNCfg = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true);
        splitAnimNCfg.setBottomComponent(viewerPanel);
        splitAnimNCfg.setTopComponent(sp2);
        splitCfgNModel.setLeftComponent(splitAnimNCfg);
        splitAnimNCfg.setDividerLocation(500);
        panelPlay.add(sw_state);
        final AbstractAction action_play = new AbstractAction("(ALT+P)", UIMessage._getIcon(UIMessage.PLAYER_PLAY_TYPE, true)) {

            public void actionPerformed(ActionEvent e) {
                SortedMap<Integer, Animation> animations = character.accessSynchCache();
                Animation anim = animations.get(modelPanel.currentRecordKey.get(ModelAnimBrowser.CURRENTRECORDKEY));
                if (anim instanceof Animation) {
                    if (animator instanceof javax.swing.Timer) {
                        if (!animator.isRunning()) {
                            animator.start();
                        }
                    } else {
                        animator = new javax.swing.Timer((int) character.getFrameRate(), new ActionListener() {

                            public void actionPerformed(ActionEvent e) {
                                if (modelPanel.currentRecord.get(ModelAnimBrowser.CURRENTRECORD) instanceof JComponent) {
                                    JComponent comp = modelPanel.currentRecord.get(ModelAnimBrowser.CURRENTRECORD);
                                    comp.paintImmediately(0, 0, comp.getWidth(), comp.getHeight());
                                }
                            }
                        });
                        animator.start();
                    }
                    anim.play();
                }

                sw_state.setText(ModelAnimBrowser.animationState(anim instanceof Animation ? anim.getState() : -1));
            }
        };

        panelPlay.add(new JButton(action_play));
        panelPlay.add(new JButton(new AbstractAction("", UIMessage._getIcon(UIMessage.PLAYER_PAUSE_TYPE, true)) {

            public void actionPerformed(ActionEvent e) {
                SortedMap<Integer, Animation> animations = character.accessSynchCache();
                Animation anim = animations.get(modelPanel.currentRecordKey.get(ModelAnimBrowser.CURRENTRECORDKEY));
                if (anim instanceof Animation) {
                    anim.pause();
                    JComponent comp = modelPanel.currentRecord.get(ModelAnimBrowser.CURRENTRECORD);
                    if (comp instanceof JComponent) {
                        comp.repaint();
                    }
                    if (animator instanceof javax.swing.Timer) {
                        if (animator.isRunning()) {
                            animator.stop();
                        }
                    }

                }
                sw_state.setText(ModelAnimBrowser.animationState(anim instanceof Animation ? anim.getState() : -1));
            }
        }));
        panelPlay.add(new JButton(modelPanel.action_playSfx));
        panelPlay.add(new JButton(new AbstractAction("", UIMessage._getIcon(UIMessage.PLAYER_PREVIOUS_TYPE, true)) {

            public void actionPerformed(ActionEvent e) {
                SortedMap<Integer, Animation> animations = character.accessSynchCache();
                Animation anim = animations.get(modelPanel.currentRecordKey.get(ModelAnimBrowser.CURRENTRECORDKEY));
                if (anim instanceof Animation) {
                    anim.stop();
                    anim.rewind();
                    JComponent comp = modelPanel.currentRecord.get(ModelAnimBrowser.CURRENTRECORD);
                    if (comp instanceof JComponent) {
                        comp.repaint();
                    }
                    if (animator instanceof javax.swing.Timer) {
                        if (animator.isRunning()) {
                            animator.stop();
                        }
                    }
                }
                sw_state.setText(ModelAnimBrowser.animationState(anim instanceof Animation ? anim.getState() : -1));
                sw_state.repaint();
            }
        }));
        panelPlay.add(new JButton(new AbstractAction("", UIMessage._getIcon(UIMessage.PLAYER_FB_TYPE, true)) {

            public void actionPerformed(ActionEvent e) {
                SortedMap<Integer, Animation> animations = character.accessSynchCache();
                Animation anim = animations.get(modelPanel.currentRecordKey.get(ModelAnimBrowser.CURRENTRECORDKEY));
                if (anim instanceof Animation) {
                    anim.pause();
                    anim.position(Math.max(0, anim.getPosition() - 1));
                    JComponent comp = modelPanel.currentRecord.get(ModelAnimBrowser.CURRENTRECORD);
                    if (comp instanceof JComponent) {
                        comp.repaint();
                    }
                    if (animator instanceof javax.swing.Timer) {
                        if (animator.isRunning()) {
                            animator.stop();
                        }
                    }

                }
                sw_state.setText(ModelAnimBrowser.animationState(anim instanceof Animation ? anim.getState() : -1));
                sw_state.repaint();
            }
        }));
        panelPlay.add(new JButton(new AbstractAction("", UIMessage._getIcon(UIMessage.PLAYER_FF_TYPE, true)) {

            public void actionPerformed(ActionEvent e) {
                SortedMap<Integer, Animation> animations = character.accessSynchCache();
                Animation anim = animations.get(modelPanel.currentRecordKey.get(ModelAnimBrowser.CURRENTRECORDKEY));
                if (anim instanceof Animation) {
                    anim.pause();
                    anim.position(Math.min(anim.length() - 1, anim.getPosition() + 1));
                    JComponent comp = modelPanel.currentRecord.get(ModelAnimBrowser.CURRENTRECORD);
                    if (comp instanceof JComponent) {
                        comp.repaint();
                    }
                    if (animator instanceof javax.swing.Timer) {
                        if (animator.isRunning()) {
                            animator.stop();
                        }
                    }

                }
                sw_state.setText(ModelAnimBrowser.animationState(anim instanceof Animation ? anim.getState() : -1));
            }
        }));
        panelPlay.add(this.sw_refresh = new JButton("refresh", UIMessage._getIcon(UIMessage.REFRESH_TYPE, false)));
        sw_refresh.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent pe) {
                final ActionEvent e = pe;
                ThreadWorks.Swing.invokeLater(new Runnable() {

                    public void run() {
                        refreshSpot(e);
                    }
                });
            }
        });

        controller.add(panelPlay, BorderLayout.CENTER);
        // character customization params
        panel.add(action_switchResolution);

        panel.add(modelPanel.action_setBgColor);
        panel.add(new AbstractAction("load a demo/uncompleted model \n\r...") {

            public void actionPerformed(ActionEvent actionEvent) {
                Model s = getSpritesChar();
                if (s instanceof Model) {
                    character = s;
                    action_customize.actionPerformed(actionEvent);
                }
            }
        });
        panel.add(new AbstractAction("load the cache") {

            public void actionPerformed(ActionEvent e) {
                Runnable r = new Runnable() {

                    public void run() {
                        SpritesCacheManager<Integer, Animation> spm = character.accessCache();
                        spm.addSpritesCacheListener(scl);
                        character.addAccessAnimationCacheListener(rLed.getSpritesCacheAdapter());
                        character.addAccessAnimationCacheListener(wLed.getSpritesCacheAdapter());
                        character.loadResource();
                        spm.removeSpritesCacheListener(scl);
                        character.removeAccessAnimationCacheListener(rLed.getSpritesCacheAdapter());
                        character.removeAccessAnimationCacheListener(wLed.getSpritesCacheAdapter());
                    }
                };
                works.doLater(r);
            }
        });
        JXTaskPane panelCache = new JXTaskPane();
        if (System.getProperty("os.name").startsWith("Linux")) {
            try {
                SpritesCacheManager.callback("setCollapsed", panelCache, new Object[]{false}, new Class[]{boolean.class});
            } catch (Exception e) {
                if (JXAenvUtils._debug) {
                    e.printStackTrace();
                }
            }
        } else {
            try {
                SpritesCacheManager.callback("setExpanded", panelCache, new Object[]{true}, new Class[]{boolean.class});
            } catch (Exception e) {
                if (JXAenvUtils._debug) {
                    e.printStackTrace();
                }
            }
        }

        XContainer.add(panelCache);
        panelCache.setTitle("Cache");
        Action compressA;
        panelCache.add(compressA = new AbstractAction("compressed sprites") {

            public void actionPerformed(ActionEvent e) {
                compress = (compress) ? false : true;
                character.setCompressionEnabled(compress);
                compress_str.setText((compress) ? "enabled" : "disabled");
            }
        });
        refreshProps.add(new AbstractAction("compress") {

            public void actionPerformed(ActionEvent e) {
                character.setCompressionEnabled(compress);
            }
        });
        panelCache.add(compress_str = new JLabel((compress) ? "enabled" : "disabled"));
        panelCache.add(new AbstractAction("cache debugger") {

            public void actionPerformed(ActionEvent e) {
                DebugMap._getInstance().setDebuggerEnabled(!DebugMap._getInstance().isDebuggerEnabled(SpritesCacheManager.class), SpritesCacheManager.class);
                debug_cache_str.setText(DebugMap._getInstance().isDebuggerEnabled(SpritesCacheManager.class) ? "enabled" : "disabled");
            }
        });
        panelCache.add(debug_cache_str = new JLabel(DebugMap._getInstance().isDebuggerEnabled(SpritesCacheManager.class) ? "enabled" : "disabled"));
        panelCache.add(new AbstractAction("render debugger") {

            public void actionPerformed(ActionEvent e) {
                DebugMap._getInstance().setDebugLevelEnabled(!DebugMap._getInstance().isDebugLevelEnabled(RenderingScene.DBUG_RENDER), RenderingScene.DBUG_RENDER);
                debug_render_str.setText(DebugMap._getInstance().isDebugLevelEnabled(RenderingScene.DBUG_RENDER) ? "enabled" : "disabled");
            }
        });
        panelCache.add(debug_render_str = new JLabel(DebugMap._getInstance().isDebugLevelEnabled(RenderingScene.DBUG_RENDER) ? "enabled" : "disabled"));
        panel.add(modelPanel.action_openLog);

        // customize frame dialog
        customizeFrame = new JFrame("Customize your Model !");
        customizePanel = new JPanel(new GridBagLayout(), true);
        refreshProps.add(new AbstractAction("customize panel") {

            public void actionPerformed(ActionEvent e) {
                if (customizeFrame.isVisible()) {
                    customizePanel.repaint();
                }
            }
        });
        customizeScrollPane = new JScrollPane(customizePanel);
        customizeScrollPane.getHorizontalScrollBar().setUnitIncrement(30);
        customizeScrollPane.getVerticalScrollBar().setUnitIncrement(30);
        Container customizeFrame_content = customizeFrame.getContentPane();
        customizeFrame_content.removeAll();
        customizeFrame_content.setLayout(new BorderLayout());
        customizeFrame_content.add(new JButton(action_customize_ok), BorderLayout.SOUTH);
        customizeScrollPane.setPreferredSize(new Dimension(200, 200));
        JPanel customizeFrame_modelCfg = new JPanel(new GridBagLayout(), true);
        JSplitPane split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, customizeScrollPane, customizeFrame_modelCfg);
        customizeFrame_content.add(split, BorderLayout.CENTER);
        customizeFrame_modelCfg.setBorder(new TitledBorder(BorderFactory.createRaisedBevelBorder(), "customize"));
        GridBagConstraints c = new GridBagConstraints();
        c.fill = GridBagConstraints.BOTH;
        c.gridwidth = GridBagConstraints.RELATIVE;
        GridBagConstraints cr = (GridBagConstraints) c.clone();
        cr.gridwidth = GridBagConstraints.REMAINDER;
        customizeFrame_modelCfg.add(customize_fileMask_lab = new JLabel("file name mask : -"), cr);
        customizeFrame_modelCfg.add(new JButton(action_switchResolution), c);
        customizeFrame_modelCfg.add(sw_anim_input = new JButton(action_setDirectory), cr);
        customizeFrame_modelCfg.add(new JLabel("model name :"), c);
        customizeFrame_modelCfg.add(sw_chr_name = new JTextField("myModel"), cr);
        sw_chr_name.getDocument().addDocumentListener(new DocumentListener() {

            public void insertUpdate(DocumentEvent e) {
                action_customize_fileMask.actionPerformed(new ActionEvent(e.getDocument(), e.getType().hashCode(), e.getType().toString()));
            }

            public void removeUpdate(DocumentEvent e) {
                action_customize_fileMask.actionPerformed(new ActionEvent(e.getDocument(), e.getType().hashCode(), e.getType().toString()));
            }

            public void changedUpdate(DocumentEvent e) {
                action_customize_fileMask.actionPerformed(new ActionEvent(e.getDocument(), e.getType().hashCode(), e.getType().toString()));
            }
        });
        sw_chr_name.setDragEnabled(true);
        customizeFrame_modelCfg.add(
                new JLabel("Distance from the floor to first pixel of image (px) :"), c);
        customizeFrame_modelCfg.add(sw_chr_floor = new JSpinner(new SpinnerNumberModel(0, 0, 1000, 1)), cr);
        customizeFrame_modelCfg.add(
                new JLabel("External dimensions of the sprites images (px) WIDTH:"), c);
        customizeFrame_modelCfg.add(sw_chr_dim_ext_w = new JSpinner(new SpinnerNumberModel(0, 0, 2000, 1)), cr);
        customizeFrame_modelCfg.add(
                new JLabel("External dimensions of the sprites images (px) HEIGHT:"), c);
        customizeFrame_modelCfg.add(sw_chr_dim_ext_h = new JSpinner(new SpinnerNumberModel(0, 0, 2000, 1)), cr);
        customizeFrame_modelCfg.add(
                new JLabel("Internal dimensions of the sprites in the images (px) WIDTH:"), c);
        customizeFrame_modelCfg.add(sw_chr_dim_int_w = new JSpinner(new SpinnerNumberModel(0, 0, 2000, 1)), cr);
        customizeFrame_modelCfg.add(
                new JLabel("Internal dimensions of the sprites in the images (px) HEIGHT:"), c);
        customizeFrame_modelCfg.add(sw_chr_dim_int_h = new JSpinner(new SpinnerNumberModel(0, 0, 2000, 1)), cr);
        customizeFrame_modelCfg.add(
                new JLabel("Input custom prefix :"), c);
        customizeFrame_modelCfg.add(sw_anim_input_prefix = new JTextField(), cr);
        sw_anim_input_prefix.setDragEnabled(true);
        sw_anim_input_prefix.getDocument().addDocumentListener(new DocumentListener() {

            public void insertUpdate(DocumentEvent e) {
                action_customize_fileMask.actionPerformed(new ActionEvent(e.getDocument(), e.getType().hashCode(), e.getType().toString()));
            }

            public void removeUpdate(DocumentEvent e) {
                action_customize_fileMask.actionPerformed(new ActionEvent(e.getDocument(), e.getType().hashCode(), e.getType().toString()));
            }

            public void changedUpdate(DocumentEvent e) {
                action_customize_fileMask.actionPerformed(new ActionEvent(e.getDocument(), e.getType().hashCode(), e.getType().toString()));
            }
        });

        customizeFrame_modelCfg.add(new JLabel("Input custom suffix :"), c);
        customizeFrame_modelCfg.add(sw_anim_input_suffix = new JTextField(), cr);
        sw_anim_input_suffix.setDragEnabled(true);
        sw_anim_input_suffix.getDocument().addDocumentListener(new DocumentListener() {

            public void insertUpdate(DocumentEvent e) {
                action_customize_fileMask.actionPerformed(new ActionEvent(e.getDocument(), e.getType().hashCode(), e.getType().toString()));
            }

            public void removeUpdate(DocumentEvent e) {
                action_customize_fileMask.actionPerformed(new ActionEvent(e.getDocument(), e.getType().hashCode(), e.getType().toString()));
            }

            public void changedUpdate(DocumentEvent e) {
                action_customize_fileMask.actionPerformed(new ActionEvent(e.getDocument(), e.getType().hashCode(), e.getType().toString()));
            }
        });
        JLabel someLab;
        cr.weightx = 2;
        customizeFrame_modelCfg.add(someLab = new JLabel("To make a custom Model : "), cr);
        customizeFrame_modelCfg.add(sw_anim_add = new JButton("Add new animation +"), cr);
        sw_anim_add.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent actionEvent) {
                customizeAddNewAnimationField(0, 0);
            }
        });
        customizeFrame_modelCfg.add(sw_sfx_add = new JButton("Add new sfx +"), cr);
        sw_sfx_add.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent actionEvent) {
                customizeAddNewSfxField("sfx file name.wav|aif|mp3");
            }
        });
        JButton sw_action_bg, sw_action_nobg;
        customizeFrame_modelCfg.add(sw_action_bg = new JButton(action_setlinkedModelsArrayModelsFiles), cr);
        sw_action_bg.setToolTipText("<html>Existing " + _linkedModelsArray + " Model's can be stored " + "<br>in the Model attributes when saving it, " + "<br>and can be retriven with " + "<br>the attribute (Model).getAttribute(\"" + _linkedModelsArray + "\").</html>");
        customizeFrame_modelCfg.add(sw_action_nobg = new JButton(action_unsetlinkedModelsArrayModelsFiles), cr);
        customizeFrame_modelCfg.add(sw_linkedModelsArrayModelsFiles, cr);
        JButton sw_action_dgb, sw_action_nodgb, sw_action_sis;
        customizeFrame_modelCfg.add(sw_action_dgb = new JButton(action_setlinkedModelFile), cr);
        sw_action_dgb.setToolTipText("<html>Existing " + _linkedModel + " Model can be stored " + "<br>in the Model attributes map when saving it," + "<br> and can be retriven with " + "<br>the attribute \"" + _linkedModel + "\".</html>");
        customizeFrame_modelCfg.add(sw_action_nodgb = new JButton(action_unsetlinkedModelFile), cr);
        customizeFrame_modelCfg.add(sw_linkedModelFile, cr);
        JPanel panelIconPanel = new JPanel(new BorderLayout(), true);
        panelIconPanel.add(new JLabel("drag'n'drop a picture >"), BorderLayout.WEST);
        panelIconPanel.add(iconPanel, BorderLayout.CENTER);
        customizeFrame_modelCfg.add(panelIconPanel, cr);
        iconPanel.setDropTarget(new DropTarget(iconPanel, dtl));
        iconPanel.setTransferHandler(net.sf.jiga.xtended.impl.Sprite._newTransferHandler());

        customizeFrame_modelCfg.add(sw_action_sis = new JButton(action_setIconSprite), cr);
        customizeFrame.setLocationRelativeTo(applet);
        customizeFrame.pack();
        // Keyboard
        KeyEventDispatcher ked = new KeyEventDispatcher() {

            public boolean dispatchKeyEvent(KeyEvent e) {
                if (JXAenvUtils._debug) {
                    System.out.println("AnimsBrowser_Ant dispatched KeyEvent");
                }
                if (e.getID() == KeyEvent.KEY_PRESSED) {
                    if (e.getModifiers() == Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()) {
                        switch (e.getKeyCode()) {
                            case KeyEvent.VK_P:
                                action_play.actionPerformed(new ActionEvent(e, e.hashCode(), e.toString()));
                                return true;
                            case KeyEvent.VK_ESCAPE:
                                action_cancel.actionPerformed(new ActionEvent(e, e.hashCode(), e.toString()));
                                return true;
                            default:
                                break;
                        }
                    }
                }
                return false;
            }
        };
        KeyboardFocusManager.getCurrentKeyboardFocusManager().addKeyEventDispatcher(ked);
        modelPanel.action_setResolution.actionPerformed(new ActionEvent(this, hashCode(), modelPanel.action_setResolution.getValue(Action.NAME).toString()));
        action_setDirectory.actionPerformed(new ActionEvent(this, hashCode(), action_setDirectory.getValue(Action.NAME).toString()));
        initialized = true;

        applet.validate();
        ThreadWorks.Swing.invokeLater(new Runnable() {

            public void run() {
                refreshSpot(new ActionEvent(this, hashCode(), "refresh"));
            }
        });
    }
    private AbstractAction action_customize_ok = new AbstractAction("Apply", UIMessage._getIcon(UIMessage.STORE_TYPE, false)) {

        public void actionPerformed(ActionEvent pe) {
            final ActionEvent e = pe;
            final Runnable r = new Runnable() {

                public void run() {
                    switch (UIMessage.showConfirmDialog(customizeFrame, "Apply the specified values to the current Model ?", "Apply?", JOptionPane.OK_CANCEL_OPTION)) {
                        case JOptionPane.OK_OPTION:
                            character = (Model) applyCustomizedModelData(Model._dataFlavor);
                            character.setAttribute(ATTR_CUSTOMIZED, true);
                            customizeFrame.setVisible(false);
                            ThreadWorks.Swing.invokeLater(new Runnable() {

                                public void run() {
                                    reset(e);
                                }
                            });
                            break;
                        case JOptionPane.CANCEL_OPTION:
                            break;
                        default:
                            break;

                    }
                }
            };
            works.doLater(new Runnable() {

                public void run() {
                    try {
                        ThreadWorks.Swing.invokeAndWait(r);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    } catch (InvocationTargetException ex) {
                        ex.printStackTrace();
                    }
                }
            });
        }
    };
    private Action action_modelPanel = new AbstractAction("load the animations interactive panel...", UIMessage._getIcon(UIMessage.INPUT_TYPE, true)) {

        public void actionPerformed(ActionEvent e) {
            Runnable r = new Runnable() {

                public void run() {
                    character.accessCache().addSpritesCacheListener(scl);
                    character.accessCache().addSpritesCacheListener(rLed.getSpritesCacheAdapter());
                    character.accessCache().addSpritesCacheListener(wLed.getSpritesCacheAdapter());
                    character.addAccessAnimationCacheListener(rLed.getSpritesCacheAdapter());
                    character.addAccessAnimationCacheListener(wLed.getSpritesCacheAdapter());
                    character.addAccessAnimationIIOReadListener(rLed.getIIOReadProgressAdapter());
                    character.addAccessAnimationIIOWriteListener(wLed.getIIOWriteProgressAdapter());
                    statusBarLabel.setIcon(UIMessage._getIcon(UIMessage.WAIT_TYPE, false));
                    modelPanel.switchModel(character);
                    modelPanel.loadResource();
                    statusBarLabel.setIcon(UIMessage._getIcon(UIMessage.ENABLED_TYPE, false));
                }
            };
            works.doLater(r);
        }
    };
    private Action action_reset = new AbstractAction("reset", UIMessage._getIcon(UIMessage.REFRESH_TYPE, true)) {

        public void actionPerformed(final ActionEvent actionEvent) {
            ThreadWorks.Swing.invokeLater(new Runnable() {

                public void run() {
                    reset(actionEvent);
                }
            });
        }
    };
    File iconFile = null;
    JComponent sw_icon;
    public static Dimension _iconSize = new Dimension(64, 64);
    JPanel iconPanel = new JPanel(new GridBagLayout(), true);
    final DropTargetListener dtl = new DropTargetAdapter() {

        @Override
        public void dragExit(DropTargetEvent dte) {
            super.dragExit(dte);
            iconPanel.setCursor(Cursor.getDefaultCursor());
        }

        @Override
        public void dragOver(DropTargetDragEvent dtde) {
            int dropAct = dtde.getDropAction();
            if (JXAenvUtils._debug) {
                System.err.println("DROPEVENT : " + dtde.getDropAction());
            }
            iconPanel.setCursor(dropAct == java.awt.dnd.DnDConstants.ACTION_LINK || dropAct == java.awt.dnd.DnDConstants.ACTION_COPY || dropAct == java.awt.dnd.DnDConstants.ACTION_MOVE || dropAct == java.awt.dnd.DnDConstants.ACTION_COPY_OR_MOVE ? DragSource.DefaultCopyDrop : Cursor.getDefaultCursor());
            iconPanel.setToolTipText("please drop here !");
        }

        public void drop(DropTargetDropEvent dtde) {
            dtde.acceptDrop(java.awt.dnd.DnDConstants.ACTION_COPY);
            if (dtde instanceof DropTargetDropEvent) {
                if (iconPanel.getTransferHandler().importData(iconPanel, dtde.getTransferable())) {
                    Sprite[] imported = ((SpriteTransferHandler) iconPanel.getTransferHandler()).getTransferedData();
                    if (imported != null) {
                        if (imported.length > 0) {
                            try {
                                imported[0].runValidate();
                                sw_icon = (JComponent) Display._Display(imported[0].getImage(iconPanel), null, _iconSize);
                                iconFile = new File("icon.png");
                                imported[0].writeImageToOutput(iconFile, .8f);
                                updateIconPanel();
                                customizeFrame.pack();
                                customizeFrame.repaint();
                            } catch (Exception ex) {
                                if (JXAenvUtils._debug) {
                                    ex.printStackTrace();
                                }
                            }
                        }
                    }
                    dtde.dropComplete(true);
                } else {
                    dtde.dropComplete(false);
                }
            }
            iconPanel.setCursor(Cursor.getDefaultCursor());

        }
    };

    private void disableModelIcon() {
        iconFile = null;
        try {
            sw_icon = (JComponent) Display._Display(Display.class.getResource("/net/sf/jiga/xtended/ui/images/dialog_disabled.gif"), null, new Dimension(32, 32));
        } catch (IOException ex) {
            if (JXAenvUtils._debug) {
                ex.printStackTrace();
            }
        } catch (URISyntaxException ex) {
            if (JXAenvUtils._debug) {
                ex.printStackTrace();
            }
        } finally {
            updateIconPanel();
        }
    }

    private void updateIconPanel() {
        iconPanel.removeAll();
        if (sw_icon != null) {
            GridBagConstraints c = new GridBagConstraints();
            c.fill = c.BOTH;
            iconPanel.add(sw_icon, c);
        }
        iconPanel.revalidate();
        iconPanel.repaint();
    }
    private AbstractAction action_setIconSprite = new AbstractAction("set an icon for the model") {

        public void actionPerformed(final ActionEvent e) {
            AccessController.doPrivileged(new PrivilegedAction() {

                public Object run() {
                    _actionPerformed(e);
                    return null;
                }
            }, acc);
        }

        private void _actionPerformed(ActionEvent e) {
            FileChooserPane fcp = new FileChooserPane(panel, spritesDir = (spritesDir == null) ? "." : spritesDir);
            fcp.setModeOpen(true);
            fcp.setMultiSelectionEnabled(false);
            fcp.getFiles().addChoosableFileFilter(new ExampleFileFilter(new String[]{"jpg", "gif", "png", "bmp"}, Sprite._dataFlavor.getHumanPresentableName()));
            File[] f = fcp.getFile();
            if (f.length > 0) {
                Throwable error = null;
                try {
                    iconFile = f[0];
                    sw_icon = Display._Display(iconFile.getPath(), null, new Dimension(32, 32)).getJComponentDisplay();
                    updateIconPanel();
                } catch (Exception ex) {
                    ex.printStackTrace();
                    error = ex;
                } finally {
                    if (error instanceof Throwable) {
                        disableModelIcon();
                        new UIMessage(true, error, null, UIMessage.ERROR_TYPE);
                    }
                }
            } else {
                disableModelIcon();
            }
            customizeFrame.pack();
            customizeFrame.repaint();
        }
    };
    File linkedModelFile = null;
    JLabel sw_linkedModelFile = new JLabel("model file is : " + linkedModelFile);
    private AbstractAction action_setlinkedModelFile = new AbstractAction("associate a \"" + _linkedModel + "\" Model...", UIMessage._getIcon(UIMessage.MODEL_TYPE, true)) {

        public void actionPerformed(ActionEvent e) {
            FileChooserPane fcp = new FileChooserPane(panel, spritesDir = (spritesDir == null) ? "." : spritesDir);
            fcp.setModeOpen(true);
            fcp.setMultiSelectionEnabled(false);
            fcp.getFiles().addChoosableFileFilter(new ExampleFileFilter(Model._MIME_EXT, Model._dataFlavor.getHumanPresentableName()));
            fcp.getFiles().addChoosableFileFilter(new ExampleFileFilter(XtendedModel._MIME_EXT, XtendedModel._dataFlavor.getHumanPresentableName()));
            File[] f = fcp.getFile();
            if (f.length > 0) {
                linkedModelFile = f[0];
            }
            sw_linkedModelFile.setText("model file is : " + linkedModelFile);
            customizeFrame.repaint();
        }
    };
    private AbstractAction action_unsetlinkedModelFile = new AbstractAction("no \"" + _linkedModel + "\"") {

        public void actionPerformed(ActionEvent e) {
            linkedModelFile = null;
            sw_linkedModelFile.setText("model file is : " + linkedModelFile);
            customizeFrame.repaint();
        }
    };
    File[] linkedModelsArrayModelsFiles = null;
    JLabel sw_linkedModelsArrayModelsFiles = new JLabel("models files are : " + linkedModelsArrayModelsFiles);
    private AbstractAction action_setlinkedModelsArrayModelsFiles = new AbstractAction("associate " + _linkedModelsArray + "Model's...", UIMessage._getIcon(UIMessage.MODEL_TYPE, true)) {

        public void actionPerformed(ActionEvent e) {
            FileChooserPane fcp = new FileChooserPane(panel, spritesDir = (spritesDir == null) ? "." : spritesDir);
            fcp.setModeOpen(true);
            fcp.setMultiSelectionEnabled(true);
            fcp.getFiles().addChoosableFileFilter(new ExampleFileFilter(Model._MIME_EXT, Model._dataFlavor.getHumanPresentableName()));
            fcp.getFiles().addChoosableFileFilter(new ExampleFileFilter(XtendedModel._MIME_EXT, XtendedModel._dataFlavor.getHumanPresentableName()));
            File[] f = fcp.getFile();
            if (f.length > 0) {
                linkedModelsArrayModelsFiles = f;
            }
            sw_linkedModelsArrayModelsFiles.setText("models files are : " + linkedModelsArrayModelsFiles);
            customizeFrame.repaint();
        }
    };
    private AbstractAction action_unsetlinkedModelsArrayModelsFiles = new AbstractAction("no " + _linkedModelsArray) {

        public void actionPerformed(ActionEvent e) {
            linkedModelsArrayModelsFiles = null;
            sw_linkedModelsArrayModelsFiles.setText("models files are : " + linkedModelsArrayModelsFiles);
            customizeFrame.repaint();
        }
    };
    private AbstractAction action_setDirectory = new AbstractAction("set up model root directory (excl. the model name)...", UIMessage._getIcon(UIMessage.SEARCH_TYPE, true)) {

        public void actionPerformed(ActionEvent e) {
            String[] result = getDirectory();
            spritesDir = result[0];
            sfxDir = spritesDir + File.separator + "sfx";
            action_customize_fileMask.actionPerformed(e);
        }
    };
    private JFrame customizeFrame;
    private JScrollPane customizeScrollPane;
    private JPanel customizePanel;
    private String customize_fileMask = "";
    private JLabel customize_fileMask_lab;
    private Action action_customize_fileMask = new AbstractAction() {

        public void actionPerformed(ActionEvent e) {
            customize_fileMask = spritesDir + File.separator + sw_chr_name.getText() + File.separator + Model.RES_PATHS_map.get(modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION)) + File.separator + sw_anim_input_prefix.getText() + "XXXXX" + sw_anim_input_suffix.getText() + Model.RES_EXT_map.get(modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION));
            customize_fileMask_lab.setText("file name mask : " + customize_fileMask);
            customize_fileMask_lab.setToolTipText("sound files are gathered from " + sfxDir);
            customize_fileMask_lab.repaint();
        }
    };

    private void customizeAddNewSfxField(String sfx) {
        GridBagConstraints c = new GridBagConstraints();
        final Map<String, JComponent> map = new HashMap<String, JComponent>();
        sw_sfx_added.push(map);
        map.put("JButton", new JButton(new AbstractAction("", UIMessage._getIcon(UIMessage.DELETE_TYPE, true)) {

            public void actionPerformed(ActionEvent e) {
                for (JComponent comp : map.values()) {
                    customizePanel.remove(comp);
                }

                sw_sfx_added.remove(map);
                customizeScrollPane.validate();
                customizeScrollPane.repaint();
            }
        }));
        customizePanel.add(map.get("JButton"));
        map.put("JTextField", new JTextField(sfx));
        customizePanel.add(map.get("JTextField"));
        ((JTextField) map.get("JTextField")).setDragEnabled(true);
        c.weightx = 3;
        c.fill = GridBagConstraints.HORIZONTAL;
        ((GridBagLayout) customizePanel.getLayout()).setConstraints(map.get("JTextField"), c);
        c.gridwidth = GridBagConstraints.REMAINDER;
        c.weightx = 1;
        map.put("JButtonPlay", new JButton(new AbstractAction("play the sound") {

            public void actionPerformed(ActionEvent e) {
                JTextField jtx = (JTextField) map.get("JTextField");
                if (jtx instanceof JTextField) {
                    try {
                        File f = new File(sfxDir + File.separator + jtx.getText());
                        AudioClip au = Applet.newAudioClip(f.toURL());
                        au.play();
                    } catch (MalformedURLException ex) {
                        if (JXAenvUtils._debug) {
                            ex.printStackTrace();
                        }
                        new UIMessage(true, ex, null, UIMessage.ERROR_TYPE);
                    }

                }
            }
        }));
        customizePanel.add(map.get("JButtonPlay"));
        ((GridBagLayout) customizePanel.getLayout()).setConstraints(map.get("JButtonPlay"), c);
        customizeScrollPane.validate();
        customizeScrollPane.getVerticalScrollBar().setValue(customizeScrollPane.getVerticalScrollBar().getMaximum() - customizeScrollPane.getVerticalScrollBar().getVisibleAmount());
        map.get("JTextField").requestFocusInWindow();
        customizeScrollPane.repaint();
    }

    private void clearCustomizedFieldsStacks() {
        Stack[] stacks = new Stack[]{sw_anim_added_st, sw_anim_added_end, sw_sfx_added};
        for (Stack<Map<String, JComponent>> stack : stacks) {
            synchronized (stack) {
                for (Iterator<Map<String, JComponent>> map = stack.iterator(); map.hasNext();) {
                    for (JComponent comp : map.next().values()) {
                        customizePanel.remove(comp);
                    }

                    map.remove();
                }

            }
        }
        customizeScrollPane.validate();
        customizeFrame.repaint();
    }

    private void customizeAddNewAnimationField(int start, int end) {
        GridBagConstraints c = new GridBagConstraints();
        final Map<String, JComponent> mapS = new HashMap<String, JComponent>();
        final Map<String, JComponent> mapE = new HashMap<String, JComponent>();
        mapS.put("JButton", new JButton(new AbstractAction("", UIMessage._getIcon(UIMessage.DELETE_TYPE, true)) {

            public void actionPerformed(ActionEvent e) {
                for (JComponent comp : mapS.values()) {
                    customizePanel.remove(comp);
                }

                for (JComponent comp : mapE.values()) {
                    customizePanel.remove(comp);
                }

                sw_anim_added_st.remove(mapS);
                sw_anim_added_end.remove(mapE);
                customizeScrollPane.validate();
                customizeScrollPane.repaint();
            }
        }));
        customizePanel.add(mapS.get("JButton"));
        mapS.put("JLabel", new JLabel("Animation start"));
        customizePanel.add(mapS.get("JLabel"));
        mapS.put("JSpinner", new JSpinner(new SpinnerNumberModel(start, 0, 100000, 1)));
        customizePanel.add(mapS.get("JSpinner"));
        sw_anim_added_st.push(mapS);
        mapE.put("JLabel", new JLabel("Animation end"));
        customizePanel.add(mapE.get("JLabel"));
        mapE.put("JSpinner", new JSpinner(new SpinnerNumberModel(end, 0, 100000, 1)));
        customizePanel.add(mapE.get("JSpinner"));
        sw_anim_added_end.push(mapE);
        c.gridwidth = 1;
        c.fill = GridBagConstraints.HORIZONTAL;
        ((GridBagLayout) customizePanel.getLayout()).setConstraints(mapS.get("JSpinner"), c);
        c.gridwidth = GridBagConstraints.REMAINDER;
        ((GridBagLayout) customizePanel.getLayout()).setConstraints(mapE.get("JSpinner"), c);
        customizeScrollPane.validate();
        customizeScrollPane.getVerticalScrollBar().setValue(customizeScrollPane.getVerticalScrollBar().getMaximum() - customizeScrollPane.getVerticalScrollBar().getVisibleAmount());
        mapS.get("JSpinner").requestFocusInWindow();
        customizeScrollPane.repaint();
    }
    ThreadWorks works = new ThreadWorks("aba-threads");
    private Action action_customize = new AbstractAction("customize character...", UIMessage._getIcon(UIMessage.INPUT_TYPE, true)) {

        public void actionPerformed(ActionEvent pe) {
            final ActionEvent e = pe;
            final Runnable r = new Runnable() {

                public void run() {
                    GridBagConstraints c = new GridBagConstraints();
                    Custom character = (Custom) AnimsBrowser_Ant.this.character;
                    if (character.id != null) {
                        int slash = character.id.lastIndexOf(File.separator);
                        sw_chr_name.setText(character.id.substring(slash == -1 ? 0 : slash + 1));
                    }

                    sw_chr_floor.setValue(character.getFloorDiff(modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION)));
                    sw_chr_dim_ext_h.setValue(character.getHeight(modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION)));
                    sw_chr_dim_ext_w.setValue(character.getWidth(modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION)));
                    if (character.spriteSize != null) {
                        sw_chr_dim_int_w.setValue(character.getInsetSize(modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION)).width);
                        sw_chr_dim_int_h.setValue(character.getInsetSize(modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION)).height);
                    }

                    clearCustomizedFieldsStacks();
                    if (character.frames != null) {
                        for (int[] anim : character.frames) {
                            customizeAddNewAnimationField(anim[0], anim[1]);
                        }

                    }
                    if (character.sfx != null) {
                        for (String sfx : character.sfx) {
                            int slash = sfx.lastIndexOf(File.separator);
                            customizeAddNewSfxField(sfx.substring(slash == -1 ? 0 : slash + 1));
                        }

                    }
                    sw_anim_input_prefix.setText(character.prefix);
                    sw_anim_input_suffix.setText(character.suffix);
                    customize_fileMask = character.getPath(false, modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION)) + character.prefix + "XXXXX" + character.suffix + Model.RES_EXT_map.get(modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION));
                    action_customize_fileMask.actionPerformed(e);
                    customizeScrollPane.validate();
                    customizeFrame.setVisible(true);
                    customizeFrame.repaint();
                }
            };
            works.doLater(new Runnable() {

                public void run() {
                    try {
                        ThreadWorks.Swing.invokeAndWait(r);
                    } catch (InterruptedException ex) {
                        ex.printStackTrace();
                    } catch (InvocationTargetException ex) {
                        ex.printStackTrace();
                    }
                }
            });
        }
    };

    private Action action_switchResolution = new AbstractAction("switch resolution...") {

        public void actionPerformed(ActionEvent e) {
            modelPanel.action_setResolution.actionPerformed(e);
            switch (UIMessage.showConfirmDialog(customizeFrame, "Do you want to update the dimensions to the new selected resolution ?", "Update ?", JOptionPane.YES_NO_OPTION)) {
                case JOptionPane.NO_OPTION:
                    action_customize_ok.actionPerformed(e);
                    break;
                case JOptionPane.YES_OPTION:
                    action_customize.actionPerformed(e);
                    break;
                default:
                    break;

            }
        }
    };

    private void copyCustomMappings(Custom custom) {
        int i = 0;
        for (List<String> animNames : modelPanel.animsID.get(ModelAnimBrowser.ATT_ANIMSID)) {
            if (animNames instanceof List) {
                for (String animName : animNames) {
                    custom.addAnimMap(animName, i);
                }
            }
            i++;
        }
        i = 0;
        for (List<String> animNames : modelPanel.sfxID.get(ModelAnimBrowser.ATT_SFXID)) {
            if (animNames instanceof List) {
                for (String animName : animNames) {
                    custom.addSoundMap(animName, i);
                }
            }
            i++;
        }
        custom.reversedAnims = modelPanel.reversedAnims.get(ModelAnimBrowser.ATT_REVERSEDANIMS).toArray(new String[]{});
        if (modelPanel.locations_map != null) {
            custom.setAttribute(ModelAnimBrowser.LOCATIONS, (Serializable) modelPanel.locations_map);
        }
        if (modelPanel.collisionsDef_map != null) {
            custom.setAttribute(ModelAnimBrowser.COLLISIONSDEF, (Serializable) modelPanel.collisionsDef_map);
        }
        if (modelPanel.collisionsAtk_map != null) {
            custom.setAttribute(ModelAnimBrowser.COLLISIONSATK, (Serializable) modelPanel.collisionsAtk_map);
        }
    }

    private Custom applyCustomizedModelData(DataFlavor flavor) {
        int[][] newFrames = new int[sw_anim_added_st.size()][2];
        int i = 0;
        for (Map<String, JComponent> start : sw_anim_added_st) {
            newFrames[i][0] = ((SpinnerNumberModel) ((JSpinner) start.get("JSpinner")).getModel()).getNumber().intValue();
            i++;

        }
        i = 0;
        for (Map<String, JComponent> end : sw_anim_added_end) {
            newFrames[i][1] = ((SpinnerNumberModel) ((JSpinner) end.get("JSpinner")).getModel()).getNumber().intValue();
            i++;

        }
        String[] sfxFiles = new String[sw_sfx_added.size()];
        i = 0;
        for (Map<String, JComponent> file : sw_sfx_added) {
            sfxFiles[i] = sfxDir + File.separator + ((JTextField) file.get("JTextField")).getText();
            i++;

        }
        List<File> fileError = new ArrayList<File>();
        for (i = 0; i < newFrames.length; i++) {
            for (int j = newFrames[i][0]; j <= newFrames[i][1]; j++) {
                File f = new File(spritesDir + File.separator + sw_chr_name.getText() + File.separator + Model.RES_PATHS_map.get(modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION)) + File.separator + sw_anim_input_prefix.getText() + j + sw_anim_input_suffix.getText() + Model.RES_EXT_map.get(modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION)));
                if (!f.exists()) {
                    fileError.add(f);
                }
            }
        }
        for (String s : sfxFiles) {
            File f = new File(s);
            if (!f.exists()) {
                fileError.add(f);
            }
        }
        if (!fileError.isEmpty()) {
            String s = "The following file(s) could not be found :\n";
            for (File f : fileError) {
                s += "\n" + f.getPath();
            }
            new UIMessage(false, s, null, UIMessage.ERROR_TYPE);
        }
        Custom custom;
        if (flavor.equals(InteractiveModel._dataFlavor)) {
            custom = new InteractiveModel(spritesDir + File.separator + sw_chr_name.getText(), modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION), ((SpinnerNumberModel) sw_chr_floor.getModel()).getNumber().intValue(), new Dimension(((SpinnerNumberModel) sw_chr_dim_ext_w.getModel()).getNumber().intValue(), ((SpinnerNumberModel) sw_chr_dim_ext_h.getModel()).getNumber().intValue()), new Dimension(((SpinnerNumberModel) sw_chr_dim_int_w.getModel()).getNumber().intValue(), ((SpinnerNumberModel) sw_chr_dim_int_h.getModel()).getNumber().intValue()), newFrames, modelPanel.reversedAnims.get(ModelAnimBrowser.ATT_REVERSEDANIMS).toArray(new String[]{}), sfxFiles);
        } else if (flavor.equals(Model._dataFlavor)) {
            custom = new Model(spritesDir + File.separator + sw_chr_name.getText(), modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION), ((SpinnerNumberModel) sw_chr_floor.getModel()).getNumber().intValue(), new Dimension(((SpinnerNumberModel) sw_chr_dim_ext_w.getModel()).getNumber().intValue(), ((SpinnerNumberModel) sw_chr_dim_ext_h.getModel()).getNumber().intValue()), new Dimension(((SpinnerNumberModel) sw_chr_dim_int_w.getModel()).getNumber().intValue(), ((SpinnerNumberModel) sw_chr_dim_int_h.getModel()).getNumber().intValue()), newFrames, modelPanel.reversedAnims.get(ModelAnimBrowser.ATT_REVERSEDANIMS).toArray(new String[]{}), sfxFiles);
        } else {
            custom = new Custom(spritesDir + File.separator + sw_chr_name.getText(), modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION), ((SpinnerNumberModel) sw_chr_floor.getModel()).getNumber().intValue(), new Dimension(((SpinnerNumberModel) sw_chr_dim_ext_w.getModel()).getNumber().intValue(), ((SpinnerNumberModel) sw_chr_dim_ext_h.getModel()).getNumber().intValue()), new Dimension(((SpinnerNumberModel) sw_chr_dim_int_w.getModel()).getNumber().intValue(), ((SpinnerNumberModel) sw_chr_dim_int_h.getModel()).getNumber().intValue()), newFrames, modelPanel.reversedAnims.get(ModelAnimBrowser.ATT_REVERSEDANIMS).toArray(new String[]{}), sfxFiles);
        }
        custom.setSuffix(sw_anim_input_suffix.getText());
        custom.setPrefix(sw_anim_input_prefix.getText());
        if (custom instanceof Model) {
            ((Model) custom).setInnerResourceModeEnabled(false);
        }
        if (JXAenvUtils._debug) {
            System.err.println("customizing Model " + ((Custom) custom).id + " at " + SpritesChar.RES_NAMES_map.get(custom.getResolution()));
        }
        copyCustomMappings(custom);
        if (custom instanceof Model) {

            if (linkedModelFile != null) {
                custom.setAttribute(_linkedModel, Model._importModel(linkedModelFile.getPath()));
            }
            if (linkedModelsArrayModelsFiles != null) {
                Model[] models = new Model[linkedModelsArrayModelsFiles.length];
                i = 0;
                for (File f : linkedModelsArrayModelsFiles) {
                    models[i++] = (Model) Model._importModel(f.getPath());
                }
                custom.setAttribute(_linkedModelsArray, models);
            }
        }
        if (custom instanceof Custom) {
            if (iconFile != null) {
                try {
                    custom.setAttribute("icon", new Sprite(ImageIO.read(iconFile), "image/x-png", _iconSize));
                } catch (IOException ex) {
                    if (JXAenvUtils._debug) {
                        ex.printStackTrace();
                    }
                    UIMessage.showConfirmDialog(panel, ex, "The icon Sprite failed to load.", JOptionPane.OK_OPTION);
                }
                custom.setAttribute("lastModificationMillis", System.currentTimeMillis());
            }
        }
        return custom;
    }
    public final static Map<DataFlavor, String[]> _MIME_EXTS = new ConcurrentHashMap<DataFlavor, String[]>();
    public final static DataFlavor[] _dataFlavors = new DataFlavor[]{Custom._dataFlavor, Model._dataFlavor, InteractiveModel._dataFlavor, XtendedModel._dataFlavor};

    static {
        for (DataFlavor df : _dataFlavors) {
            try {
                _MIME_EXTS.put(df, (String[]) df.getRepresentationClass().getField("_MIME_EXT").get(null));
            } catch (Exception e) {
                if (JXAenvUtils._debug) {
                    e.printStackTrace();
                }
            }
        }
    }

    private Custom loadCustom() {
        try {
            File[] userFiles = getFiles(_dataFlavors, Custom._dataFlavor);
            currentFile = transferFile = userFiles.length > 0 ? userFiles[0] : null;
            if (getTransferData(Custom._dataFlavor) instanceof File) {
                return loadCustom((File) getTransferData(Custom._dataFlavor));
            } else if (getTransferData(Model._dataFlavor) instanceof File) {
                return loadModel((File) getTransferData(Model._dataFlavor));
            } else if (getTransferData(InteractiveModel._dataFlavor) instanceof File) {
                return loadModel((File) getTransferData(InteractiveModel._dataFlavor));
            } else if (getTransferData(XtendedModel._dataFlavor) instanceof File) {
                return loadModel((File) getTransferData(XtendedModel._dataFlavor));
            }
            return character;
        } catch (UnsupportedFlavorException ex) {
            if (JXAenvUtils._debug) {
                ex.printStackTrace();
            }
            return character;
        } catch (IOException ex) {
            if (JXAenvUtils._debug) {
                ex.printStackTrace();
            }
            return character;
        }

    }

    /*
     * private static InteractiveModel __makeInteractive(Model model,
     * InteractiveModel imodel, File iconFile) { return imodel;
     }
     */
    public Custom _convertCustom(Custom custom, File iconFile, DataFlavor flavor) {
        Custom model = null;
        if (XtendedModel._dataFlavor.equals(flavor)) {
            model = new XtendedModel(custom.id, SpritesChar.HIGH, custom.floorDiff, new Dimension(custom.spriteWidth, custom.spriteHeight), custom.spriteSize, custom.frames, custom.reversedAnims, custom.sfx);
        } else if (InteractiveModel._dataFlavor.equals(flavor)) {
            model = new InteractiveModel(custom.id, SpritesChar.HIGH, custom.floorDiff, new Dimension(custom.spriteWidth, custom.spriteHeight), custom.spriteSize, custom.frames, custom.reversedAnims, custom.sfx);
        } else if (Model._dataFlavor.equals(flavor)) {
            model = new Model(custom.id, SpritesChar.HIGH, custom.floorDiff, new Dimension(custom.spriteWidth, custom.spriteHeight), custom.spriteSize, custom.frames, custom.reversedAnims, custom.sfx);
        } else {
            model = new Custom(custom.id, SpritesChar.HIGH, custom.floorDiff, new Dimension(custom.spriteWidth, custom.spriteHeight), custom.spriteSize, custom.frames, custom.reversedAnims, custom.sfx);
        }
        model.setAttribute(ATTR_CUSTOMIZED, true);
        model.animsMap = custom.animsMap;
        model.sfxMap = custom.sfxMap;
        model.suffix = custom.suffix;
        model.prefix = custom.prefix;
        model.res = custom.res;
        if (custom.getAttribute(ATTR_CUSTOMIZED) != null) {
            model.setAttribute(ATTR_CUSTOMIZED, custom.getAttribute(ATTR_CUSTOMIZED));
        }
        if (custom.getAttribute(ModelAnimBrowser.LOCATIONS) != null) {
            model.setAttribute(ModelAnimBrowser.LOCATIONS, custom.getAttribute(ModelAnimBrowser.LOCATIONS));
        }
        if (custom.getAttribute(ModelAnimBrowser.COLLISIONSDEF) != null) {
            model.setAttribute(ModelAnimBrowser.COLLISIONSDEF, custom.getAttribute(ModelAnimBrowser.COLLISIONSDEF));
        }
        if (custom.getAttribute(ModelAnimBrowser.COLLISIONSATK) != null) {
            model.setAttribute(ModelAnimBrowser.COLLISIONSATK, custom.getAttribute(ModelAnimBrowser.COLLISIONSATK));
        }
        if (model instanceof Model) {
            ((Model) model).setInnerResourceModeEnabled(false);
            ((Model) model).setCompressionEnabled(compress);
            if (custom.getAttribute(_linkedModel) != null) {
                model.setAttribute(_linkedModel, custom.getAttribute(_linkedModel));
            }
            if (custom.getAttribute(_linkedModelsArray) != null) {
                model.setAttribute(_linkedModelsArray, custom.getAttribute(_linkedModelsArray));
            }
            try {
                if (iconFile != null) {
                    model.setAttribute("icon", new Sprite(ImageIO.read(iconFile), "image/x-png", _iconSize));
                }
            } catch (IOException ex) {
                if (JXAenvUtils._debug) {
                    ex.printStackTrace();
                }
                UIMessage.showConfirmDialog(null, ex, "The icon Sprite failed to load.", JOptionPane.OK_OPTION);
            } finally {
                if (custom instanceof Model) {
                    ((Model) model).accessCache().getSwapMap().clear();
                    ((Model) model).accessCache().getSwapMap().putAll(((Model) custom).accessCache().getSwapMap());
                }
            }
        } else {
            model.setAttribute("icon", null);
        }
        return model;
    }
    private Action action_import = new AbstractAction("open...", UIMessage._getIcon(UIMessage.LOAD_TYPE, true)) {

        public void actionPerformed(ActionEvent pe) {
            final ActionEvent e = pe;
            Runnable r = new Runnable() {

                public void run() {
                    Custom custom = loadCustom();
                    if (custom instanceof Model) {
                        character = (Model) custom;
                    } else if (custom instanceof Custom) {
                        character = (Model) _convertCustom(custom, iconFile, Model._dataFlavor);
                    }
                    ThreadWorks.Swing.invokeLater(new Runnable() {

                        public void run() {
                            reset(e);
                        }
                    });
                }
            };
            works.doLater(r);
        }
    };
    private static final String ATTR_CUSTOMIZED = "customized";
    private File currentFile = null;

    private Custom loadCustom(File f) {
        try {
            if (!f.exists()) {
                throw new IOException("File " + f + " not found.");
            }
            addRecentFile(f);
            RandomAccessFile raf = new RandomAccessFile(f, "r");
            FileInputStream fis = new FileInputStream(raf.getFD());
            ObjectInputStream ois = new ObjectInputStream(fis);
            Custom custom = (Custom) ois.readObject();
            ois.close();
            fis.close();
            raf.close();
            return custom == null ? character : custom;
        } catch (Exception e) {
            if (JXAenvUtils._debug) {
                e.printStackTrace();
            }
            return character;
        }
    }

    private Model loadModel(File f) {
        try {
            if (!f.exists()) {
                throw new IOException("File " + f + " not found.");
            }
            addRecentFile(f);
            Model model = (Model) Model._importModel(f.getCanonicalPath());
            if (model == null) {
                return character;
            }
            currentFile = f;
            /*
             * model.setAttribute(ATTR_CUSTOMIZED, false);
             */
            if (model.getAttribute("icon") instanceof Sprite) {
                Sprite sp = (Sprite) model.getAttribute("icon");
                sp.runValidate();
                sw_icon = Display._Display(sp.getImage(iconPanel), null, _iconSize).getJComponentDisplay();
                iconFile = new File("icon.png");
                sp.writeImageToOutput(iconFile, .8f);
                updateIconPanel();
                customizeFrame.pack();
                customizeFrame.repaint();
                viewerPanel.removeAll();
                viewerPanel.add(sw_icon, BorderLayout.CENTER);
            } else {
                viewerPanel.removeAll();
                viewerPanel.add(new JLabel(UIMessage._getIcon(UIMessage.MODEL_TYPE, false)), BorderLayout.CENTER);
            }
            viewerPanel.revalidate();
            viewerPanel.repaint();
            return model;
        } catch (Exception ex) {
            if (JXAenvUtils._debug) {
                ex.printStackTrace();
            }
            return character;
        }
    }

    private DataFlavor getDataFlavorFromFile(File f) {
        transferFile = f;
        DataFlavor selectedDf = null;
        for (DataFlavor flavor : _dataFlavors) {
            try {
                if (getTransferData(flavor) instanceof File) {
                    selectedDf = flavor;
                    break;
                }
            } catch (UnsupportedFlavorException ex) {
                if (JXAenvUtils._debug) {
                    ex.printStackTrace();
                }
            } catch (IOException ex) {
                if (JXAenvUtils._debug) {
                    ex.printStackTrace();
                }
            }
        }
        return selectedDf;
    }

    private Model saveAs(DataFlavor[] flavors) {
        FileChooserPane fcp = new FileChooserPane(applet, spritesDir = (spritesDir == null) ? "." : spritesDir);

        FileFilter ff = null;
        fcp.setModeSave(true);
        for (DataFlavor flavor : flavors) {
            if (Custom._dataFlavor.equals(flavor)) {
                fcp.getFiles().addChoosableFileFilter(new ExampleFileFilter(Custom._MIME_EXT, Custom._dataFlavor.getHumanPresentableName()));
            } else if (Model._dataFlavor.equals(flavor)) {
                ff = new ExampleFileFilter(Model._MIME_EXT, Model._dataFlavor.getHumanPresentableName());
                fcp.getFiles().addChoosableFileFilter(ff);
            } else if (InteractiveModel._dataFlavor.equals(flavor)) {
                fcp.getFiles().addChoosableFileFilter(new ExampleFileFilter(InteractiveModel._MIME_EXT, InteractiveModel._dataFlavor.getHumanPresentableName()));
            } else if (XtendedModel._dataFlavor.equals(flavor)) {
                fcp.getFiles().addChoosableFileFilter(new ExampleFileFilter(XtendedModel._MIME_EXT, XtendedModel._dataFlavor.getHumanPresentableName()));
            } else {
                if (JXAenvUtils._debug) {
                    System.err.println("unsupported DataFlavor : " + flavor.toString());
                }
            }
        }
        if (ff != null) {
            fcp.getFiles().setFileFilter(ff);
        }
        File[] savePath = fcp.getFile();
        if (savePath.length == 0) {
            return character;
        }
        DataFlavor selectedDf = getDataFlavorFromFile(savePath[0]);
        if (selectedDf == null) {
            ff = fcp.getFiles().getFileFilter();
            if (ff.accept(new File("file"))) {
                selectedDf = (DataFlavor) UIMessage.showSelectDialog(applet, "What document type to you want to save ?", "Document type is unknown", _dataFlavors, InteractiveModel._dataFlavor);
            } else if (ff.accept(new File("file." + Custom._MIME_EXT[0]))) {
                selectedDf = Custom._dataFlavor;
            } else if (ff.accept(new File("file." + Model._MIME_EXT[0]))) {
                selectedDf = Model._dataFlavor;
            } else if (ff.accept(new File("file." + InteractiveModel._MIME_EXT[0]))) {
                selectedDf = InteractiveModel._dataFlavor;
            } else if (ff.accept(new File("file." + XtendedModel._MIME_EXT[0]))) {
                selectedDf = XtendedModel._dataFlavor;
            }
        }
        applet.setEnabled(false);
        if (selectedDf instanceof DataFlavor) {
            if (savePath.length > 0) {
                if (!save(savePath[0].getPath(), selectedDf)) {
                    new UIMessage(true, "An error occurred while attemping to save the model.", null, UIMessage.MODEL_TYPE);
                }
            }
        }
        applet.setEnabled(true);
        return character;
    }
    private Action action_save_template = new AbstractAction("<html><b>save template...</b></html>", UIMessage._getIcon(UIMessage.TEMPLATE_TYPE, true)) {

        public void actionPerformed(ActionEvent pe) {
            final ActionEvent e = pe;
            Runnable r = new Runnable() {

                public void run() {
                    saveAs(new DataFlavor[]{Custom._dataFlavor});
                    try {
                        ThreadWorks.Swing.invokeLater(new Runnable() {

                            public void run() {
                                refreshSpot(e);
                            }
                        });
                    } catch (Exception e) {
                        if (JXAenvUtils._debug) {
                            e.printStackTrace();
                        }
                    } finally {
                    }
                }
            };
            works.doLater(r);
        }
    };
    private Action action_save = new AbstractAction("save", UIMessage._getIcon(UIMessage.MODEL_TYPE, true)) {

        public void actionPerformed(ActionEvent pe) {
            final ActionEvent e = pe;
            Runnable r = new Runnable() {

                public void run() {
                    if (currentFile instanceof File) {
                        save(currentFile.getPath());
                    } else {
                        character = saveAs(_dataFlavors);
                    }
                    try {
                        ThreadWorks.Swing.invokeLater(new Runnable() {

                            public void run() {
                                refreshSpot(e);
                            }
                        });
                    } catch (Exception e) {
                        if (JXAenvUtils._debug) {
                            e.printStackTrace();
                        }
                    } finally {
                    }
                }
            };
            works.doLater(r);
        }
    };
    private Action action_saveAs = new AbstractAction("save as...", UIMessage._getIcon(UIMessage.STORE_TYPE, true)) {

        public void actionPerformed(ActionEvent pe) {
            final ActionEvent e = pe;
            Runnable r = new Runnable() {

                public void run() {
                    character = saveAs(_dataFlavors);
                    try {
                        ThreadWorks.Swing.invokeLater(new Runnable() {

                            public void run() {
                                refreshSpot(e);
                            }
                        });
                    } catch (Exception e) {
                        if (JXAenvUtils._debug) {
                            e.printStackTrace();
                        }
                    } finally {
                    }
                }
            };
            works.doLater(r);
        }
    };
    private Action action_exportAs = new AbstractAction("export as MCX...", UIMessage._getIcon(UIMessage.STORE_TYPE, true)) {

        public void actionPerformed(ActionEvent pe) {
            final ActionEvent e = pe;
            Runnable r = new Runnable() {

                public void run() {
                    character = saveAs(new DataFlavor[]{XtendedModel._dataFlavor});
                    try {
                        ThreadWorks.Swing.invokeLater(new Runnable() {

                            public void run() {
                                refreshSpot(e);
                            }
                        });
                    } catch (Exception e) {
                        if (JXAenvUtils._debug) {
                            e.printStackTrace();
                        }
                    } finally {
                    }
                }
            };
            works.doLater(r);
        }
    };
    private AbstractAction action_new = new AbstractAction("new", UIMessage._getIcon(UIMessage.MODEL_TYPE, true)) {

        public void actionPerformed(final ActionEvent e) {
            ThreadWorks.Swing.invokeLater(new Runnable() {

                public void run() {
                    reset(e);
                    currentFile = null;
                    character = new Model("newModel", modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION), 0, new Dimension(), new Dimension(), new int[][]{}, new String[]{}, new String[]{});
                    disableModelIcon();
                    modelPanel.switchModel(character);
                    viewerPanel.removeAll();
                    viewerPanel.add(new JLabel(UIMessage._getIcon(UIMessage.DROPTARGET_TYPE, false)), BorderLayout.CENTER);
                    viewerPanel.validate();
                    refreshSpot(e);
                }
            });
        }
    };
    private AbstractAction action_cancel = new AbstractAction("cancel loading", UIMessage._getIcon(UIMessage.DISABLED_TYPE, true)) {

        public void actionPerformed(ActionEvent e) {
            works.cancelAllSchedules();
            UIMessage.killAllStaticWindows();
        }
    };
    static int MODELPANELWIDTH = 2;

    /**
     *
     */
    public void start() {
    }

    /**
     *
     */
    public void stop() {
        if (modelPanel instanceof ModelBrowser) {
            modelPanel.clearResource();
        }
    }
    private Action action_clearHeapMemory = new AbstractAction("<Restart Application>", UIMessage._getIcon(UIMessage.ERROR_TYPE, true)) {

        public void actionPerformed(ActionEvent e) {
            JFCApplet._restart((JFCApplet) AnimsBrowser_Ant.this.getApplet());
        }
    };
    private MemStatus scl = new MemStatus();
    JApplet applet = null;

    public void setApplet(JApplet arg0) {
        applet = arg0;
    }

    public void destroy() {
        if (initialized) {
            applet.getContentPane().removeAll();
        }
        initialized = false;
    }
    boolean initialized = false;

    public boolean isInitialized() {
        return initialized;
    }

    public Runnable shutdownHook() {
        return actionShutdownHook;
    }

    public DisplayInterface getSplash() {
        try {
            return Display._Display(getClass().getResource("/net/sf/jiga/xtended/ui/images/anims-splash.png"), null);
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

    public Vector<Action> getLoadLayers() {
        Vector<Action> loadLayers = new Vector<Action>();
        loadLayers.add(new AbstractAction("application store") {

            public void actionPerformed(ActionEvent e) {
                character = new Model("newModel", Model.HIGH, 0, new Dimension(), new Dimension(), new int[][]{}, new String[]{}, new String[]{});
                if (applicationStore.exists()) {
                    try {
                        RandomAccessFile raf = new RandomAccessFile(applicationStore, "r");
                        ObjectInputStream in = new ObjectInputStream(new FileInputStream(raf.getFD()));
                        List<File> fileList = (List<File>) in.readObject();
                        raf.close();
                        for (File f : fileList) {
                            addRecentFile(f);
                        }
                    } catch (Exception ex) {
                        if (JXAenvUtils._debug) {
                            ex.printStackTrace();
                        }
                    }
                }
                if (templateStore.exists()) {
                    character = (Model) _convertCustom(loadCustom(templateStore), null, Model._dataFlavor);
                }
                InteractiveModel model;
                String[] sfx;
                List<KeyEventWrapper> seq;
                /**
                 * ***
                 *
                 * ABA.ABA.PROPERTIES File defines available animation ID names
                 *
                 ***
                 */
                // myKfm
                SpritesChar.characters.put("KFM", new InteractiveModel(
                        "myKfm",
                        SpritesChar.HIGH,
                        20,
                        new Dimension(122, 141),
                        new Dimension(40, 100),
                        new int[][]{{68, 74}, {13, 28}, {220, 227}, {228, 239}, {240, 247}, {29, 44}, {45, 53}, {196, 197}, {198, 201}, {202, 203}, {204, 206}, {12, 12}, {178, 180}, {181, 184}, {185, 188}, {189, 195}, {54, 61}, {54, 61}, {160, 162}, {163, 168}, {169, 171}, {172, 177}, {207, 219}, {81, 83}, {86, 90}, {97, 100}, {84, 84}, {107, 109}, {110, 114}, {136, 137}, {156, 159}, {260, 264}, {248, 259}, {220, 247}, {115, 118}, {118, 118}, {220, 227}, {220, 247}, {196, 197}, {198, 201}, {202, 203}, {202, 203}, {204, 206}, {204, 206}, {198, 201}, {2, 7}},
                        new String[]{"jump forwards", "stance forwards", "stance forwards LP", "stance forwards MP", "stance forwards HP",
                            "stance forwards LK", "stance forwards MK", "stance forwards HK", "jump forwards LK"},
                        new String[]{"sf3-sfx 2.wav"}));
                model = SpritesChar.characters.get("KFM");
                model.setPrefix("kfm");
                model.addAnimMap("stance", 46);
                model.addAnimMap("stance intro", 0);
                model.addAnimMap("win", 0);
                model.addAnimMap("lose", 0);
                model.addAnimMap("stance forwards", 1);
                model.addAnimMap("stance forwards LP", 2);
                model.addAnimMap("stance forwards LK", 3);
                model.addAnimMap("stance forwards MK", 4);
                model.addAnimMap("stance backwards", 5);
                model.addAnimMap("jump", 6);
                model.addAnimMap("jump LP", 7);
                model.addAnimMap("jump MP", 8);
                model.addAnimMap("jump LK", 9);
                model.addAnimMap("jump MK", 10);
                model.addAnimMap("stance crouch", 11);
                model.addAnimMap("stance crouch LP", 12);
                model.addAnimMap("stance crouch MP", 13);
                model.addAnimMap("stance crouch LK", 14);
                model.addAnimMap("stance crouch MK", 15);
                model.addAnimMap("jump forwards", 16);
                model.addAnimMap("jump backwards", 17);
                model.addAnimMap("stance LP", 18);
                model.addAnimMap("stance MP", 18);
                model.addAnimMap("stance LK", 20);
                model.addAnimMap("stance MK", 21);
                model.addAnimMap("stance throw P", 22);
                model.addAnimMap("stance block H", 23);
                model.addAnimMap("stance hit L", 24);
                model.addAnimMap("stance hit M", 25);
                model.addAnimMap("stance crouch block H", 26);
                model.addAnimMap("stance crouch hit H", 27);
                model.addAnimMap("jump hit", 28);
                model.addAnimMap("thrown", 29);
                model.addAnimMap("stance draw", 30);
                model.addAnimMap("stance forwards super LP", 31);
                model.addAnimMap("stance forwards super MP", 31);
                model.addAnimMap("stance forwards super LK", 33);
                model.addAnimMap("fall", 34);
                model.addAnimMap("K.O.", 35);
                model.addAnimMap("stance forwards MP", 36);
                model.addAnimMap("stance forwards super MK", 37);
                model.addAnimMap("jump backwards LP", 38);
                model.addAnimMap("jump forwards LP", 38);
                model.addAnimMap("jump backwards MP", 40);
                model.addAnimMap("jump backwards LK", 41);
                model.addAnimMap("jump forwards LK", 41);
                model.addAnimMap("jump backwards MK", 43);
                model.addAnimMap("jump forwards MK", 43);
                model.addAnimMap("jump forwards MP", 45);
                model.addSoundMap("stance intro", 0);

                // background dojo
                // center first layer
                Model bmodel;
                SpritesChar.models.put("Dojo_center-layer1", new Model("dojo/center", SpritesChar.HIGH, 0, new Dimension(1482, 608), new Dimension(1482, 608), new int[][]{{0, 0}}, new String[]{}, new String[]{}));
                bmodel = SpritesChar.models.get("Dojo_center-layer1");
                bmodel.setPrefix("sf3-battle-bg-center");
                // center second layer
                SpritesChar.models.put("Dojo_center-layer2", new Model("dojo/center2", SpritesChar.HIGH, 0, new Dimension(1482, 608), new Dimension(1482, 608), new int[][]{{0, 4}}, new String[]{}, new String[]{}));
                bmodel = SpritesChar.models.get("Dojo_center-layer2");
                bmodel.setPrefix("sf3-battle-bg-center1-");
                // floor
                SpritesChar.models.put("Dojo_floor", new Model("dojo/floor", SpritesChar.HIGH, 0, new Dimension(1482, 470), new Dimension(1482, 470), new int[][]{{0, 0}}, new String[]{}, new String[]{}));
                bmodel = SpritesChar.models.get("Dojo_floor");
                // roof
                bmodel.setPrefix("sf3-battle-bg-floor");
                SpritesChar.models.put("Dojo_roof", new Model("dojo/roof", SpritesChar.HIGH, 0, new Dimension(1482, 164), new Dimension(1482, 164), new int[][]{{0, 0}}, new String[]{}, new String[]{}));
                bmodel = SpritesChar.models.get("Dojo_roof");
                bmodel.setPrefix("sf3-battle-bg-roof");
                // Chunli
                sfx = new String[17];
                for (int i = 0; i < sfx.length; i++) {
                    sfx[i] = "sf3-sfx " + (i + 23) + ".aif";
                }
                SpritesChar.characters.put("ChunLi",
                        new InteractiveModel("chunli",
                                SpritesChar.HIGH,
                                30,
                                new Dimension(576, 230),
                                new Dimension(85, 105),
                                new int[][]{{19457, 19461}, {19472, 19479}, {19488, 19505},
                                {19520, 19537}, {19552, 19583}, {19584, 19590}, {19591, 19599}, {19600, 19605}, {19606, 19615}, {19616, 19641},
                                {19642, 19647}, {19648, 19655}, {19656, 19663}, {19664, 19680}, {19681, 19689}, {19696, 19704}, {19712, 19722},
                                {19728, 19736}, {19744, 19788}, {19792, 19793}, {19795, 19818}, {19819, 19827}, {19829, 19839},
                                {19840, 19848}, {19856, 19864}, {19872, 19883}, {19888, 19896}, {19904, 19913}, {19920, 19926}, {19936, 19957},
                                {19959, 19979}, {19984, 19994}, {20000, 20025}, {20032, 20037}, {20048, 20062}, {20064, 20076}, {20080, 20099}, {20112, 20115}, {20128, 20133},
                                {20144, 20160}, {20176, 20178}, {20192, 20195}, {20208, 20277}, {20288, 20292}, {20304, 20314}, {20320, 20332}, {20336, 20344},
                                {20352, 20358}, {20368, 20382}, {20384, 20394}, {20400, 20407}, {20416, 20427}, {20432, 20442}, {20448, 20462},
                                {20464, 20472}, {20480, 20497}, {20512, 20518}, {20528, 20532}, {20544, 20552}, {20560, 20566}, {20576, 20580},
                                {20592, 20600}, {20608, 20618}, {20624, 20636}, {20640, 20659}, {20672, 20675}, {20688, 20700}, {20704, 20713},
                                {20720, 20728}, {20734, 20766},
                                {20768, 20798}, {20800, 20814}, {20816, 20837}, {20848, 20861}, {20864, 20876}, {20880, 20939}, {20944, 20985},
                                {20992, 21099}
                                },
                                new String[]{"jump forwards", "stance forwards", "stance forwards LP", "stance forwards MP", "stance forwards HP",
                                    "stance forwards LK", "stance forwards MK", "stance forwards HK", "jump forwards LK"},
                                sfx));
                model = SpritesChar.characters.get("ChunLi");
                model.addAnimMap("stance intro", 0);
                model.addAnimMap("stance", 1);
                model.addAnimMap("stance forwards", 2);
                model.addAnimMap("stance backwards", 3);
                model.addAnimMap("stance crouch", 5);
                model.addAnimMap("stance win", 6);
                model.addAnimMap("stance draw", 8);
                model.addAnimMap("jump high recover", 12);
                model.addAnimMap("stance block H", 14);
                model.addAnimMap("stance block M", 15);
                model.addAnimMap("stance block L", 16);
                model.addAnimMap("jump", 17);
                model.addAnimMap("stance hit H", 24);
                model.addAnimMap("stance hit M", 25);
                model.addAnimMap("stance hit L", 26);
                model.addAnimMap("stance super hit", 28);
                model.addAnimMap("stance super hit", 31);
                model.addAnimMap("stance forwards LP", 41);
                model.addAnimMap("stance forwards MP", 42);
                model.addAnimMap("stance forwards HP", 43);
                model.addAnimMap("stance LP", 44);
                model.addAnimMap("stance MP", 45);
                model.addAnimMap("stance HP", 46);
                model.addAnimMap("jump backwards", 47);
                model.addAnimMap("stance forwards LK", 48);
                model.addAnimMap("stance forwards MK", 49);
                model.addAnimMap("stance forwards HK", 50);
                model.addAnimMap("stance LK", 51);
                model.addAnimMap("stance MK", 52);
                model.addAnimMap("stance HK", 53);
                model.addAnimMap("jump forwards", 47);
                model.addAnimMap("stance hit M", 24);
                model.addAnimMap("stance hit H", 25);
                model.addAnimMap("stance hit L", 26);
                model.addAnimMap("stance back hit", 27);
                model.addAnimMap("stance hit L", 30);
                model.addAnimMap("stance super hit", 31);
                model.addAnimMap("fall thrown", 32);
                model.addAnimMap("stance LP", 44);
                model.addAnimMap("stance crouch LP", 54);
                model.addAnimMap("stance crouch MP", 55);
                model.addAnimMap("stance crouch HP", 56);
                model.addAnimMap("stance crouch LK", 57);
                model.addAnimMap("stance crouch MK", 58);
                model.addAnimMap("stance crouch HK", 59);
                model.addAnimMap("stance block H", 14);
                model.addAnimMap("stance block M", 15);
                model.addAnimMap("stance block L", 16);
                model.addAnimMap("jump LP", 60);
                model.addAnimMap("jump MP", 61);
                model.addAnimMap("jump HP", 62);
                model.addAnimMap("jump LK", 63);
                model.addAnimMap("jump MK", 64);
                model.addAnimMap("jump HK", 65);
                model.addAnimMap("stance throw", 69);
                model.addAnimMap("jump throw", 70);
                model.addAnimMap("jump forwards LK", 71);
                model.addAnimMap("stance super 2", 72);
                model.addAnimMap("stance super 1", 73);
                model.addAnimMap("stance super 3", 74);

                model.addSoundMap("stance draw", 8);
                model.addSoundMap("stance win", 15);
                model.addSoundMap("stance super 1", 0);
                model.addSoundMap("stance fireball 1", 1);
                model.addSoundMap("stance super 2", 4);
                model.addSoundMap("stance intro", 7);
                model.addSoundMap("stance feign", 11);
                model.addSoundMap("stance lose", 16);

                //demo
                SpritesChar.characters.put("ChunLi-demo",
                        new InteractiveModel("chunli",
                                SpritesChar.HIGH,
                                30,
                                new Dimension(576, 230),
                                new Dimension(85, 105),
                                new int[][]{{19457, 19461}},
                                new String[]{"jump forwards", "stance forwards", "stance forwards LP", "stance forwards MP", "stance forwards HP",
                                    "stance forwards LK", "stance forwards MK", "stance forwards HK", "jump forwards LK"},
                                sfx));
                model = SpritesChar.characters.get("ChunLi-demo");
                model.addSoundMap("stance draw", 8);
                model.addSoundMap("stance win", 15);
                model.addSoundMap("stance fireball super M", 1);
                model.addSoundMap("stance intro", 7);
                model.addSoundMap("stance feign", 11);
                model.addSoundMap("stance lose", 16);

                //Ken
                sfx = new String[11];
                for (int i = 0; i < sfx.length; i++) {
                    sfx[i] = "sf3-sfx " + (i + 12) + ".aif";
                }
                SpritesChar.characters.put("Ken",
                        new InteractiveModel("ken",
                                SpritesChar.HIGH,
                                50,
                                new Dimension(368, 238),
                                new Dimension(80, 110),
                                new int[][]{{14657, 14669}, {14672, 14682}, {14684, 14694}, {14696, 14707}, {14714, 14717}, {14720, 14764},
                                {14768, 14779},
                                {14784, 14796}, {14800, 14814}, {14816, 14824}, {14826, 14839}, {14842, 14864}, {14880, 14908}, {14911, 14932}, {14944, 14998},
                                {15008, 15037}, {15040, 15067}, {15073, 15078}, {15104, 15110}, {15112, 15132}, {15138, 15148}, {15152, 15156}, {15164, 15172},
                                {15184, 15205}, {15216, 15222}, {15233, 15240}, {15246, 15254}, {15264, 15288}, {15296, 15318}, {15328, 15359}, {15368, 15372}, {15376, 15388},
                                {15408, 15417}, {15438, 15438}, {15440, 15449}, {15456, 15469}, {15536, 15552}, {15568, 15584}, {15601, 15623},
                                {15626, 15628},
                                {15632, 15646}, {15648, 15658}, {15680, 15688}, {15696, 15706}
                                },
                                new String[]{"jump forwards", "stance forwards", "stance forwards LP", "stance forwards MP", "stance forwards HP",
                                    "stance forwards LK", "stance forwards MK", "stance forwards HK", "jump forwards LK"},
                                sfx));
                model = SpritesChar.characters.get("Ken");
                model.addAnimMap("stance", 0);
                model.addAnimMap("stance forwards MP", 13);
            }
        });
        return loadLayers;
    }

    class MemStatus extends SpritesCacheAdapter {

        JProgressBar WtimeProgress = JXAenvUtils2._JTimeProgressBar();

        private int getCharacterTotalFrames() {
            int total = 0;
            for (int[] f : character.frames) {
                total += f[1] - f[0] + 1;
            }
            return total;
        }

        public void writeCompleted() {
            statusBar.setStringPainted(true);
            statusBar.setMaximum_init(character.frames.length);
            statusBar.setValue_init(character.accessCache().getSwapMap().size());
            statusBar.setValue((int) Math.round(character.accessCache().allocSize()));
            WtimeProgress.setMaximum(getCharacterTotalFrames());
            WtimeProgress.setValue((int) Math.round((double) statusBar.getValue_init() / (double) statusBar.getMaximum_init() * (double) getCharacterTotalFrames()));
            if (JXAenvUtils._debug) {
                System.out.println(WtimeProgress.getValue() + " / " + WtimeProgress.getMaximum() + " = " + WtimeProgress.getString());
            }
            statusBar.setString(WtimeProgress.getString());
        }

        public void readCompleted() {
            statusBar.setMaximum_committed(character.frames.length);
            statusBar.setValue_committed(character.accessCache().getSwapMap().size());
            statusBar.setValue(character.accessCache().keySet().size());
        }
    }

    /**
     * This refreshes anim spot in applet content. @discussion (comprehensive
     * description)
     */
    private void refreshSpot(ActionEvent e) {
        sw_refresh.setText("refreshing...");
        sw_refresh.paintImmediately(0, 0, sw_refresh.getWidth(), sw_refresh.getHeight());
        if (JXAenvUtils._debug) {
            System.out.println(sw_refresh.getText());
        }
        statusBar.setIndeterminate(!(character instanceof Model));
        if (character instanceof Model) {
            statusBar.setValue((int) character.allocSize());
            /*
             * character.setMultiThreadingEnabled(JXAenvUtils.env.THREADING_MULTI.isEnv());
             */
        }
        for (Iterator<Action> i = refreshProps.iterator(); i.hasNext();) {
            Action a = i.next();
            sw_refresh.setText((String) a.getValue(Action.NAME));
            sw_refresh.paintImmediately(0, 0, sw_refresh.getWidth(), sw_refresh.getHeight());
            if (JXAenvUtils._debug) {
                System.out.print(sw_refresh.getText());
            }
            a.actionPerformed(e);
            if (JXAenvUtils._debug) {
                System.out.println(" : done.");
            }
        }
        applet.repaint();
        if (JXAenvUtils._debug) {
            System.out.println("applet repaint done.");
            System.err.println("model status : " + character.toString());
        }
        sw_refresh.setText("refresh");
        sw_refresh.repaint();
    }

    /**
     * Loads a dialog with all of the optional characters (from SpritesChars
     * src), then returns user selected SpritesChar. @discussion (comprehensive
     * description)
     *
     * @return  the selected SpritesChar instance
     */
    private Model getSpritesChar() {
        String[] allModels = new String[SpritesChar.characters.size() + SpritesChar.models.size()];
        int n = 0;
        for (Iterator<String> i = SpritesChar.characters.keySet().iterator(); i.hasNext();) {
            allModels[n++] = i.next();
        }
        for (Iterator<String> i = SpritesChar.models.keySet().iterator(); i.hasNext();) {
            allModels[n++] = i.next();
        }

        String s = (String) requestUserActionDialog("Select model to anim (you will lose your current unsaved data):", allModels, null);
        return (s != null && !new String("").equals(s)) ? (SpritesChar.models.containsKey(s) ? SpritesChar.models.get(s) : (SpritesChar.characters.containsKey(s) ? SpritesChar.characters.get(s) : character)) : character;
    }

    /**
     * fetch files from disk
     */
    private File[] getFiles(DataFlavor[] flavors, DataFlavor preselectedFlavor) {
        FileChooserPane fcp = new FileChooserPane(applet, spritesDir = (spritesDir == null) ? "." : spritesDir);
        FileFilter sff = null;
        for (int i = 0; i < flavors.length; i++) {
            if (_MIME_EXTS.get(flavors[i]) instanceof String[]) {
                FileFilter ff = new ExampleFileFilter(_MIME_EXTS.get(flavors[i]), flavors[i].getHumanPresentableName());
                fcp.getFiles().addChoosableFileFilter(ff);
                if (flavors[i].equals(preselectedFlavor)) {
                    sff = ff;
                }
            }
        }
        fcp.getFiles().setFileFilter(sff);
        return fcp.getFile();
    }

    /**
     * Loads a FileChooser dialog, then returns user selected Directory with
     * file extension. @discussion (comprehensive description)
     *
     * @return an array of strings containing [0] directory and [1] file
     * extension, can have null entries if nothing is chosen by the user
     */
    private String[] getDirectory() {
        this.dirSelect = new FileChooserPane(applet, spritesDir = (spritesDir == null) ? "." : spritesDir);
        dirSelect.setMultiSelectionEnabled(false);
        File[] dir = dirSelect.getDirectory();
        return new String[]{(dir.length > 0) ? dir[0].getPath() : null, (format = getFormat()).substring(format.lastIndexOf('/') + 1)};
    }

    /**
     * Pops up a dialog to select options values. Returns an Object to cast.
     *
     * @discussion (comprehensive description)
     *
     * @param  actionMsg This dialog action name
     * @param  options Object array with the selectable options
     * @param  init Object that will be initialy selected in tray
     * @return  selected object, cast it to the options common class
     */
    private Object requestUserActionDialog(
            String actionMsg, Object[] options, Object init) {
        JOptionPane userActionDialog = new JOptionPane(actionMsg, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION);
        userActionDialog.setSelectionValues(options);
        userActionDialog.setInitialSelectionValue(init);
        userActionDialog.setWantsInput(true);
        Dialog dialog = userActionDialog.createDialog(applet, "Option");
        dialog.setModal(true);
        dialog.setVisible(true);
        return userActionDialog.getInputValue();
    }

    /**
     * *
     */
    private void stateAnimation(Animation anim) {
        String state = "";
        if (anim != null) {
            int status = anim.getState();
            if (status == Animation.PLAYING) {
                state = "PLAYING";
            } else if (status == Animation.STOPPED) {
                state = "STOPPED";
            } else if (status == Animation.PAUSED) {
                state = "PAUSED";
            } else {
                state = "Can't status Animation!";
            }
        }
        if (sw_state != null) {
            sw_state.setText(state);
        }

        if (JXAenvUtils._debug) {
            System.out.println(state);
        }
        panel.repaint();
    }

    public void setOwner(JFrame owner) {
        this.owner = owner;
    }
    private JFrame owner = null;

    /**
     * main command to java launcher public static void main(String[] args)
     * throws IOException { new AnimsBrowser_Ant(args); }* AppLauncher
     * applauncher;
     */
    /**
     *
     */
    public AnimsBrowser_Ant(String[] args) {
        /*
         * try { applauncher = new AppLauncher(JXAenvUtils._defaultGC,
         * getClass(), this,
         * "/net/sf/jiga/xtended/ui/images/AnimsBrowser_Ant.png",
         * "/aba/anims.gif", new Dimension(800, 600),
         * "/net/sf/jiga/xtended/ui/about-anims.htm", true); } catch
         * (URISyntaxException ex) { if (JXAenvUtils._debug) {
         * ex.printStackTrace(); } } catch (IOException ex) { if
         * (JXAenvUtils._debug) { ex.printStackTrace(); }
         }
         */
    }

    /**
     * called to init the most recent model data
     */
    public void reset(ActionEvent e) {
        modelPanel.clearResource();
        character.accessCache().removeSpritesCacheListener(scl);
        character.removeAccessAnimationCacheListener(rLed.getSpritesCacheAdapter());
        character.removeAccessAnimationCacheListener(wLed.getSpritesCacheAdapter());
        character.removeAccessAnimationIIOReadListener(rLed.getIIOReadProgressAdapter());
        character.removeAccessAnimationIIOWriteListener(wLed.getIIOWriteProgressAdapter());
        linkedModelFile = null;
        linkedModelsArrayModelsFiles = null;
        modelPanel.switchModel(character);
        refreshSpot(e);
        try {
            DataFlavor df = getDataFlavorFromFile(currentFile);
            if (Model._dataFlavor.equals(df) || InteractiveModel._dataFlavor.equals(df)) {
                action_modelPanel.actionPerformed(e);
            } else {
                action_customize.actionPerformed(e);
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    private String getFormat() {
        return character.RES_EXT_map.get(modelPanel.resolution.get(ModelAnimBrowser.ATT_RESOLUTION));
    }

    public JApplet getApplet() {
        return applet;
    }

    public boolean open(final Object data) {
        File f = null;
        if (data instanceof java.util.List) {
            java.util.List<File> l = (java.util.List) data;
            f = l.get(0);
        } else if (data instanceof String) {
            f = new File(data.toString());
        } else if (data instanceof Custom) {
            if (data instanceof Model) {
                character = (Model) data;
            } else {
                character = (Model) _convertCustom((Custom) data, iconFile, Model._dataFlavor);
            }
            ThreadWorks.Swing.invokeLater(new Runnable() {

                public void run() {
                    reset(new ActionEvent(data, data.hashCode(), "data transfer"));
                }
            });
            return true;
        }
        if (f instanceof File) {
            if (f.exists()) {
                for (String ext : Model._MIME_EXT) {
                    if (f.getName().endsWith(ext)) {
                        character = loadModel(f);
                        break;
                    }
                }
                for (String ext : InteractiveModel._MIME_EXT) {
                    if (f.getName().endsWith(ext)) {
                        character = loadModel(f);
                        break;
                    }
                }
                for (String ext : XtendedModel._MIME_EXT) {
                    if (f.getName().endsWith(ext)) {
                        character = loadModel(f);
                        break;
                    }
                }
                for (String ext : Custom._MIME_EXT) {
                    if (f.getName().endsWith(ext)) {
                        character = (Model) _convertCustom(loadCustom(f), iconFile, Model._dataFlavor);
                        break;
                    }
                }
                ThreadWorks.Swing.invokeLater(new Runnable() {

                    public void run() {
                        reset(new ActionEvent(data, data.hashCode(), "data transfer"));
                    }
                });
                return true;
            }
        }
        return false;
    }
    AccessControlContext acc = AccessController.getContext();
    private List<File> recentFiles = Collections.synchronizedList(new ArrayList<File>());
    private File applicationStore = new File(FileHelper._USERHOMESTOREDIRECTORY + File.separator + "ABAapplicationStore");
    private File templateStore = new File(FileHelper._USERHOMESTOREDIRECTORY + File.separator + "ABAtemplateStore");
    private Runnable actionShutdownHook = new Runnable() {

        public void run() {
            try {
                storeApplication(applicationStore, templateStore);
            } catch (FileNotFoundException ex) {
                if (JXAenvUtils._debug) {
                    ex.printStackTrace();
                }
            }
        }
    };

    private void storeApplication(final File fileStore, final File templateStore) throws FileNotFoundException {
        try {
            AccessController.doPrivileged(new PrivilegedExceptionAction() {

                public Object run() throws FileNotFoundException {
                    _storeApplication(fileStore, templateStore);
                    return null;
                }
            }, acc);
        } catch (PrivilegedActionException ex) {
            throw (FileNotFoundException) ex.getException();
        }
    }

    private void _storeApplication(File fileStore, File templateStore) throws FileNotFoundException {
        try {
            File tmp = File.createTempFile("store_", ".aba");
            tmp.deleteOnExit();
            RandomAccessFile rafTmp = new RandomAccessFile(tmp, "rw");
            RandomAccessFile raf = new RandomAccessFile(fileStore, "rw");
            ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream(rafTmp.getFD()));
            out.writeObject(recentFiles);
            rafTmp.close();
            rafTmp = new RandomAccessFile(tmp, "r");
            raf.setLength(tmp.length());
            byte[] rb = new byte[512];
            int r = 0;
            while ((r = rafTmp.read(rb)) != -1) {
                raf.write(rb, 0, r);
            }
            raf.close();
            rafTmp.close();
            if (templateStore != null) {
                if (character instanceof Model) {
                    if (Boolean.TRUE.equals(character.getAttribute(ATTR_CUSTOMIZED))) {
                        save(templateStore.getPath(), Custom._dataFlavor, false);
                    }
                }
            }
        } catch (IOException ex) {
            if (JXAenvUtils._debug) {
                ex.printStackTrace();
            }
        }
    }
    private List<JMenu> recentFilesMenu = new ArrayList<JMenu>();

    private JMenu makeRecentFilesMenu() {
        recentFilesMenu.add(new JMenu(("Recent files...")));
        updateRecentFilesMenus();
        return recentFilesMenu.get(recentFilesMenu.size() - 1);
    }

    private void updateRecentFilesMenus() {
        for (JMenu menu : recentFilesMenu) {
            menu.removeAll();
            for (final File f : recentFiles) {
                menu.add(new AbstractAction(f.getName()) {

                    public void actionPerformed(ActionEvent e) {
                        Runnable r = new Runnable() {

                            public void run() {
                                open(f.getPath());
                            }
                        };
                        works.doLater(r);
                    }
                });
            }
            while (menu.getItemCount() > 5) {
                menu.remove(0);
            }
            menu.validate();
            menu.repaint();
        }
    }

    private void addRecentFile(final File f) {
        if (f == null || recentFiles.contains(f)) {
            return;
        }
        recentFiles.add(f);
        updateRecentFilesMenus();
    }

    public DataFlavor[] getTransferDataFlavors() {
        List<DataFlavor> dataFlavors = new ArrayList<DataFlavor>();
        for (DataFlavor df : _dataFlavors) {
            dataFlavors.add(df);
        }
        dataFlavors.add(DataFlavor.javaFileListFlavor);
        dataFlavors.add(DataFlavor.stringFlavor);
        return dataFlavors.toArray(new DataFlavor[dataFlavors.size()]);
    }

    public boolean isDataFlavorSupported(DataFlavor flavor) {
        for (DataFlavor df : getTransferDataFlavors()) {
            if (df.equals(flavor)) {
                return true;
            }
        }
        return false;
    }
    File transferFile = null;

    public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
        if (isDataFlavorSupported(flavor)) {
            if (transferFile instanceof File) {
                for (String ext : _MIME_EXTS.get(flavor)) {
                    if (transferFile.getName().endsWith(ext)) {
                        return transferFile;
                    }
                }
            }
        } else {
            String dfStr = "";
            String sep = "";
            for (DataFlavor df : getTransferDataFlavors()) {
                dfStr += sep + df;
                sep = ":";
            }
            if (JXAenvUtils._debug) {
                System.err.println("UNSPPORTED DATAFLAVOR error, actually supporting : " + dfStr);
            }
            throw new UnsupportedFlavorException(flavor);
        }
        return null;
    }

    /*
     * public AppLauncher getAppLauncher() { return applauncher; }
     */
    public JMenu getActionMenu() {
        JMenu menu = new JMenu("File");
        Action[] actions = new Action[]{action_new, action_import, action_save_template, action_save, action_saveAs, action_exportAs, action_cancel, action_reset, action_clearHeapMemory};
        action_new.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_N, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
        action_save.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
        action_import.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_O, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
        action_saveAs.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.SHIFT_DOWN_MASK | Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
        action_save_template.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_T, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
        action_cancel.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0));
        action_exportAs.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_E, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
        for (Action a : actions) {
            menu.add(a);
        }
        menu.add(makeRecentFilesMenu());
        menu.addSeparator();
        menu.add(new AbstractAction("Quit") {

            public void actionPerformed(ActionEvent e) {
                if (JOptionPane.OK_OPTION == UIMessage.showConfirmDialog(panel, new JLabel("<html>Are your sure to quit the application ?</html>"), "Quit ?", JOptionPane.OK_CANCEL_OPTION)) {
                    System.exit(0);
                }
            }
        });
        return menu;
    }
    private AbstractAction action_help = new AbstractAction("Quick help...") {

        public void actionPerformed(ActionEvent e) {
            try {
                JEditorPane browser = new JEditorPane(AnimsBrowser_Ant.class.getResource("quickHelp.html"));
                browser.setPreferredSize(new Dimension(400, 400));
                browser.setDragEnabled(true);
                browser.setEditable(false);
                browser.addHyperlinkListener(new HyperlinkAdapter());
                JScrollPane sp = new JScrollPane(browser);
                sp.getHorizontalScrollBar().setUnitIncrement(30);
                sp.getVerticalScrollBar().setUnitIncrement(30);
                sp.setPreferredSize(browser.getPreferredSize());
                new UIMessage(false, sp, owner);
            } catch (IOException ex) {
                if (JXAenvUtils._debug) {
                    ex.printStackTrace();
                }
            }
        }
    };

    public JMenu getHelpActionMenu() {
        JMenu menu = new JMenu("Edit");
        Action[] actions = new Action[]{action_help, action_customize, action_modelPanel, ModelBrowser.action_openLog};
        action_help.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0));
        ModelBrowser.action_openLog.putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_F1, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
        for (Action a : actions) {
            menu.add(a);
        }
        return menu;
    }

    public boolean save(String file) {
        DataFlavor dataFlavor = getDataFlavorFromFile(new File(file));
        if (dataFlavor instanceof DataFlavor) {
            return save(file, dataFlavor);
        }
        return false;
    }

    public boolean save(final String file, final DataFlavor flavor) {
        return save(file, flavor, true);
    }

    public boolean save(final String file, final DataFlavor flavor, final boolean uiMsg) {
        return AccessController.doPrivileged(new PrivilegedAction<Boolean>() {

            public Boolean run() {
                return _save(file, flavor, uiMsg);
            }
        }, acc);
    }

    private boolean _save(String file, DataFlavor flavor) {
        return _save(file, flavor, true);
    }

    private boolean _save(String file, DataFlavor flavor, boolean uiMsg) {
        if (!Boolean.TRUE.equals(character.getAttribute(ATTR_CUSTOMIZED))) {
            if (uiMsg) {
                if (JOptionPane.OK_OPTION == UIMessage.showConfirmDialog(panel, new JLabel("<html>Invalid customization ! <br>You must have run and applied to the customize task before to save. <br>Run it now ?</html>"), "Invalid action", JOptionPane.OK_CANCEL_OPTION)) {
                    action_customize.actionPerformed(new ActionEvent(panel, panel.hashCode(), "invalid customization need validating"));
                }
            }
            return false;
        }
        boolean success = false;
        long wait = uiMsg ? UIMessage.displayWaiting("saving " + flavor.getHumanPresentableName() + "...", panel) : 0L;
        if (Model._dataFlavor.equals(flavor) || InteractiveModel._dataFlavor.equals(flavor) || XtendedModel._dataFlavor.equals(flavor)) {
            Model custom = (Model) _convertCustom(character, iconFile, flavor);
            copyCustomMappings(custom);
            character = custom;
            modelPanel.switchModel(character);
            SpritesCacheManager<Integer, Animation> spm = character.accessCache();
            character.addAccessAnimationCacheListener(rLed.getSpritesCacheAdapter());
            character.addAccessAnimationCacheListener(wLed.getSpritesCacheAdapter());
            spm.addSpritesCacheListener(scl);
            character.addAccessAnimationIIOReadListener(rLed.getIIOReadProgressAdapter());
            character.addAccessAnimationIIOWriteListener(wLed.getIIOWriteProgressAdapter());
            statusBarLabel.setIcon(UIMessage._getIcon(UIMessage.WAIT_TYPE, false));
            character.loadResource();
            if (!Thread.currentThread().isInterrupted()) {
                character.runValidate();
                if (Model._dataFlavor.equals(flavor)) {
                    success = Model._exportModel(file, Model._MIME_EXT, character);
                } else if (InteractiveModel._dataFlavor.equals(flavor)) {
                    success = Model._exportModel(file, InteractiveModel._MIME_EXT, character);
                } else if (XtendedModel._dataFlavor.equals(flavor)) {
                    success = Model._exportModel(file, XtendedModel._MIME_EXT, character);
                }
            }
            statusBarLabel.setIcon(UIMessage._getIcon(UIMessage.ENABLED_TYPE, false));
            spm.removeSpritesCacheListener(scl);
            character.addAccessAnimationCacheListener(rLed.getSpritesCacheAdapter());
            character.addAccessAnimationCacheListener(wLed.getSpritesCacheAdapter());
        } else if (Custom._dataFlavor.equals(flavor)) {
            try {
                Custom custom = applyCustomizedModelData(Custom._dataFlavor);
                boolean validExt = false;
                for (String ext : Custom._MIME_EXT) {
                    if (file.endsWith("." + ext)) {
                        validExt = true;
                        break;
                    }
                }
                if (!validExt) {
                    file = file.concat("." + Custom._MIME_EXT[0]);
                }
                File tmp = File.createTempFile("custom_", ".mcd");
                tmp.deleteOnExit();
                RandomAccessFile rafTmp = new RandomAccessFile(tmp, "rw");
                RandomAccessFile raf = new RandomAccessFile(file, "rw");
                FileOutputStream fos = new FileOutputStream(rafTmp.getFD());
                ObjectOutputStream oos = new ObjectOutputStream(fos);
                oos.writeObject(custom);
                oos.close();
                fos.close();
                rafTmp.close();
                raf.setLength(tmp.length());
                rafTmp = new RandomAccessFile(tmp, "r");
                byte[] rb = new byte[512];
                int r = 0;
                while ((r = rafTmp.read(rb)) != -1) {
                    raf.write(rb, 0, r);
                }
                raf.close();
                rafTmp.close();
                if (uiMsg) {
                    new UIMessage(true, "The customized template successfully saved to " + file + " !", null, UIMessage.TEMPLATE_TYPE);
                }
                success = true;
            } catch (IOException ex) {
                if (JXAenvUtils._debug) {
                    ex.printStackTrace();
                }
                if (uiMsg) {
                    new UIMessage(true, "An error occurred while attempting to save the customized template : " + ex.getMessage(), null, UIMessage.ERROR_TYPE);
                }
                success = false;
            }
        }
        character.setAttribute(ATTR_CUSTOMIZED, !success);
        if (success) {
            currentFile = new File(file);
            addRecentFile(new File(file));
        }
        if (uiMsg) {
            UIMessage.kill(wait);
        }
        return success;
    }
}
TOP

Related Classes of aba.AnimsBrowser_Ant$MemStatus

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.