001package jmri.jmrit.dispatcher;
002
003import java.util.ArrayList;
004import jmri.InstanceManager;
005
006/**
007 * This class holds information and options for an AllocationRequestt.
008 * <p>
009 * An AllocationRequest holds the following information: Section to be allocated
010 * Active Train requesting the allocation
011 * <p>
012 * A AllocationRequests is referenced via a list in DispatcherFrame, which
013 * serves as a manager for AllocationRequest objects.
014 * <p>
015 * AllocationRequests are transient, and are not saved to disk.
016 *
017 * <p>
018 * This file is part of JMRI.
019 * <p>
020 * JMRI is open source software; you can redistribute it and/or modify it under
021 * the terms of version 2 of the GNU General Public License as published by the
022 * Free Software Foundation. See the "COPYING" file for a copy of this license.
023 * <p>
024 * JMRI is distributed in the hope that it will be useful, but WITHOUT ANY
025 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
026 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
027 *
028 * @author Dave Duchamp Copyright (C) 2008-2010
029 */
030public class AllocationRequest {
031
032    /**
033     * Create an AllocationRequest.
034     *
035     * @param s   the requested section
036     * @param num the sequence number for the requested section
037     * @param dir the direction the train is traveling on the section
038     * @param at  the train for which the section is requested
039     */
040    public AllocationRequest(jmri.Section s, int num, int dir, ActiveTrain at) {
041        mSection = s;
042        mActiveTrain = at;
043        mSectionSeqNum = num;
044        mSectionDirection = dir;
045        // listen for changes in Section occupancy
046        if (mSection != null) {
047            mSection.addPropertyChangeListener(mSectionListener = new java.beans.PropertyChangeListener() {
048                @Override
049                public void propertyChange(java.beans.PropertyChangeEvent e) {
050                    handleSectionChange(e);
051                }
052            });
053        }
054    }
055
056    // instance variables
057    private jmri.Section mSection = null;
058    private ActiveTrain mActiveTrain = null;
059    private int mSectionSeqNum = 0;
060    private int mSectionDirection = jmri.Section.UNKNOWN;
061    private java.beans.PropertyChangeListener mSectionListener = null;
062    // instance variables related to automatic allocation of Sections
063    private boolean mWaitingForTrain = false;
064    private ArrayList<ActiveTrain> mMeetingTrainList = new ArrayList<ActiveTrain>();
065
066    //
067    // Access methods
068    //
069    public jmri.Section getSection() {
070        return mSection;
071    }
072
073    public String getSectionName() {
074        String s = mSection.getDisplayName();
075        return s;
076    }
077
078    protected ActiveTrain getActiveTrain() {
079        return mActiveTrain;
080    }
081
082    protected String getActiveTrainName() {
083        return (mActiveTrain.getTrainName() + "/" + mActiveTrain.getTransitName());
084    }
085
086    protected int getSectionSeqNumber() {
087        return mSectionSeqNum;
088    }
089
090    protected int getSectionDirection() {
091        return mSectionDirection;
092    }
093
094    protected String getSectionDirectionName() {
095        if (mSectionDirection == jmri.Section.FORWARD) {
096            return Bundle.getMessage("FORWARD");
097        }
098        if (mSectionDirection == jmri.Section.REVERSE) {
099            return Bundle.getMessage("REVERSE");
100        }
101        return Bundle.getMessage("UNKNOWN");
102    }
103
104    protected boolean getWaitingForTrain() {
105        return mWaitingForTrain;
106    }
107
108    protected void setWaitingForTrain(boolean set) {
109        mWaitingForTrain = set;
110    }
111
112    protected void addMeetingTrain(ActiveTrain at) {
113        mMeetingTrainList.add(at);
114    }
115
116    protected void removeMeetingTrain(ActiveTrain at) {
117        for (int i = 0; i < mMeetingTrainList.size(); i++) {
118            if (at == mMeetingTrainList.get(i)) {
119                mMeetingTrainList.remove(i);
120                return;
121            }
122        }
123    }
124
125    protected ArrayList<ActiveTrain> getMeetingTrainList() {
126        return mMeetingTrainList;
127    }
128
129    /**
130     * Methods
131     */
132    private void handleSectionChange(java.beans.PropertyChangeEvent e) {
133        InstanceManager.getDefault(DispatcherFrame.class).sectionOccupancyChanged();
134        //This forces us to rescan the allocation list if the section has gone unoccupied, thus this might get re-allocated
135        if (e.getPropertyName().equals("occupancy")) {
136            if (((Integer) e.getNewValue()).intValue() == jmri.Section.UNOCCUPIED) {
137                InstanceManager.getDefault(DispatcherFrame.class).queueScanOfAllocationRequests();
138            }
139        }
140    }
141
142    public void dispose() {
143        if ((mSectionListener != null) && (mSection != null)) {
144            mSection.removePropertyChangeListener(mSectionListener);
145        }
146
147        if ((mSignalMastListener != null) && (mWaitingForSignalMast != null)) {
148            mWaitingForSignalMast.removePropertyChangeListener(mSignalMastListener);
149        }
150
151        if ((mWaitingOnBlock != null) && (mWaitingOnBlockListener != null)) {
152            mWaitingOnBlock.removePropertyChangeListener(mWaitingOnBlockListener);
153        }
154        mWaitingOnBlock = null;
155        mWaitingOnBlockListener = null;
156        mSignalMastListener = null;
157        mWaitingForSignalMast = null;
158        mSectionListener = null;
159        mSection = null;
160        mActiveTrain = null;
161    }
162
163    private java.beans.PropertyChangeListener mSignalMastListener = null;
164
165    private jmri.SignalMast mWaitingForSignalMast = null;
166
167    public void setWaitingForSignalMast(jmri.SignalMast sm) {
168        if (mSignalMastListener == null) {
169            mSignalMastListener = new java.beans.PropertyChangeListener() {
170                @Override
171                public void propertyChange(java.beans.PropertyChangeEvent e) {
172                    if (e.getPropertyName().equals("Held")) {
173                        if (!((Boolean) e.getNewValue()).booleanValue()) {
174                            mWaitingForSignalMast.removePropertyChangeListener(mSignalMastListener);
175                            InstanceManager.getDefault(DispatcherFrame.class).queueScanOfAllocationRequests();
176                        }
177                    }
178                }
179            };
180        }
181        if (mWaitingForSignalMast != null) {
182            mWaitingForSignalMast.removePropertyChangeListener(mSignalMastListener);
183        }
184        mWaitingForSignalMast = sm;
185        if (mWaitingForSignalMast != null) {
186            mWaitingForSignalMast.addPropertyChangeListener(mSignalMastListener);
187        }
188    }
189
190    jmri.Block mWaitingOnBlock = null;
191    private java.beans.PropertyChangeListener mWaitingOnBlockListener = null;
192
193    protected void setWaitingOnBlock(jmri.Block b) {
194        if (mWaitingOnBlockListener == null) {
195            mWaitingOnBlockListener = new java.beans.PropertyChangeListener() {
196                @Override
197                public void propertyChange(java.beans.PropertyChangeEvent e) {
198                    if (e.getPropertyName().equals("state")) {
199                        if (((Integer) e.getNewValue()).intValue() == jmri.Block.UNOCCUPIED) {
200                            mWaitingOnBlock.removePropertyChangeListener(mWaitingOnBlockListener);
201                            InstanceManager.getDefault(DispatcherFrame.class).queueScanOfAllocationRequests();
202                        }
203                    }
204                }
205            };
206        }
207        if (mWaitingOnBlock != null) {
208            mWaitingOnBlock.removePropertyChangeListener(mWaitingOnBlockListener);
209        }
210        mWaitingOnBlock = b;
211        if (mWaitingOnBlock != null) {
212            mWaitingOnBlock.addPropertyChangeListener(mWaitingOnBlockListener);
213        }
214
215    }
216}