Completed
Push — master ( 16c929...217223 )
by Peter
06:17
created

IntervalComparator::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php 
2
/**
3
 * GpsLab component.
4
 *
5
 * @author    Peter Gribanov <[email protected]>
6
 * @copyright Copyright (c) 2016, Peter Gribanov
7
 * @license   http://opensource.org/licenses/MIT
8
 */
9
10
namespace GpsLab\Component\Interval;
11
12
class IntervalComparator
13
{
14
    /**
15
     * @var ComparableIntervalInterface
16
     */
17
    private $interval;
18
19
    /**
20
     * @param ComparableIntervalInterface $interval
21
     */
22
    public function __construct(ComparableIntervalInterface $interval)
23
    {
24
        $this->interval = $interval;
25
    }
26
27
    /**
28
     * @param IntervalPointInterface $point
29
     *
30
     * @return bool
31
     */
32
    public function contains(IntervalPointInterface $point)
33
    {
34
        if ($this->interval->startPoint()->eq($point)) {
35
            return !$this->interval->type()->startExcluded();
36
        }
37
38
        if ($this->interval->endPoint()->eq($point)) {
39
            return !$this->interval->type()->endExcluded();
40
        }
41
42
        return $this->interval->startPoint()->lt($point) && $this->interval->endPoint()->gt($point);
43
    }
44
45
    /**
46
     * @param ComparableIntervalInterface $interval
47
     * @param bool $check_interval_type
48
     *
49
     * @return bool
50
     */
51
    public function intersects(ComparableIntervalInterface $interval, $check_interval_type = true)
52
    {
53
        if (
54
            $this->interval->startPoint()->gt($interval->endPoint()) ||
55
            $this->interval->endPoint()->lt($interval->startPoint())
56
        ) {
57
            return false;
58
        }
59
60
        if ($check_interval_type) {
61
            if ($this->interval->startPoint()->eq($interval->endPoint())) {
62
                return !$this->interval->type()->startExcluded() && !$interval->type()->endExcluded();
63
            }
64
65
            if ($this->interval->endPoint()->eq($interval->startPoint())) {
66
                return !$this->interval->type()->endExcluded() && !$interval->type()->startExcluded();
67
            }
68
        }
69
70
        return true;
71
    }
72
73
    /**
74
     * @param ComparableIntervalInterface $interval
75
     *
76
     * @return ComparableIntervalInterface|null
77
     */
78
    public function intersection(ComparableIntervalInterface $interval)
79
    {
80
        // intervals is not intersect or impossible create interval from one point
81
        if (
82
            $this->interval->startPoint()->gte($interval->endPoint()) ||
83
            $this->interval->endPoint()->lte($interval->startPoint())
84
        ) {
85
            // ignore closed intervals:
86
            // [a, b] | [b, c] = [b, b]
87
            return null;
88
        }
89
90
        $type = IntervalType::TYPE_CLOSED;
91
92
        if ($this->interval->startPoint()->lt($interval->startPoint())) {
93
            $start = $interval->startPoint();
94
            if ($interval->type()->startExcluded()) {
95
                $type |= IntervalType::TYPE_START_EXCLUDED;
96
            }
97
        } else {
98
            $start = $this->interval->startPoint();
99
            if ($this->interval->type()->startExcluded()) {
100
                $type |= IntervalType::TYPE_START_EXCLUDED;
101
            }
102
        }
103
104
        if ($this->interval->endPoint()->gt($interval->endPoint())) {
105
            $end = $interval->endPoint();
106
            if ($interval->type()->endExcluded()) {
107
                $type |= IntervalType::TYPE_END_EXCLUDED;
108
            }
109
        } else {
110
            $end = $this->interval->endPoint();
111
            if ($this->interval->type()->endExcluded()) {
112
                $type |= IntervalType::TYPE_END_EXCLUDED;
113
            }
114
        }
115
116
        return $this->interval
117
            ->withStart($start)
118
            ->withEnd($end)
119
            ->withType(IntervalType::create($type));
120
    }
121
122
    /**
123
     * The point is before the interval
124
     *
125
     * @param IntervalPointInterface $point
126
     *
127
     * @return bool
128
     */
129
    public function before(IntervalPointInterface $point)
130
    {
131
        return $this->interval->startPoint()->gt($point);
132
    }
133
134
    /**
135
     * The point is after the interval
136
     *
137
     * @param IntervalPointInterface $point
138
     *
139
     * @return bool
140
     */
141
    public function after(IntervalPointInterface $point)
142
    {
143
        return $this->interval->endPoint()->lt($point);
144
    }
145
}
146