package org.korsakow.ide.ui.resources;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultBoundedRangeModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSlider;
import javax.swing.JSplitPane;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.korsakow.domain.interf.IInterface;
import org.korsakow.domain.interf.IMedia;
import org.korsakow.domain.interf.IResource;
import org.korsakow.domain.interf.ISound;
import org.korsakow.domain.interf.ISnu.BackgroundSoundMode;
import org.korsakow.ide.lang.LanguageBundle;
import org.korsakow.ide.resources.ResourceType;
import org.korsakow.ide.ui.components.DelayedMediaPanelLoader;
import org.korsakow.ide.ui.components.KCollapsiblePane;
import org.korsakow.ide.ui.components.KLayoutPanel;
import org.korsakow.ide.ui.components.NewMediaPanel;
import org.korsakow.ide.ui.components.TokenizerTextArea;
import org.korsakow.ide.ui.components.cell.ResourceDOComboBoxRenderer;
import org.korsakow.ide.ui.components.code.CodeTable;
import org.korsakow.ide.ui.components.layout.HorizontalFlowLayout;
import org.korsakow.ide.ui.components.layout.VerticalFlowLayout;
import org.korsakow.ide.ui.components.model.ResourceComboBoxModel;
import org.korsakow.ide.ui.factory.IUIFactory;
import org.korsakow.ide.ui.factory.UIFactory;
import org.korsakow.ide.util.PreferencesManager;
import org.korsakow.ide.util.UIResourceManager;
import org.korsakow.ide.util.UIUtil;
public class SnuResourceView extends ResourceView
{
/**
* TODO: refactor
*/
public static final String INFINITE = "\u221E";
private static final String[] LIVES_CHOICES = {"1", "2", "3", "4", "5", INFINITE};
private static final Long DEFAULT_LIVES = 1L;
/**
* TODO: refactor
*/
public static final String[] MAXLINKS_CHOICES = {"1", "2", "3", "4", "5", INFINITE};
/**
* TODO: refactor
*/
public static final Long DEFAULT_MAXLINKS = null;
private Long mainMediaCustomDuration;
private NewMediaPanel mainMediaPanel;
private Long mainMediaId;
private JCheckBox videoLoopCheck;
private JComboBox backgroundSoundCombo;
private JCheckBox backgroundSoundLoopCheck;
private JComboBox interfaceCombo;
JComboBox livesCombo;
DefaultComboBoxModel livesComboModel;
private JComboBox maxLinksCombo;
private DefaultComboBoxModel maxLinksComboModel;
private JCheckBox startingSnuCheck;
private JCheckBox endingSnuCheck;
private JComboBox previewMediaCombo;
private NewMediaPanel previewMediaPanel;
private JTextField previewTextField;
private JTextField insertTextField;
private CodeTable codeTable;
private JSplitPane mainSplitPane;
private KCollapsiblePane snuCollapse;
private KCollapsiblePane keywordCollapse;
private KCollapsiblePane previewCollapse;
private JSlider ratingSlider;
private JLabel ratingField;
private Object cachedRules;
public SnuResourceView()
{
}
@Override
protected void createUIComponents()
{
// hack until ui is consistent accross the whole app
setBackground(UIManager.getColor("window2"));
setOpaque(true);
UIUtil.runUITaskLater(new Runnable() {
public void run() {
if (getTopLevelAncestor() != null) // timing issues...
((JFrame)getTopLevelAncestor()).getContentPane().setBackground(getBackground());
}
});
// /hack
super.createUIComponents();
IUIFactory uifac = UIFactory.getFactory();
// setLayout(null);
removeAll();
JPanel dummyPanel = new KLayoutPanel();
mainPanel = new KLayoutPanel();
add(mainPanel);
mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
VerticalFlowLayout vlayout = new VerticalFlowLayout(VerticalFlowLayout.TOP, 0, 0);
vlayout.setMaximizeOtherDimension(true);
mainPanel.setLayout(vlayout);
JPanel snuPanel = new KLayoutPanel();
JPanel keywordPanel = new KLayoutPanel();
JPanel previewPanel = new KLayoutPanel();
dummyPanel.add(maxLinksCombo = uifac.createComboBox("maxLinksComboBox", maxLinksComboModel = new DefaultComboBoxModel(MAXLINKS_CHOICES)));
JPanel snuPanelSizer = uifac.customComponent("snuSettingPanelSizer", new JPanel());
//This causes the snuPanel to stretch nicely. I make it invisible not to interfere with the real widgets.
//This presumes that the size of an invisible panel is considered when sizing snuPanel.
snuPanelSizer.setVisible(false);
snuPanel.add(snuPanelSizer);
snuPanel.add(uifac.createLabel("backgroundSoundLabel", LanguageBundle.getString("snuresourceview.backgroundsound.label")));
snuPanel.add(backgroundSoundCombo = uifac.createComboBox("backgroundSoundPanel", new ResourceComboBoxModel(false), new ResourceDOComboBoxRenderer()));
backgroundSoundCombo.setEditable(false);
// snuPanel.add(uifac.createLabel("backgroundSoundLoopLabel", LanguageBundle.getString("snuresourceview.mainmediapanel.backgroundsoundloop.label")));
snuPanel.add(backgroundSoundLoopCheck = uifac.createCheckBox("backgroundSoundLoopCheck", LanguageBundle.getString("snuresourceview.backgroundsound.loop.label")));
backgroundSoundLoopCheck.setHorizontalTextPosition(JCheckBox.LEFT);
snuPanel.add(uifac.createLabel("livesLabel", LanguageBundle.getString("snuresourceview.lives.label")));
snuPanel.add(livesCombo = uifac.createComboBox("livesComboBox", livesComboModel = new DefaultComboBoxModel(LIVES_CHOICES)));
livesCombo.setEditable(true);
JPanel bottomPanel = new JPanel();
bottomPanel.setBounds(10, 95, 500, 23);
snuPanel.add(bottomPanel);
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.X_AXIS));
// bottomPanel.setLayout(new HorizontalFlowLayout(HorizontalFlowLayout.LEFT));
bottomPanel.add(uifac.createLabel("ratingLabel", LanguageBundle.getString("snuresourceview.rating.label")));
bottomPanel.add(Box.createHorizontalStrut(5));
ratingSlider = uifac.createSlider("ratingSlider", new DefaultBoundedRangeModel(0, 0, 0, 100));
ratingSlider.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent event) {
ratingField.setText(String.format("%2.2f", (RatingCalculator.calculate(ratingSlider.getValue()/100.0f))));
}
});
ratingField = uifac.createLabel("ratingField");
ratingField.setHorizontalAlignment(JLabel.CENTER);
ratingField.setBorder(BorderFactory.createLineBorder(Color.gray));
JPanel ratingBorder = new JPanel(new HorizontalFlowLayout(HorizontalFlowLayout.LEFT, 0, 0));
ratingBorder.setLayout(new BoxLayout(ratingBorder, BoxLayout.X_AXIS));
ratingBorder.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.gray),
BorderFactory.createEmptyBorder(3, 5, 3, 0)
));
bottomPanel.add(ratingBorder);
ratingBorder.add(ratingSlider);
ratingBorder.add(ratingField);
bottomPanel.add(Box.createHorizontalStrut(100));
bottomPanel.add(Box.createHorizontalGlue());
// bottomPanel.add(ratingBorder = uifac.customComponent("ratingBorder", new JPanel()));
// ratingBorder.setBorder(BorderFactory.createLineBorder(Color.gray));
ratingSlider.setValue(10);
JPanel topPanel = new JPanel();
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.X_AXIS));
snuPanel.add(topPanel);
topPanel.setBounds(10, 14, 500, 23);
topPanel.add(uifac.createLabel("startingSnuLabel", LanguageBundle.getString("snuresourceview.startingsnu.label")));
topPanel.add(Box.createHorizontalStrut(5));
topPanel.add(startingSnuCheck = uifac.createCheckBox("startingSnuCheckBox"));
topPanel.add(Box.createHorizontalStrut(20));
topPanel.add(uifac.createLabel("endingSnuLabel", LanguageBundle.getString("snuresourceview.endingsnu.label")));
topPanel.add(Box.createHorizontalStrut(5));
topPanel.add(endingSnuCheck = new JCheckBox());
topPanel.add(Box.createHorizontalStrut(20));
topPanel.add(new JLabel(LanguageBundle.getString("snuresourceview.mainmediapanel.loop.label")));
topPanel.add(Box.createHorizontalStrut(5));
topPanel.add(videoLoopCheck = new JCheckBox());
topPanel.add(Box.createHorizontalGlue());
snuPanel.add(uifac.createLabel("interfaceLabel", LanguageBundle.getString("snuresourceview.interface.label")));
snuPanel.add(interfaceCombo = uifac.createComboBox("interfacePanel", new ResourceComboBoxModel(true), new ResourceDOComboBoxRenderer()));
snuPanel.add(uifac.createLabel("insertTextLabel", LanguageBundle.getString("snuresourceview.inserttext.label")));
snuPanel.add(insertTextField = uifac.createTextField("insertTextField"));
JPanel keywordPanelSizer = uifac.customComponent("keywordPanelSizer", new JPanel());
keywordPanelSizer.setVisible(false);
keywordPanel.add(keywordPanelSizer);
codeTable = new CodeTable();
JScrollPane codeScroll = uifac.customComponent("k3Rules", new JScrollPane(codeTable));
codeScroll.setPreferredSize(new Dimension(600, 200));
// setting the border results in the LaF's default border, not no border
codeScroll.setBorder(BorderFactory.createEmptyBorder());
// stop cell editing when clicking outside the table bounds
codeScroll.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent event) {
if (codeTable.getCellEditor() != null)
codeTable.getCellEditor().stopCellEditing();
}
});
keywordPanel.add(uifac.createLabel("k3RulesLabel", LanguageBundle.getString("snuresourceview.outkeywords.label"), UIResourceManager.getIcon(UIResourceManager.ICON_SNU_OUT)));
keywordPanel.add(codeScroll);
keywordPanel.add(inKeywordLabel);
keywordPanel.add(inKeywordBox);
inKeywordBox.setFocusBackgroundColor(new Color(0xee1b23));
inKeywordBox.setFocusForegroundColor(Color.white);
inKeywordBox.setBorder(new JTextField().getBorder());
JPanel previewPanelSizer = uifac.customComponent("previewPanelSizer", new JPanel());
previewPanelSizer.setVisible(false);
previewPanel.add(previewPanelSizer);
previewPanel.add(uifac.createLabel("previewMediaLabel", LanguageBundle.getString("snuresourceview.previewmedia.label")));
previewPanel.add(previewMediaCombo = uifac.createComboBox("previewMediaCombo", new ResourceComboBoxModel(true), new ResourceDOComboBoxRenderer()));
previewMediaCombo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
setPreviewMedia(getPreviewMedia());
}
});
previewPanel.add(previewMediaPanel = uifac.customComponent("previewMediaPanel", new NewMediaPanel()));
previewPanel.add(uifac.createLabel("previewTextLabel", LanguageBundle.getString("snuresourceview.previewtext.label")));
previewPanel.add(previewTextField = uifac.createTextField("previewTextField"));
mainPanel.add(nameField);
mainPanel.add(mainMediaPanel = uifac.customComponent("mainMedia", new NewMediaPanel()));
// mainPanel.add(mainSplitPane = uifac.createSplitPane("mainSplitPane"));
mainPanel.add(keywordCollapse = uifac.customComponent("keywordPanel", new KCollapsiblePane(LanguageBundle.getString("resourceview.tab.keywords.label"), keywordPanel)));
mainPanel.add(previewCollapse = uifac.customComponent("previewPanel", new KCollapsiblePane(LanguageBundle.getString("snuresourceview.tab.preview.label"), previewPanel)));
mainPanel.add(snuCollapse = uifac.customComponent("snuPanel", new KCollapsiblePane(LanguageBundle.getString("snuresourceview.snusettings.label"), snuPanel)));
UIUtil.runUITaskLater(new Runnable() { // this is run later because we set the windows' size based on its panel's preferred size and we want the full size
public void run() {
snuCollapse.setExpanded(PreferencesManager.getPreferences(SnuResourceView.class).getBoolean("snuCollapse", true));
keywordCollapse.setExpanded(PreferencesManager.getPreferences(SnuResourceView.class).getBoolean("keywordCollapse", true));
previewCollapse.setExpanded(PreferencesManager.getPreferences(SnuResourceView.class).getBoolean("previewCollapse", true));
}
});
}
@Override
protected void layoutUIComponents()
{
super.layoutUIComponents();
IUIFactory uifac = UIFactory.getFactory();
LayoutManager layout = uifac.createLayout("snuresourceview");
snuCollapse.getContent().setLayout(layout);
keywordCollapse.getContent().setLayout(layout);
previewCollapse.getContent().setLayout(layout);
Dimension mainMediaSize = new Dimension(481, 270);
mainMediaPanel.setPreferredSize(mainMediaSize);
mainMediaPanel.setMaximumSize(mainMediaSize);
mainMediaPanel.setMinimumSize(mainMediaSize);
}
@Override
protected void initUI()
{
super.initUI2();
}
@Override
protected void initListeners()
{
super.initListeners();
livesCombo.getEditor().getEditorComponent().addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
onLivesFocusLost();
}
});
maxLinksCombo.getEditor().getEditorComponent().addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent e) {
onMaxLinksFocusLost();
}
});
}
public TokenizerTextArea getKeywordArea()
{
return inKeywordBox;
}
public CodeTable getCodeTable()
{
return codeTable;
}
public NewMediaPanel getMainMediaPanel()
{
return mainMediaPanel;
}
private void onLivesFocusLost()
{
Object value = livesCombo.getSelectedItem();
if (value == null)
livesCombo.setSelectedItem(INFINITE);
else {
try {
livesCombo.setSelectedItem(Long.parseLong(value.toString()));
} catch (NumberFormatException e) {
livesCombo.setSelectedItem(INFINITE);
}
}
}
private void onMaxLinksFocusLost()
{
Object value = maxLinksCombo.getSelectedItem();
if (value == null)
maxLinksCombo.setSelectedItem(INFINITE);
else {
try {
maxLinksCombo.setSelectedItem(Long.parseLong(value.toString()));
} catch (NumberFormatException e) {
maxLinksCombo.setSelectedItem(INFINITE);
}
}
}
public void setMainMedia(final IMedia media)
{
mainMediaId = media.getId();
DelayedMediaPanelLoader.load(this, mainMediaPanel, media);
}
public Long getMainMediaId()
{
return mainMediaId;
}
public void setInterfaceChoices(Collection<IInterface> choices)
{
interfaceCombo.setModel(new ResourceComboBoxModel(choices, false));
}
public void setInterface(IInterface interf)
{
interfaceCombo.setSelectedItem(interf);
repaint();
}
private IInterface getInterface()
{
return (IInterface)interfaceCombo.getSelectedItem();
}
public Long getInterfaceId()
{
return getInterface()!=null?getInterface().getId():null;
}
public void setBackgroundSoundChoices(Collection<ISound> choices)
{
List<Object> c = new ArrayList<Object>();
c.add(BackgroundSoundMode.KEEP);
c.add(BackgroundSoundMode.CLEAR);
c.addAll(choices);
backgroundSoundCombo.setModel(new ResourceComboBoxModel(c));
}
public void setBackgroundSound(Object sound)
{
backgroundSoundCombo.setSelectedItem(sound);
}
public BackgroundSoundMode getBackgroundSoundMode()
{
if ( backgroundSoundCombo.getSelectedItem() instanceof IResource &&
ResourceType.SOUND.isInstance( (IResource)backgroundSoundCombo.getSelectedItem() ))
return BackgroundSoundMode.SET;
else
return (BackgroundSoundMode)backgroundSoundCombo.getSelectedItem();
}
/**
* Valid to call only when BackgroundSoundMode == SET
*/
public Long getBackgroundSoundId()
{
return ((ISound)backgroundSoundCombo.getSelectedItem()).getId();
}
public void addBackgroundSoundChangeListener( ActionListener listener ) {
backgroundSoundCombo.addActionListener( listener );
}
public boolean getBackgroundSoundLooping()
{
return backgroundSoundLoopCheck.isSelected();
}
public void setBackgroundSoundLoop(boolean loop)
{
backgroundSoundLoopCheck.setSelected(loop);
}
public void setPreviewMediaChoices(Collection<IMedia> choices)
{
previewMediaCombo.setModel(new ResourceComboBoxModel(choices, true));
}
public void setPreviewMedia(final IMedia media)
{
previewMediaCombo.setSelectedItem(media);
DelayedMediaPanelLoader.load(this, previewMediaPanel, media);
}
private IMedia getPreviewMedia()
{
return (IMedia)previewMediaCombo.getSelectedItem();
}
public Long getPreviewMediaId()
{
return getPreviewMedia()!=null?getPreviewMedia().getId():null;
}
public String getPreviewText()
{
return previewTextField.getText();
}
public void setPreviewText(String text)
{
previewTextField.setText(text);
}
public String getInsertText()
{
return insertTextField.getText();
}
public void setInsertText(String text)
{
insertTextField.setText(text);
}
public Long getLives()
{
return getComboLong(livesCombo, DEFAULT_LIVES);
}
public void setLives(Long lives)
{
livesCombo.setSelectedItem(lives!=null?(""+lives):""+INFINITE);
}
public Long getMaxLinks()
{
return getComboLong(maxLinksCombo, DEFAULT_MAXLINKS);
}
public void setMaxLinks(Long maxLinks)
{
maxLinksCombo.setSelectedItem(maxLinks!=null?(""+maxLinks):""+INFINITE);
}
public void setRating(float rating)
{
ratingSlider.setValue((int)(RatingCalculator.inverse(rating)*100));
}
public float getRating()
{
return RatingCalculator.calculate(ratingSlider.getValue()/100.0f);
}
public void setLooping(boolean loop)
{
videoLoopCheck.setSelected(loop);
}
public boolean getLooping()
{
return videoLoopCheck.isSelected();
}
public JCheckBox getStarerCheck()
{
return startingSnuCheck;
}
public boolean getStarter()
{
return startingSnuCheck.isSelected();
}
public void setStarter(boolean starter)
{
startingSnuCheck.setSelected(starter);
}
public JCheckBox getEnderCheck()
{
return endingSnuCheck;
}
public boolean getEnder()
{
return endingSnuCheck.isSelected();
}
public void setEnder(boolean ender)
{
endingSnuCheck.setSelected(ender);
}
public void setCachedRules(Object cachedRules)
{
this.cachedRules = cachedRules;
}
public Object getCachedRules()
{
return cachedRules;
}
public void setMainMediaCustomDuration( long duration ) {
mainMediaPanel.setDuration( duration );
mainMediaCustomDuration = duration;
}
public Long getMainMediaCustomDuration() {
return mainMediaCustomDuration;
}
/**
* TODO: refactor me
* @param combo
* @param defaultValue
* @return
*/
public static Long getComboLong(JComboBox combo, Long defaultValue)
{
Object value = combo.getSelectedItem();
if (value == null || value.equals(INFINITE))
return null;
else {
try {
return Long.parseLong(value.toString());
} catch (NumberFormatException e) {
return defaultValue;
}
}
}
@Override
public void dispose()
{
super.dispose();
PreferencesManager.getPreferences(SnuResourceView.class).putBoolean("snuCollapse", snuCollapse.isExpanded());
PreferencesManager.getPreferences(SnuResourceView.class).putBoolean("keywordCollapse", keywordCollapse.isExpanded());
PreferencesManager.getPreferences(SnuResourceView.class).putBoolean("previewCollapse", previewCollapse.isExpanded());
// if (mainMedia != null) {
mainMediaPanel.dispose();
// }
previewMediaPanel.dispose();
}
}