package regexgolf2.ui.wordrepository.wordcell;
import java.util.EventObject;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ReadOnlyBooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import regexgolf2.model.ObjectChangedListener;
import regexgolf2.model.Word;
import regexgolf2.services.persistence.changetracking.PersistenceState;
import com.google.java.contract.Ensures;
import com.google.java.contract.Requires;
public class WordItem
{
private final StringProperty _text = new SimpleStringProperty();
private final BooleanProperty _isChanged = new SimpleBooleanProperty();
private final BooleanProperty _isOutOfSynch = new SimpleBooleanProperty();
private final Word _word;
private final PersistenceState _ps;
private ObjectChangedListener _listener;
@Requires({
"word != null",
"ps != null",
"ps.getObservedItem() == word"
})
public WordItem(Word word, PersistenceState ps)
{
_word = word;
_ps = ps;
_text.set(_word.getText());
_isChanged.set(ps.isChanged());
initListeners();
}
private void initListeners()
{
_text.addListener(new ChangeListener<String>()
{
@Override
public void changed(ObservableValue<? extends String> o,
String oV, String nV)
{
//FIXME this does not work, fix
boolean success = _word.trySetText(nV);
_isOutOfSynch.set(!success);
}
});
_listener = new ObjectChangedListener()
{
@Override
public void objectChanged(EventObject event)
{
_text.set(_word.getText());
_isChanged.set(_ps.isChanged());
}
};
_word.addObjectChangedListener(_listener);
_ps.addObjectChangedListener(_listener);
}
@Ensures("result != null")
public Word getWord()
{
return _word;
}
@Ensures("result != null")
public StringProperty textProperty()
{
return _text;
}
@Ensures("result != null")
public ReadOnlyBooleanProperty isChangedProperty()
{
return _isChanged;
}
/**
* Indicates that the Text inside the Item and the Text inside the
* Word are out of synch.
* This occurs if a Text is entered for which a Word already exists
*(duplicate words are not allowed).
*/
public boolean isOutOfSynch()
{
return _isOutOfSynch.get();
}
@Ensures("result != null")
public ReadOnlyBooleanProperty isOutOfSynchPropery()
{
return _isOutOfSynch;
}
/**
* This should be called to avoid memory leaks.
* This will remove the listener from the Word and PersistenceState,
* allowing the garbage collector to collect this WordItem.
*/
public void discard()
{
_word.removeObjectChangedListener(_listener);
_ps.removeObjectChangedListener(_listener);
}
}