package nl.fontys.sofa.limo.view.topcomponent;
import java.awt.HeadlessException;
import java.awt.event.ActionEvent;
import java.io.File;
import java.io.IOException;
import java.rmi.activation.ActivateFailedException;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
import javax.swing.filechooser.FileNameExtensionFilter;
import nl.fontys.sofa.limo.domain.component.SupplyChain;
import nl.fontys.sofa.limo.view.InvalidSupplyChainException;
import nl.fontys.sofa.limo.view.chain.ChainBuilder;
import nl.fontys.sofa.limo.view.util.ChainSaveFileChooser;
import org.apache.commons.io.FilenameUtils;
import org.netbeans.spi.actions.AbstractSavable;
import org.openide.DialogDescriptor;
import org.openide.DialogDisplayer;
import org.openide.NotifyDescriptor;
import org.openide.util.ImageUtilities;
import org.openide.util.lookup.InstanceContent;
import org.openide.windows.TopComponent;
/**
* SavableComponent enables saving of a supply chain.
*
* @author Sebastiaan Heijmann
*/
public class SavableComponent extends AbstractSavable {
private final ChainBuilder chainBuilder;
private final SupplyChain supplyChain;
private final InstanceContent ic;
private final TopComponent parent;
private boolean isAdded = false;
/**
* Constructor creates a new SavableComponent.
*
* @param chainBuilder the chain builder which contains the supply chains.
*/
public SavableComponent(ChainBuilder chainBuilder, InstanceContent ic, TopComponent parent) {
this.chainBuilder = chainBuilder;
this.supplyChain = chainBuilder.getSupplyChain();
this.ic = ic;
this.parent = parent;
chainBuilder.addListener((ActionEvent e) -> {
if (isAdded) {
return;
}
ImageIcon saveIcon = new ImageIcon(getClass().getClassLoader().getResource("icons/gui/save.png"));
parent.setIcon(ImageUtilities.icon2Image(saveIcon));
parent.getParent().revalidate();
ic.add(this);
register();
isAdded = true;
});
}
@Override
protected String findDisplayName() {
return supplyChain.getName().replace(".lsc", "");
}
public void removeSavable() {
ic.remove(this);
unregister();
ImageIcon link = new ImageIcon(getClass().getClassLoader().getResource("icons/gui/Link.png"));
parent.setIcon(ImageUtilities.icon2Image(link));
parent.getParent().revalidate();
isAdded = false;
}
private void saveComponent() throws IOException {
if (chainBuilder.validate()) {
if (supplyChain.getFilepath() != null) {
NotifyDescriptor dd = new NotifyDescriptor.Confirmation("Would you like to overwrite the '" + supplyChain.getName().replace(".lsc", "") + "' supply chain file?");
dd.setMessageType(DialogDescriptor.YES_NO_CANCEL_OPTION);
Object retval = DialogDisplayer.getDefault().notify(dd);
if (retval.equals(DialogDescriptor.YES_OPTION)) {
supplyChain.saveToFile();
removeSavable();
} else if (retval.equals(DialogDescriptor.NO_OPTION)) {
openFileChooser();
} else if (retval.equals(DialogDescriptor.CANCEL_OPTION)) {
throw new ActivateFailedException("The chain should not close because of the canClose method in topComponent");
}
} else { //If a new supply chain needs to be saved.
openFileChooser();
}
} else { //When the supply chain is invalid, display a dialog.
DialogDescriptor dialogDescriptor = new DialogDescriptor("The supply chain " + supplyChain.getName().replace(".lsc", "")
+ " is invalid. An invalid supply chain cannot be saved. Please close the window and make the supply chain valid.", "Error while saving");
dialogDescriptor.setMessageType(DialogDescriptor.PLAIN_MESSAGE);
dialogDescriptor.setOptions(new Object[]{DialogDescriptor.OK_OPTION});
Object retval = DialogDisplayer.getDefault().notify(dialogDescriptor);
if (retval.equals(DialogDescriptor.OK_OPTION)) { //Throw an exception when the OK-button is selected so the saving process is cancelled
throw new InvalidSupplyChainException("The supply chain " + supplyChain.getName().replace(".lsc", "") + " is invalid.");
}
}
}
private void openFileChooser() throws HeadlessException, IOException {
JFileChooser fc = new ChainSaveFileChooser();
FileNameExtensionFilter chainFilter = new FileNameExtensionFilter(
"Supply chains (*.lsc)", "lsc");
if (supplyChain.getFilepath() != null) { //This happens if a supply chain is loaded.
fc.setCurrentDirectory(new File(supplyChain.getFilepath()));
}
fc.setFileFilter(chainFilter);
fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
fc.setSelectedFile(new File(FilenameUtils.removeExtension(supplyChain.getName()))); // This sets the name without the extension
int result = fc.showOpenDialog(null);
String fileName = fc.getSelectedFile().getName(); //name with extension
if (result == JFileChooser.APPROVE_OPTION) { //If folder is selected than save the supply chain.
supplyChain.setName(fileName);
File file = fc.getSelectedFile();
if (supplyChain.getName().endsWith(".lsc")) {
supplyChain.setFilepath(file.getParent() + File.separator + supplyChain.getName());
} else {
supplyChain.setFilepath(file.getParent() + File.separator + supplyChain.getName() + ".lsc");
}
supplyChain.saveToFile();
removeSavable();
} else { //If no folder is selected throw an exception so the saving process is cancelled.
throw new IOException("The supply chain " + supplyChain.getName() + " is invalid.");
}
}
@Override
public boolean equals(Object obj) {
if (obj instanceof SavableComponent) {
return ((SavableComponent) obj).supplyChain.equals(supplyChain);
}
return false;
}
/*@Override
public String toString() {
return supplyChain.getName().replace(".lsc", "");
}*/
@Override
public int hashCode() {
return supplyChain.hashCode();
}
@Override
protected void handleSave() throws IOException {
saveComponent();
}
}