package com.intellij.lang.javascript.flex.projectStructure.ui;
import com.intellij.lang.javascript.flex.projectStructure.model.ModifiableFlexBuildConfiguration;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.options.ConfigurationException;
import com.intellij.openapi.roots.ui.configuration.projectRoot.ProjectStructureElementConfigurable;
import com.intellij.openapi.roots.ui.configuration.projectRoot.daemon.ProjectStructureElement;
import com.intellij.openapi.ui.NamedConfigurable;
import com.intellij.openapi.util.ActionCallback;
import com.intellij.openapi.util.Disposer;
import com.intellij.ui.IdeBorderFactory;
import com.intellij.ui.TabbedPaneWrapper;
import com.intellij.ui.navigation.History;
import com.intellij.ui.navigation.Place;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
/**
* @author ksafonov
*/
public class CompositeConfigurable extends ProjectStructureElementConfigurable<ModifiableFlexBuildConfiguration> implements Place.Navigator {
public static final String TAB_NAME = "tabName";
public interface Item {
String getTabTitle();
}
private final FlexBCConfigurable myMainChild;
private final List<NamedConfigurable> myChildren = new ArrayList<>();
private final Disposable myDisposable = Disposer.newDisposable();
private final TabbedPaneWrapper myTabs;
public CompositeConfigurable(FlexBCConfigurable mainChild, List<NamedConfigurable> otherChildren, Runnable updateTree) {
super(false, updateTree);
myMainChild = mainChild;
myTabs = new TabbedPaneWrapper(myDisposable);
myChildren.add(mainChild);
myChildren.addAll(otherChildren);
}
@Override
public void setDisplayName(String name) {
getMainChild().setDisplayName(name);
}
public FlexBCConfigurable getMainChild() {
return myMainChild;
}
@Override
public ModifiableFlexBuildConfiguration getEditableObject() {
return getMainChild().getEditableObject();
}
@Override
public String getBannerSlogan() {
return getMainChild().getBannerSlogan();
}
@Override
public JComponent createOptionsPanel() {
for (NamedConfigurable child : myChildren) {
addTab(child);
}
return myTabs.getComponent();
}
private void addTab(final NamedConfigurable child) {
JPanel p = new JPanel(new BorderLayout());
p.setBorder(IdeBorderFactory.createEmptyBorder(5));
p.add(child.createComponent(), BorderLayout.CENTER);
String tabName = child instanceof Item ? ((Item)child).getTabTitle() : child.getDisplayName();
myTabs.addTab(tabName, p);
}
public List<NamedConfigurable> getChildren() {
return myChildren;
}
public void addChild(final NamedConfigurable child) {
myChildren.add(child);
addTab(child);
}
public void removeChildAt(final int index) {
myChildren.remove(index);
myTabs.removeTabAt(index);
}
@Nls
@Override
public String getDisplayName() {
return getMainChild().getDisplayName();
}
@Override
public Icon getIcon(boolean expanded) {
return FlexBCConfigurable.unwrap(this).getIcon();
}
@Override
public String getHelpTopic() {
final String helpTopic = myChildren.get(myTabs.getSelectedIndex()).getHelpTopic();
return helpTopic != null ? helpTopic : getMainChild().getHelpTopic();
}
@Override
public boolean isModified() {
//for (NamedConfigurable child : myChildren) {
// if (child.isModified()) return true;
//}
//return false;
return getMainChild().isModified();
}
@Override
public void apply() throws ConfigurationException {
//for (NamedConfigurable child : myChildren) {
// child.apply();
//}
getMainChild().apply();
}
@Override
public void reset() {
//for (NamedConfigurable child : myChildren) {
// child.reset();
//}
getMainChild().reset();
}
@Override
public void disposeUIResources() {
//for (NamedConfigurable child : myChildren) {
// child.disposeUIResources();
//}
getMainChild().disposeUIResources();
Disposer.dispose(myDisposable);
}
@Override
public void setHistory(final History history) {
}
@Override
public ActionCallback navigateTo(@Nullable final Place place, final boolean requestFocus) {
if (place == null) {
return ActionCallback.DONE;
}
final Object tabName = place.getPath(TAB_NAME);
if (tabName instanceof String) {
for (int i = 0; i < myChildren.size(); i++) {
final NamedConfigurable child = myChildren.get(i);
if (tabName.equals(child.getDisplayName())) {
myTabs.setSelectedIndex(i);
return Place.goFurther(child, place, requestFocus);
}
}
}
return ActionCallback.DONE;
}
@Override
public void queryPlace(@NotNull final Place place) {
final NamedConfigurable child = myChildren.get(myTabs.getSelectedIndex());
place.putPath(TAB_NAME, child.getDisplayName());
//Place.queryFurther(child, place); we don't want to localize place to text field level (and actually it is impossible because the field hasn't got focus yet when this method is called)
}
@Override
@Nullable
public ProjectStructureElement getProjectStructureElement() {
NamedConfigurable mainChild = getMainChild();
if (mainChild instanceof ProjectStructureElementConfigurable) {
return ((ProjectStructureElementConfigurable)mainChild).getProjectStructureElement();
}
return null;
}
}