/// <summary>
        /// LocationDisambiguator implementation.
        /// Use the base of the slope to disambiguate.
        /// </summary>
        /// <param name="loc"></param>
        /// <returns></returns>
        public bool isSelectable(Location loc)
        {
            if (!isPlacing)
            {
                SlopeRailRoad rr = SlopeRailRoad.get(loc);
                if (rr != null && rr.level < 2)
                {
                    return(true);
                }

                loc.z++;
                rr = SlopeRailRoad.get(loc);
                if (rr != null && rr.level >= 2)
                {
                    return(true);
                }

                return(false);
            }
            else
            {
                // it is always allowed to place it on or under ground
                if (World.world.getGroundLevel(loc) >= loc.z)
                {
                    return(true);
                }

                // if the new rail road is at the edge of existing rail,
                // allow.
                RailRoad rr = RailRoad.get(loc + direction.opposite);
                if (rr != null && rr.hasRail(direction))
                {
                    return(true);
                }

                for (int i = 0; i < 4; i++)
                {
                    loc += direction;
                }
                loc.z++;

                // run the same test to the other end
                rr = RailRoad.get(loc);
                if (rr != null && rr.hasRail(direction.opposite))
                {
                    return(true);
                }

                return(false);
            }
        }
        public override void onClick(MapViewWindow source, Location loc, Point ab)
        {
            if (isPlacing)
            {
                // placing
                if (SlopeRailRoad.canCreateSlope(loc, direction))
                {
                    SlopeRailRoad.createSlope(loc, direction);
                }
                else
                {
                    MainWindow.showError("Can not build");
                }
                //! MainWindow.showError("設置できません");
            }
            else
            {
                SlopeRailRoad srr = SlopeRailRoad.get(loc);
                if (srr == null)
                {
                    loc.z++;
                    srr = SlopeRailRoad.get(loc);
                }
                if (srr != null)
                {
                    if (srr.level >= 2)
                    {
                        loc.z--;
                    }
                    for (int i = 0; i < srr.level; i++)
                    {
                        loc -= direction;
                    }

                    // removing
                    if (SlopeRailRoad.canRemoveSlope(loc, direction))
                    {
                        SlopeRailRoad.removeSlope(loc, direction);
                        return;
                    }
                }
                MainWindow.showError("Can not remove");
                //! MainWindow.showError("撤去できません");
            }
        }
        public override void onMouseMove(MapViewWindow source, Location loc, Point ab)
        {
            if (lastMouse != loc)
            {
                // update the image
                invalidateScreen();
                lastMouse = loc;
                invalidateScreen();

                if (isPlacing)
                {
                    costBox.cost = SlopeRailRoad.calcCostOfNewSlope(loc, direction);
                }
                else
                {
                    costBox.cost = SlopeRailRoad.calcCostOfTearDownSlope(loc, direction);
                }
            }
        }
        public void drawAfter(QuarterViewDrawer view, DrawContextEx dc)
        {
            if (!isPlacing)
            {
                return;
            }
            Location loc = lastMouse;

            if (loc == world.Location.UNPLACED)
            {
                return;
            }
            if (!SlopeRailRoad.canCreateSlope(loc, direction))
            {
                return;
            }

            Surface canvas = dc.surface;

            int Z = loc.z;

            for (int i = 0; i < 4; i++)
            {
                if (i == 2)
                {
                    loc.z++;
                }

                for (int j = World.world.getGroundLevel(loc); j < Z; j++)
                {
                    // TODO: ground level handling
                    BridgePierVoxel.defaultSprite.drawAlpha(
                        canvas, view.fromXYZToClient(loc.x, loc.y, j));
                }

                RailPattern.getSlope(direction, i).drawAlpha(
                    canvas, view.fromXYZToClient(loc));
                loc += direction;
            }
        }