package fi.utu.ville.exercises.stub;
import java.util.HashSet;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Button.ClickListener;
import com.vaadin.ui.Component;
import com.vaadin.ui.HorizontalLayout;
import com.vaadin.ui.Label;
import com.vaadin.ui.Layout;
import com.vaadin.ui.Panel;
import com.vaadin.ui.TextArea;
import com.vaadin.ui.TextField;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
import com.vaadin.ui.Window;
import com.vaadin.ui.themes.BaseTheme;
import fi.utu.ville.exercises.helpers.TestingExecutionSettings;
import fi.utu.ville.exercises.model.EditorHelper;
import fi.utu.ville.exercises.model.Executor;
import fi.utu.ville.exercises.model.ExerciseData;
import fi.utu.ville.exercises.model.ExerciseException;
import fi.utu.ville.exercises.model.ExerciseSaveListener;
import fi.utu.ville.exercises.model.ExerciseTypeDescriptor;
import fi.utu.ville.exercises.model.GeneralExerciseInfo;
import fi.utu.ville.standardutils.Localizer;
import fi.utu.ville.standardutils.StandardUIFactory;
import fi.utu.ville.standardutils.TempFilesManager;
import fi.utu.ville.standardutils.ui.CleanRichTextArea;
/**
* Stub-implementor for {@link EditorHelper} that provides {@link Editor}s with certain necessary services.
*
* @author Riku Haavisto
*
*/
class EditorHelperStubImpl<E extends ExerciseData> implements EditorHelper<E> {
/**
*
*/
private static final long serialVersionUID = 1533013485600936320L;
// to keep track that the editor was actually shown to user;
// this must be done in real ville to allow the teacher to edit
// certain data like notes for other teachers on the newly created exercise
private boolean editorWasShown;
private final Localizer localizer;
private EditedExerciseGiver<E> exerDataParser = null;
private final ExerciseTypeDescriptor<E, ?> typeDesc;
private final ControlButtons contLayout;
private final TempFilesManager tempManager;
private final EditorView editorView;
private final HashSet<ExerciseSaveListener<E>> listeners = new HashSet<ExerciseSaveListener<E>>();
private boolean hasUnsavedChanges = false;
public EditorHelperStubImpl(GeneralExerciseInfo exerInfo,
Localizer localizer, ExerciseTypeDescriptor<E, ?> typeDesc,
TempFilesManager tempManager) {
this.localizer = localizer;
this.typeDesc = typeDesc;
this.tempManager = tempManager;
this.editorView = new EditorView(exerInfo);
this.contLayout = new ControlButtons();
}
@Override
public GeneralExerciseInfo getExerciseInfo() {
return new GeneralExerciseInfoStubImpl(editorView.getName(),
editorView.getExerDescription());
}
@Override
public Component getInfoEditorView() {
return editorView;
}
@Override
public TempFilesManager getTempManager() {
return tempManager;
}
boolean wasShown() {
return editorWasShown;
}
@Override
public Layout getTestingExerciseView(Executor<?, ?> toTest) {
return TestingExerciseView.getViewForTestingInEditor(toTest,
getExerciseInfo(), localizer, tempManager);
}
@Override
public void goBack() {
UI.getCurrent().setContent(new StubStartView());
}
@Override
public void setTestEnabled(boolean enabled) {
contLayout.testButton.setEnabled(enabled);
}
@Override
public void setSaveEnabled(boolean enabled) {
contLayout.saveButton.setEnabled(enabled);
}
@Override
public void registerExerSaveListener(ExerciseSaveListener<E> saveListener) {
listeners.add(saveListener);
}
@Override
public void informSaveListeners(E dataToSave) {
for (ExerciseSaveListener<E> listener : listeners) {
listener.actOnExerciseTypeSave(dataToSave);
}
}
@Override
public Component getControlbar(EditedExerciseGiver<E> toRegister) {
exerDataParser = toRegister;
return contLayout;
}
/**
* <p>
* Stub-implementation for editor control-bar.
* </p>
* <p>
* The look and feel of the editor control-bar is (and should be) the same as in real-Ville.
* </p>
*
* @author Riku Haavisto
*
*/
private class ControlButtons extends HorizontalLayout {
/**
*
*/
private static final long serialVersionUID = -966408303275424357L;
private final Button saveButton;
private final Button testButton;
private final Button cancelButton;
public ControlButtons() {
setWidth("100%");
setMargin(false);
// HorizontalLayout buttonLayout = new HorizontalLayout();
// buttonLayout.setSpacing(false);
saveButton = StandardUIFactory.getSaveButton(localizer);
testButton = StandardUIFactory.getTestButton(localizer);
cancelButton = StandardUIFactory.getCloseButton(localizer);
cancelButton.addClickListener(new Button.ClickListener() {
/**
*
*/
private static final long serialVersionUID = -5183123395118709055L;
@Override
public void buttonClick(ClickEvent event) {
goBack();
}
});
saveButton.addClickListener(new Button.ClickListener() {
/**
*
*/
private static final long serialVersionUID = 1830860710406665375L;
@Override
public void buttonClick(ClickEvent event) {
if (exerDataParser != null) {
E data = exerDataParser.getCurrExerData(true);
if (data != null) {
informSaveListeners(data);
}
clearUnSubmChangesFlag();
}
}
});
testButton.addClickListener(new Button.ClickListener() {
/**
*
*/
private static final long serialVersionUID = 5616753173844822725L;
@Override
public void buttonClick(ClickEvent event) {
Executor<E, ?> execToUse = typeDesc.newExerciseExecutor();
if (exerDataParser != null) {
E data = exerDataParser.getCurrExerData(false);
if (data != null) {
try {
execToUse.initialize(localizer, data, null,
tempManager,
TestingExecutionSettings.INSTANCE);
} catch (ExerciseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
execToUse = null;
}
Component testView = getTestingExerciseView(execToUse);
Window testWindow = new Window();
testWindow.setModal(true);
testWindow.setWidth("90%");
testWindow.setHeight("90%");
testWindow.addStyleName("opaque");
testWindow.setContent(testView);
testWindow.center();
UI.getCurrent().addWindow(testWindow);
}
}
}
});
addComponent(StandardUIFactory.getButtonPanel(testButton,
saveButton, cancelButton));
// buttonLayout.addComponent(saveButton);
// buttonLayout.addComponent(testButton);
// buttonLayout.addComponent(cancelButton);
//
// addComponent(buttonLayout);
// setComponentAlignment(buttonLayout, Alignment.MIDDLE_CENTER);
}
}
/**
* <p>
* A stub-implementation for a view allowing teacher to edit general properties of an exercise, its name, description and notes for other teachers.
* </p>
* <p>
* This view is similar and look-and-feel and size to its real counterpart. Editor UI looks the same in stub as it does in real-Ville.
* </p>
*
* @author Riku Haavisto
*
*/
private class EditorView extends VerticalLayout implements ClickListener {
private static final long serialVersionUID = 7155855298442571450L;
private TextField exerciseName;
private Label descriptionLabel;
private CleanRichTextArea description;
private Label notesLabel;
private TextArea notes;
private Button hideShowButton;
private boolean showDescriptions;
private final boolean showNotes = true;
public EditorView(GeneralExerciseInfo exerInfo) {
String name = exerInfo.getName();
String desc = exerInfo.getDescription();
String notes = localizer
.getUIText(StubUiConstants.NO_NOTES_FOR_TEACHERS_IN_STUB);
doLayout("", name, desc, notes);
}
@Override
public void attach() {
super.attach();
editorWasShown = true;
}
private void doLayout(String caption, String name, String desc,
String notesForTeachers) {
setSpacing(true);
this.setWidth("100%");
showDescriptions = true;
Panel p = new Panel(caption);
p.setWidth("100%");
p.addStyleName("bubble");
p.addStyleName("info-panel-bolded");
VerticalLayout pLayout = new VerticalLayout();
pLayout.setMargin(true);
pLayout.setSpacing(true);
pLayout.setWidth("100%");
exerciseName = new TextField();
exerciseName.setWidth("100%");
exerciseName.setValue(name);
exerciseName.addStyleName("component-margin-bottom");
pLayout.addComponent(new Label(localizer
.getUIText(StubUiConstants.EXERCISE_NAME)));
pLayout.addComponent(exerciseName);
description = new CleanRichTextArea();
description.setWidth("100%");
description.setHeight("200px");
description.setValue(desc);
description.addStyleName("component-margin-bottom");
descriptionLabel = new Label(
localizer.getUIText(StubUiConstants.DEFAULT_DESCRIPTION));
pLayout.addComponent(descriptionLabel);
pLayout.addComponent(description);
notes = new TextArea();
notes.setWidth("100%");
notes.setRows(3);
notes.setValue(notesForTeachers);
notes.addStyleName("component-margin-bottom");
notesLabel = new Label(
localizer.getUIText(StubUiConstants.NOTES_FOR_TEACHERS));
pLayout.addComponent(notesLabel);
pLayout.addComponent(notes);
hideShowButton = new Button(
localizer.getUIText(StubUiConstants.HIDE_DESCRIPTIONS));
hideShowButton.addClickListener(this);
hideShowButton.setStyleName(BaseTheme.BUTTON_LINK);
pLayout.addComponent(hideShowButton);
p.setContent(pLayout);
this.addComponent(p);
}
public String getName() {
return exerciseName.getValue().replaceAll("\\W", "");
}
public String getExerDescription() {
return description.getValue();
}
public void setName(String name) {
exerciseName.setValue(name);
}
public void setExerciseDescription(String description) {
this.description.setValue(description);
}
@Override
public void buttonClick(ClickEvent event) {
if (event.getSource() == hideShowButton) {
hideShowDescriptions();
}
}
private void hideShowDescriptions() {
showDescriptions = !showDescriptions;
descriptionLabel.setVisible(showDescriptions);
description.setVisible(showDescriptions);
if (showNotes) {
notesLabel.setVisible(showDescriptions);
notes.setVisible(showDescriptions);
}
if (showDescriptions) {
hideShowButton.setCaption(localizer
.getUIText(StubUiConstants.HIDE_DESCRIPTIONS));
} else {
hideShowButton.setCaption(localizer
.getUIText(StubUiConstants.SHOW_DESCRIPTIONS));
}
}
}
@Override
public void setExerciseName(String name) {
editorView.setName(name);
}
@Override
public void setExerciseDescription(String description) {
editorView.setExerciseDescription(description);
}
@Override
public boolean hasUnsubmittedChanges() {
return hasUnsavedChanges;
}
@Override
public void clearUnSubmChangesFlag() {
hasUnsavedChanges = false;
}
@Override
public void setUnSubmChangesFlag() {
hasUnsavedChanges = true;
}
}