TVShowTimelineMaker.timeConstraints.CharacterRelation.java Source code

Java tutorial

Introduction

Here is the source code for TVShowTimelineMaker.timeConstraints.CharacterRelation.java

Source

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package TVShowTimelineMaker.timeConstraints;

import TVShowTimelineMaker.character.NamedCharacter;
import TVShowTimelineMaker.timeline.Event;
import TVShowTimelineMaker.timeline.OnceDayEvent;
import TVShowTimelineMaker.timeline.OncePeriodEvent;
import TVShowTimelineMaker.timeline.PlacementEvent.Placement;
import TVShowTimelineMaker.util.MyLittePonyMaps;
import TVShowTimelineMaker.util.XML.XMLWriterImp;
import java.util.Iterator;
import java.util.NavigableSet;
import java.util.logging.Logger;
import org.jdom2.Element;
import org.joda.time.DateTime;
import org.joda.time.ReadablePeriod;

public class CharacterRelation
        extends Relation<OnceDayEvent.OnceDayEventPlacement, OnceDayEvent.OnceDayEventPlacement> {

    private static final long serialVersionUID = 6L;

    public static int START_OF_PUBERTY = 13;
    public static int START_OF_MENOPAUSE = 61;
    private static final Logger LOG = Logger.getLogger(CharacterRelation.class.getName());

    @com.civprod.dynamicClassLoading.ClassInitalizer
    public static final void init2() {
        MyLittePonyMaps.putConstraint("CharacterRelation", CharacterRelation.class);
    }

    private final NamedCharacter mFirstNamedCharacter;
    private final NamedCharacter mSecondNamedCharacter;
    private final CharacterRelationKind mCharacterRelationKind;

    public CharacterRelation(NamedCharacter inFirstNamedCharacter, NamedCharacter inSecondNamedCharacter,
            CharacterRelationKind inCharacterRelationKind) {
        super(inFirstNamedCharacter.getBirthday(), inSecondNamedCharacter.getBirthday(),
                inCharacterRelationKind.getCharacterRelationKind(), inCharacterRelationKind.getPeriod());
        this.mFirstNamedCharacter = inFirstNamedCharacter;
        this.mSecondNamedCharacter = inSecondNamedCharacter;
        this.mCharacterRelationKind = inCharacterRelationKind;
    }

    public CharacterRelation(Element root) {
        super(root,
                NamedCharacter.NamedCharacterIDXMLWriter.instance.readElements(root.getChild("firstCharacterByID"))
                        .getBirthday(),
                NamedCharacter.NamedCharacterIDXMLWriter.instance.readElements(root.getChild("secondCharacterByID"))
                        .getBirthday(),
                CharacterRelationKind.valueOf(root.getChild("kind").getTextNormalize()).getCharacterRelationKind(),
                CharacterRelationKind.valueOf(root.getChild("kind").getTextNormalize()).getPeriod());
        Element firstCharacterElement = root.getChild("firstCharacterByID");
        this.mFirstNamedCharacter = NamedCharacter.NamedCharacterIDXMLWriter.instance
                .readElements(firstCharacterElement);
        Element secondCharacterElement = root.getChild("secondCharacterByID");
        this.mSecondNamedCharacter = NamedCharacter.NamedCharacterIDXMLWriter.instance
                .readElements(secondCharacterElement);
        Element kindElement = root.getChild("kind");
        this.mCharacterRelationKind = CharacterRelationKind.valueOf(kindElement.getTextNormalize());
    }

    /**
     * @return the mFirstNamedCharacter
     */
    public NamedCharacter getFirstNamedCharacter() {
        return this.mFirstNamedCharacter;
    }

    /**
     * @return the mSecondNamedCharacter
     */
    public NamedCharacter getSecondNamedCharacter() {
        return this.mSecondNamedCharacter;
    }

    /**
     * @return the mCharacterRelationKind
     */
    public CharacterRelationKind getCharacterRelationKind() {
        return this.mCharacterRelationKind;
    }

    @Override
    public boolean isStrict() {
        boolean rvalue = super.isStrict();
        if (this.mCharacterRelationKind.equals(CharacterRelationKind.MOTHER)) {
            rvalue = true;
        }
        return rvalue;
    }

    @Override
    public boolean consistentWithConstraint(DateTime inFirstDay, DateTime inSecondDay) {
        boolean con = super.consistentWithConstraint(inFirstDay, inSecondDay);
        if (con) {
            if (this.mCharacterRelationKind.equals(CharacterRelationKind.MOTHER)) {
                DateTime lowerBoundOnBirthDay1 = inSecondDay.minusYears(START_OF_MENOPAUSE).withHourOfDay(1);
                DateTime upperBoundOnBirthDay1 = inSecondDay.minus(this.mCharacterRelationKind.mPeriod)
                        .withHourOfDay(23);
                con = inFirstDay.isAfter(lowerBoundOnBirthDay1) && inFirstDay.isBefore(upperBoundOnBirthDay1);
            }
        }
        return con;
    }

    @Override
    public boolean complexApplyConstraint() {
        boolean changed = super.complexApplyConstraint();
        if (this.mCharacterRelationKind.equals(CharacterRelationKind.MOTHER)) {
            if ((!this.mFirstNamedCharacter.getBirthday().isMarkedForComplexEval())
                    && this.mSecondNamedCharacter.getBirthday().isMarkedForComplexEval()) {
                this.mFirstNamedCharacter.getBirthday().setUpForComplexEval();
            }
            if (this.mFirstNamedCharacter.getBirthday().isMarkedForComplexEval()
                    && (!this.mSecondNamedCharacter.getBirthday().isMarkedForComplexEval())) {
                this.mSecondNamedCharacter.getBirthday().setUpForComplexEval();
            }
            if (this.mFirstNamedCharacter.getBirthday().isMarkedForComplexEval()
                    && this.mSecondNamedCharacter.getBirthday().isMarkedForComplexEval()) {
                NavigableSet<DateTime> firstEpisodeDates = this.mFirstNamedCharacter.getBirthday()
                        .getPossibleDays();
                NavigableSet<DateTime> secondEpisodeDates = this.mSecondNamedCharacter.getBirthday()
                        .getPossibleDays();
                DateTime lowerBoundOnBirthDay1 = secondEpisodeDates.first().minusYears(START_OF_MENOPAUSE)
                        .withHourOfDay(1);
                DateTime upperBoundOnBirthDay1 = secondEpisodeDates.first()
                        .minus(this.mCharacterRelationKind.mPeriod).withHourOfDay(23);
                Iterator<DateTime> firstEpisodeDatesIterator = firstEpisodeDates.iterator();
                Iterator<DateTime> secondEpisodeDatesIterator = secondEpisodeDates.iterator();
                DateTime curFirstEpisodeDate = firstEpisodeDatesIterator.next();
                DateTime curSecondEpisodeDate = secondEpisodeDatesIterator.next();
                boolean cont = true;
                //while (indexInToFirstEpisodeDatesDates < firstEpisodeDates.size()) {
                while (cont) {
                    if (curFirstEpisodeDate.isBefore(lowerBoundOnBirthDay1)) {
                        firstEpisodeDatesIterator.remove();
                        if (firstEpisodeDatesIterator.hasNext()) {
                            curFirstEpisodeDate = firstEpisodeDatesIterator.next();
                        } else {
                            cont = false;
                        }
                        changed = true;
                    } else if (curFirstEpisodeDate.isAfter(upperBoundOnBirthDay1)) {
                        if (secondEpisodeDatesIterator.hasNext()) {
                            curSecondEpisodeDate = secondEpisodeDatesIterator.next();
                            lowerBoundOnBirthDay1 = curSecondEpisodeDate.minusYears(START_OF_MENOPAUSE)
                                    .withHourOfDay(1);
                            upperBoundOnBirthDay1 = curSecondEpisodeDate.minus(this.mCharacterRelationKind.mPeriod)
                                    .withHourOfDay(23);
                        } else {
                            firstEpisodeDatesIterator.remove();
                            if (firstEpisodeDatesIterator.hasNext()) {
                                curFirstEpisodeDate = firstEpisodeDatesIterator.next();
                            } else {
                                cont = false;
                            }
                            changed = true;
                        }
                    } else {
                        if (firstEpisodeDatesIterator.hasNext()) {
                            curFirstEpisodeDate = firstEpisodeDatesIterator.next();
                        } else {
                            cont = false;
                        }
                    }
                }
                firstEpisodeDatesIterator = firstEpisodeDates.iterator();
                secondEpisodeDatesIterator = secondEpisodeDates.iterator();
                curFirstEpisodeDate = firstEpisodeDatesIterator.next();
                curSecondEpisodeDate = secondEpisodeDatesIterator.next();
                cont = true;
                DateTime lowerBoundOnBirthDay2 = firstEpisodeDates.first().plus(this.mCharacterRelationKind.mPeriod)
                        .withHourOfDay(1);
                DateTime upperBoundOnBirthDay2 = firstEpisodeDates.first().plusYears(START_OF_MENOPAUSE)
                        .withHourOfDay(23);
                while (cont) {
                    if (curSecondEpisodeDate.isBefore(lowerBoundOnBirthDay2)) {
                        secondEpisodeDatesIterator.remove();
                        if (secondEpisodeDatesIterator.hasNext()) {
                            curSecondEpisodeDate = secondEpisodeDatesIterator.next();
                        } else {
                            cont = false;
                        }
                        changed = true;
                    } else if (curSecondEpisodeDate.isAfter(upperBoundOnBirthDay2)) {
                        if (firstEpisodeDatesIterator.hasNext()) {
                            curFirstEpisodeDate = firstEpisodeDatesIterator.next();
                            lowerBoundOnBirthDay2 = curFirstEpisodeDate.plus(this.mCharacterRelationKind.mPeriod)
                                    .withHourOfDay(1);
                            upperBoundOnBirthDay2 = curFirstEpisodeDate.plusYears(START_OF_MENOPAUSE)
                                    .withHourOfDay(23);
                        } else {
                            secondEpisodeDatesIterator.remove();
                            if (secondEpisodeDatesIterator.hasNext()) {
                                curSecondEpisodeDate = secondEpisodeDatesIterator.next();
                            } else {
                                cont = false;
                            }
                            changed = true;
                        }
                    } else {
                        if (secondEpisodeDatesIterator.hasNext()) {
                            curSecondEpisodeDate = secondEpisodeDatesIterator.next();
                        } else {
                            cont = false;
                        }
                    }
                }
            }
        }
        return changed;
    }

    @Override
    public boolean applyConstraint() {
        boolean changed = super.applyConstraint();
        if (this.mCharacterRelationKind.equals(CharacterRelationKind.MOTHER)) {
            DateTime tempEarliestPossibleDateForFirstEpisode = this.mSecondNamedCharacter.getBirthday()
                    .getEarliestPossibleDate().minusYears(START_OF_MENOPAUSE).withHourOfDay(1);
            DateTime tempLatestPossibleDateForSecondEpisode = this.mFirstNamedCharacter.getBirthday()
                    .getLatestPossibleDate().plusYears(START_OF_MENOPAUSE).withHourOfDay(23);
            if (tempEarliestPossibleDateForFirstEpisode
                    .isAfter(this.mFirstNamedCharacter.getBirthday().getEarliestPossibleDate())) {
                this.mFirstNamedCharacter.getBirthday()
                        .setEarliestPossibleDate(tempEarliestPossibleDateForFirstEpisode);
                changed = true;
            }
            if (this.mSecondNamedCharacter.getBirthday().getLatestPossibleDate()
                    .isAfter(tempLatestPossibleDateForSecondEpisode)) {
                this.mSecondNamedCharacter.getBirthday()
                        .setLatestPossibleDate(tempLatestPossibleDateForSecondEpisode);
                changed = true;
            }
        }
        return changed;
    }

    @Override
    public boolean ConstraintSatisfied() {
        boolean rValue = super.ConstraintSatisfied();
        if (this.mCharacterRelationKind.equals(CharacterRelationKind.MOTHER)) {
            DateTime tempEarliestPossibleDateForFirstEpisode = this.mSecondNamedCharacter.getBirthday()
                    .getEarliestPossibleDate().minusYears(START_OF_MENOPAUSE).withHourOfDay(1);
            DateTime tempLatestPossibleDateForSecondEpisode = this.mFirstNamedCharacter.getBirthday()
                    .getLatestPossibleDate().plusYears(START_OF_MENOPAUSE).withHourOfDay(23);
            if (tempEarliestPossibleDateForFirstEpisode
                    .isAfter(this.mFirstNamedCharacter.getBirthday().getEarliestPossibleDate())) {
                rValue = false;
            }
            if (this.mSecondNamedCharacter.getBirthday().getLatestPossibleDate()
                    .isAfter(tempLatestPossibleDateForSecondEpisode)) {
                rValue = false;
            }
        }
        return rValue;
    }

    @Override
    public String toString() {
        String rString = this.mFirstNamedCharacter.getName() + " is " + this.mSecondNamedCharacter.getName()
                + "'s ";
        if (this.mCharacterRelationKind.equals(CharacterRelationKind.OLDER_SIBLING)) {
            rString += "older sibling";
        } else if (this.mCharacterRelationKind.equals(CharacterRelationKind.PARENT)) {
            rString += "parent";
        } else if (this.mCharacterRelationKind.equals(CharacterRelationKind.TWIN)) {
            rString += "twin";
        } else {
            rString += this.mCharacterRelationKind.toString();
        }
        return rString;
    }

    @Override
    public boolean consistentWithConstraint(Placement[] inValues) {
        boolean consistent = super.consistentWithConstraint(inValues);
        DateTime inFirstStartTime;
        DateTime inFirstEndTime;
        DateTime inSecondStartTime;
        DateTime inSecondEndTime;
        if (this.mFirstNamedCharacter.getBirthday() instanceof OnceDayEvent) {
            OnceDayEvent.OnceDayEventPlacement curOnceDayEventPlacement = (OnceDayEvent.OnceDayEventPlacement) inValues[0];
            inFirstStartTime = curOnceDayEventPlacement.day;
            inFirstEndTime = curOnceDayEventPlacement.day;
        } else {
            OncePeriodEvent.OncePeriodEventPlacement curOncePeriodEventPlacement = (OncePeriodEvent.OncePeriodEventPlacement) inValues[0];
            inFirstStartTime = curOncePeriodEventPlacement.startDay;
            inFirstEndTime = curOncePeriodEventPlacement.endDay;
        }
        if (this.mSecondNamedCharacter.getBirthday() instanceof OnceDayEvent) {
            OnceDayEvent.OnceDayEventPlacement curOnceDayEventPlacement = (OnceDayEvent.OnceDayEventPlacement) inValues[1];
            inSecondStartTime = curOnceDayEventPlacement.day;
            inSecondEndTime = curOnceDayEventPlacement.day;
        } else {
            OncePeriodEvent.OncePeriodEventPlacement curOncePeriodEventPlacement = (OncePeriodEvent.OncePeriodEventPlacement) inValues[1];
            inSecondStartTime = curOncePeriodEventPlacement.startDay;
            inSecondEndTime = curOncePeriodEventPlacement.endDay;
        }
        if (consistent) {
            if (this.mCharacterRelationKind.equals(CharacterRelationKind.MOTHER)) {
                DateTime lowerBoundOnBirthDay1 = inSecondStartTime.minusYears(START_OF_MENOPAUSE).withHourOfDay(1);
                DateTime upperBoundOnBirthDay1 = inSecondStartTime.minus(this.mCharacterRelationKind.mPeriod)
                        .withHourOfDay(23);
                consistent = inFirstEndTime.isAfter(lowerBoundOnBirthDay1)
                        && inFirstEndTime.isBefore(upperBoundOnBirthDay1);
            }
        }
        return consistent;
    }

    @Override
    public Event[] increaseWhat(Placement inValues[]) {
        Event[] rValue = super.increaseWhat(inValues);
        DateTime inFirstStartTime;
        DateTime inFirstEndTime;
        DateTime inSecondStartTime;
        DateTime inSecondEndTime;
        if (this.mFirstNamedCharacter.getBirthday() instanceof OnceDayEvent) {
            OnceDayEvent.OnceDayEventPlacement curOnceDayEventPlacement = (OnceDayEvent.OnceDayEventPlacement) inValues[0];
            inFirstStartTime = curOnceDayEventPlacement.day;
            inFirstEndTime = curOnceDayEventPlacement.day;
        } else {
            OncePeriodEvent.OncePeriodEventPlacement curOncePeriodEventPlacement = (OncePeriodEvent.OncePeriodEventPlacement) inValues[0];
            inFirstStartTime = curOncePeriodEventPlacement.startDay;
            inFirstEndTime = curOncePeriodEventPlacement.endDay;
        }
        if (this.mSecondNamedCharacter.getBirthday() instanceof OnceDayEvent) {
            OnceDayEvent.OnceDayEventPlacement curOnceDayEventPlacement = (OnceDayEvent.OnceDayEventPlacement) inValues[1];
            inSecondStartTime = curOnceDayEventPlacement.day;
            inSecondEndTime = curOnceDayEventPlacement.day;
        } else {
            OncePeriodEvent.OncePeriodEventPlacement curOncePeriodEventPlacement = (OncePeriodEvent.OncePeriodEventPlacement) inValues[1];
            inSecondStartTime = curOncePeriodEventPlacement.startDay;
            inSecondEndTime = curOncePeriodEventPlacement.endDay;
        }
        if (rValue.length == 0) {
            if (this.mCharacterRelationKind.equals(CharacterRelationKind.MOTHER)) {
                DateTime lowerBoundOnBirthDay1 = inSecondStartTime.minusYears(START_OF_MENOPAUSE).withHourOfDay(1);
                DateTime upperBoundOnBirthDay1 = inSecondStartTime.minus(this.mCharacterRelationKind.mPeriod)
                        .withHourOfDay(23);
                if (!inFirstEndTime.isAfter(lowerBoundOnBirthDay1)) {
                    rValue = new Event[] { this.getFirstEvent() };
                }
                if (!inFirstEndTime.isBefore(upperBoundOnBirthDay1)) {
                    rValue = new Event[] { this.getSecondEvent() };
                }
            }
        }
        return rValue;
    }

    public static enum CharacterRelationKind {

        OLDER_SIBLING(RelationKind.BEFORE, null), PARENT(RelationKind.MORE_THEN_BEFORE,
                org.joda.time.Years.years(13)), TWIN(RelationKind.SAME_TIME_AS, null), GRANDPARENT(
                        RelationKind.MORE_THEN_BEFORE, org.joda.time.Years.years(26)), GREAT_GRANDPARENT(
                                RelationKind.MORE_THEN_BEFORE, org.joda.time.Years.years(39)), MOTHER(
                                        RelationKind.MORE_THEN_BEFORE, org.joda.time.Years.years(13));
        private final RelationKind mCharacterRelationKind;
        private final ReadablePeriod mPeriod;

        CharacterRelationKind(RelationKind inCharacterRelationKind, ReadablePeriod inPeriod) {
            this.mCharacterRelationKind = inCharacterRelationKind;
            this.mPeriod = inPeriod;
        }

        /**
         * @return the mCharacterRelationKind
         */
        public RelationKind getCharacterRelationKind() {
            return this.mCharacterRelationKind;
        }

        /**
         * @return the mPeriod
         */
        public ReadablePeriod getPeriod() {
            return this.mPeriod;
        }
    }

    public static class CharacterRelationXMLWriter extends IDedObjectXMLWriter<CharacterRelation> {

        @com.civprod.dynamicClassLoading.ClassInitalizer
        public static final void init() {
            XMLWriterImp.addXMLWriter(CharacterRelation.class, new CharacterRelationXMLWriter());
        }

        @Override
        public Element writeElements(CharacterRelation ObjectToWrite) {
            Element newElement = new Element("CharacterRelation");
            this.writeElements(ObjectToWrite, newElement);
            Element firstCharacterElement = new Element("firstCharacterByID");
            NamedCharacter.NamedCharacterIDXMLWriter.instance.writeElements(ObjectToWrite.mFirstNamedCharacter,
                    firstCharacterElement);
            newElement.addContent(firstCharacterElement);
            Element secondCharacterElement = new Element("secondCharacterByID");
            NamedCharacter.NamedCharacterIDXMLWriter.instance.writeElements(ObjectToWrite.mSecondNamedCharacter,
                    secondCharacterElement);
            newElement.addContent(secondCharacterElement);
            Element kindElement = new Element("kind");
            kindElement.setText(ObjectToWrite.mCharacterRelationKind.name());
            newElement.addContent(kindElement);
            return newElement;
        }

        @Override
        public CharacterRelation readElements(Element root) {
            return new CharacterRelation(root);
        }

    }
}