package info.opencards.learnstrats.ltm;
import info.opencards.Utils;
import info.opencards.core.*;
import info.opencards.ui.AbstractLearnDialog;
import java.util.ArrayList;
import java.util.List;
/**
* An adapted SM type II implementation. This implementation is based on http://www.supermemo.com/english/ol/sm2.htm and
* some ideas implemented within the mnemosyne-project ( http://mnemosyne-proj.sourceforge.net )
*
* @author Holger Brandl
*/
public class SM2 extends LearnMethod {
List<Item> scheduledItems = new ArrayList<Item>();
SM2(ItemValuater itemValuater) {
super(itemValuater);
}
/**
* @return <code>true</code> if the item is still on schedule in the current session
*/
protected boolean processItemFeedBack(Item item, Integer feedback) {
if (feedback.equals(AbstractLearnDialog.INVALID_ITEM)) {
unscheduleItem(item);
return false;
}
if (feedback.equals(LearnMethod.SKIP_UNTIL_NEXT)) {
((LTMItem) item).skipUntil(ScheduleUtils.getIncDate(ScheduleUtils.getToday(), 0));
unscheduleItem(item);
return false;
}
if (feedback.equals(LearnMethod.SKIP_UNTIL_TOMORROW)) {
((LTMItem) item).skipUntil(ScheduleUtils.getIncDate(ScheduleUtils.getToday(), 1));
unscheduleItem(item);
return false;
}
return !applyLTMFeedback(item, feedback);
}
/**
* @return <code>true</code> if hte item is no longer scheduled for today.
*/
boolean applyLTMFeedback(Item item, Integer feedback) {
assert item instanceof LTMItem;
LTMItem ltmItem = (LTMItem) item;
ltmItem.updateEFactor(feedback);
if (!ltmItem.isScheduledForToday()) {
unscheduleItem(item);
return true;
}
return false;
}
private void unscheduleItem(Item item) {
//reset the random reverse state if necessary because the item is finished for now
item.getFlashCard().resetRndRevPolicy();
scheduledItems.remove(item);
}
public void fireStatusInfo() {
for (LearnMethodListener procListener : procListeners) {
procListener.processStatusInfo("test", 0.75);
}
}
protected boolean isFinished() {
return scheduledItems.isEmpty();
}
public void run(ItemCollection parentCollection, List<Item> scheduledFileItems) {
// oc 0.12 and prior:
// scheduledItems = ScheduleUtils.getScheduledItems(scheduledFileItems); // why? the items were already chosen with the same method
// note: using the reference here will allow to sucessfully unschedule the file within a session
scheduledItems = scheduledFileItems;
// compare this to the old outdated approach
// scheduledItems = new ArrayList<Item>(scheduledFileItems);
scoreNextItem();
}
protected void scoreNextItem() {
valuater.score(scheduledItems.get(Utils.getRandGen().nextInt(scheduledItems.size())));
}
/**
* Creates a factory which is able to instantiate <code>SM2</code>-instances.
*/
public static LearnMethodFactory getFactory() {
return new LearnMethodFactory() {
public LearnMethod createLearner(ItemValuater itemValuater) {
// return new SM2(itemValuater);
return new UltraShortSM2(itemValuater);
}
};
}
}