001package jmri.jmrit.entryexit;
002
003import jmri.Block;
004import jmri.NamedBean;
005import jmri.jmrit.display.layoutEditor.LayoutBlock;
006import jmri.jmrit.display.layoutEditor.LayoutBlockManager;
007
008public class ManuallySetRoute {
009
010    LayoutBlockManager lbm = jmri.InstanceManager.getDefault(jmri.jmrit.display.layoutEditor.LayoutBlockManager.class);
011    PointDetails sourcePoint = null;
012
013    public ManuallySetRoute(PointDetails pd) {
014        sourcePoint = pd;
015        LayoutBlock facing = lbm.getFacingBlockByNamedBean(pd.getSensor(), pd.getPanel());
016        EntryExitPairs manager = jmri.InstanceManager.getDefault(jmri.jmrit.entryexit.EntryExitPairs.class);
017        for (LayoutBlock pro : lbm.getProtectingBlocksByNamedBean(pd.getSensor(), pd.getPanel())) {
018            if (findDestPoint(pro, facing)) {
019                PointDetails dest = manager.providePoint(destLoc, pd.getPanel());
020                Source src = manager.getSourceForPoint(pd);
021                if (dest != null && src != null) {
022                    DestinationPoints dp = src.getDestForPoint(dest);
023                    if (dp != null) {
024                        dp.setInterlockRoute(false);
025                        break;
026                    }
027                }
028            }
029        }
030    }
031
032    NamedBean destLoc = null;
033
034    int depth = 0;
035
036    boolean findDestPoint(LayoutBlock pro, LayoutBlock facing) {
037        depth++;
038        if (depth > 50) //This is to prevent a loop, only look as far as 50 blocks
039        {
040            return false;
041        }
042        boolean looking = true;
043        if (pro.getNumberOfThroughPaths() == 0) {
044            destLoc = lbm.getSensorAtEndBumper(pro.getBlock(), sourcePoint.getPanel());
045        } else {
046            while (looking) {
047                Block found = cycle(pro, facing);
048                if (found != null) {
049                    destLoc = lbm.getFacingBean(pro.getBlock(), found, sourcePoint.getPanel(), jmri.Sensor.class);
050                    if (destLoc != null) {
051                        looking = false;
052                    } else {
053                        findDestPoint(lbm.getLayoutBlock(found), pro);
054                        looking = false;
055                    }
056                } else {
057                    looking = false;
058                }
059            }
060        }
061        if (destLoc != null) {
062            return true;
063        }
064        return false;
065
066    }
067
068    Block cycle(LayoutBlock protect, LayoutBlock face) {
069        for (int i = 0; i < protect.getNumberOfThroughPaths(); i++) {
070            if (protect.isThroughPathActive(i)) {
071                if (protect.getThroughPathSource(i) == face.getBlock()) {
072                    jmri.Block found = protect.getThroughPathDestination(i);
073                    LayoutBlock lfound = lbm.getLayoutBlock(found);
074                    if (found.getState() == jmri.Block.UNOCCUPIED && lfound!=null && !lfound.getUseExtraColor()) {
075                        return found;
076                    }
077                }
078            }
079        }
080        return null;
081    }
082}