001package jmri.jmrit.dispatcher;
002
003import jmri.Section;
004import org.slf4j.Logger;
005import org.slf4j.LoggerFactory;
006
007/**
008 * Handle planning information for AutoAllocate
009 * <p>
010 * An Allocation Plan involves a planned meet of two ActiveTrains in a specified
011 * area of the layout.
012 * <p>
013 * AllocationPlan objects are transient (not saved between runs).
014 * <p>
015 * AllocationPlan objects are created and disposed by AutoAllocate as needed.
016 * AutoAllocate serves as the manager of AllocationPlan objects.
017 * <p>
018 * An ActiveTrain may be in more than one AllocationPlan of the same type,
019 * provided its target Section in all active AllocationPlans is the same.
020 * <p>
021 * An AllocationPlan is "complete" when both Active Trains have been allocated
022 * their target Sections.
023 *
024 * <p>
025 * This file is part of JMRI.
026 * <p>
027 * JMRI is open source software; you can redistribute it and/or modify it under
028 * the terms of version 2 of the GNU General Public License as published by the
029 * Free Software Foundation. See the "COPYING" file for a copy of this license.
030 * <p>
031 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
032 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
033 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
034 *
035 * @author Dave Duchamp Copyright (C) 2011
036 */
037public class AllocationPlan {
038
039    public AllocationPlan(AutoAllocate aa, int planNum) {
040        _autoAllocate = aa;
041        if (_autoAllocate == null) {
042            log.error("null AutoAllocate when constructing an AllocationPlan");
043        }
044        _planNum = planNum;
045    }
046
047    /**
048     * Constants representing the type of AllocationPlan
049     */
050    protected static final int NONE = 0x00;   // no plan type
051    protected static final int XING_MEET = 0x01;
052    protected static final int PASSING_MEET = 0x02;
053    protected static final int CONTINUING = 0x04;
054
055    // instance variables
056    private AutoAllocate _autoAllocate = null;
057    private int _planNum = 0;     // Note: _planNum may not be changed. It is the ID of this plan.
058    private int _planType = NONE;
059    private ActiveTrain _atOne = null;
060    private ActiveTrain _atTwo = null;
061    private Section _tSectionOne = null;
062    private Section _tSectionTwo = null;
063    private int _tSectionOneSeq = 0;
064    private int _tSectionTwoSeq = 0;
065
066    //
067    // Access methods
068    //
069    protected int getPlanNum() {
070        return _planNum;
071    }
072
073    protected int getPlanType() {
074        return _planType;
075    }
076
077    protected void setPlanType(int type) {
078        _planType = type;
079    }
080
081    protected ActiveTrain getActiveTrain(int i) {
082        if (i == 1) {
083            return _atOne;
084        } else if (i == 2) {
085            return _atTwo;
086        }
087        return null;
088    }
089
090    protected void setActiveTrain(ActiveTrain at, int i) {
091        if (i == 1) {
092            _atOne = at;
093        } else if (i == 2) {
094            _atTwo = at;
095        } else {
096            log.error("out of range index argument in call to 'setActiveTrain'");
097        }
098    }
099
100    protected Section getTargetSection(int i) {
101        if (i == 1) {
102            return _tSectionOne;
103        } else if (i == 2) {
104            return _tSectionTwo;
105        }
106        return null;
107    }
108
109    protected void setTargetSection(Section s, int seq, int i) {
110        if (i == 1) {
111            _tSectionOne = s;
112            _tSectionOneSeq = seq;
113        } else if (i == 2) {
114            _tSectionTwo = s;
115            _tSectionTwoSeq = seq;
116        } else {
117            log.error("out of range index argument in call to 'setTargetSection'");
118        }
119    }
120
121    protected int getTargetSectionSequenceNum(int i) {
122        if (i == 1) {
123            return _tSectionOneSeq;
124        } else if (i == 2) {
125            return _tSectionTwoSeq;
126        }
127        return 0;
128    }
129
130    //
131    // Other Methods
132    //
133    protected boolean isComplete() {
134        if ((_atOne == null) || (_atTwo == null)) {
135            return false;
136        }
137        java.util.List<AllocatedSection> aSections = _atOne.getAllocatedSectionList();
138        boolean complete = false;
139        for (int i = 0; i < aSections.size(); i++) {
140            if ((aSections.get(i).getSection() == _tSectionOne)
141                    && (aSections.get(i).getSequence() == _tSectionOneSeq)) {
142                complete = true;
143            }
144        }
145        if (!complete) {
146            return false;
147        }
148        complete = false;
149        aSections = _atTwo.getAllocatedSectionList();
150        for (int j = 0; j < aSections.size(); j++) {
151            if ((aSections.get(j).getSection() == _tSectionTwo)
152                    && (aSections.get(j).getSequence() == _tSectionTwoSeq)) {
153                complete = true;
154            }
155        }
156        return complete;
157    }
158
159    public void dispose() {
160        // does nothing for now
161    }
162
163    private final static Logger log = LoggerFactory.getLogger(AllocationPlan.class);
164}