Passed
Push — master ( ecaac2...a03751 )
by David
01:36
created

Warehouse::createFromTree()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 9
nc 2
nop 1
dl 0
loc 16
rs 9.9666
c 0
b 0
f 0
1
<?php
2
3
namespace GGGGino\WarehousePath;
4
5
use GGGGino\WarehousePath\Breadcrumb\BreadcrumbInterface;
6
use GGGGino\WarehousePath\Breadcrumb\BreadthFirstBreadcrumb;
7
use GGGGino\WarehousePath\Calculator\CalculatorInterface;
8
use GGGGino\WarehousePath\Entity\Place;
9
use GGGGino\WarehousePath\Parser\JsonMatrixParser;
10
use GGGGino\WarehousePath\Parser\MatrixParser;
11
use GGGGino\WarehousePath\Parser\ParserInterface;
12
use GGGGino\WarehousePath\Parser\TreeParser;
13
14
class Warehouse
15
{
16
    /**
17
     * @var PlacesCollector
18
     */
19
    private $placesCollector;
20
21
    /**
22
     * @var CalculatorInterface
23
     */
24
    private $pathCalculator;
25
26
    /**
27
     * @var ParserInterface
28
     */
29
    private $parser;
30
    /**
31
     * @var BreadcrumbInterface
32
     */
33
    private $breadcrumbBuilder;
34
35
    public function __construct(PlacesCollector $placesCollector, ParserInterface $parser, BreadcrumbInterface $breadcrumbBuilder)
36
    {
37
        $this->placesCollector = $placesCollector;
38
        $this->parser = $parser;
39
        $this->breadcrumbBuilder = $breadcrumbBuilder;
40
    }
41
42
    /***
43
     * @param string $path
44
     * @return Warehouse
45
     * @throws \Exception
46
     */
47
    public static function createFromJson($path)
48
    {
49
        if( !$path )
50
            throw new \Exception('Please select a path');
51
52
        $placesCollector = new PlacesCollector();
53
        $placesCollector->addBasePlaceTypes();
54
55
        $breadcrumbBuilder = new BreadthFirstBreadcrumb($placesCollector);
56
57
        $wm = new JsonMatrixParser($path, $placesCollector);
58
        $placesCollector->setPlaces($wm->parse());
59
60
        $instance = new self($placesCollector, $wm, $breadcrumbBuilder);
61
62
        return $instance;
63
    }
64
65
    /**
66
     * @param $param
67
     * @return Warehouse
68
     * @throws \Exception
69
     */
70
    public static function createFromMatrix($param)
71
    {
72
        if( !is_array($param) )
73
            throw new \Exception('Matrix should be initialized with an array');
74
75
        $placesCollector = new PlacesCollector();
76
        $placesCollector->addBasePlaceTypes();
77
78
        $breadcrumbBuilder = new BreadthFirstBreadcrumb($placesCollector);
79
80
        $wm = new MatrixParser($param, $placesCollector);
81
        $placesCollector->setPlaces($wm->parse());
82
83
        $instance = new self($placesCollector, $wm, $breadcrumbBuilder);
84
85
        return $instance;
86
    }
87
88
    /**
89
     * @param $param
90
     * @return Warehouse
91
     * @throws \Exception
92
     */
93
    public static function createFromTree($param)
94
    {
95
        if( !is_array($param) )
96
            throw new \Exception('Should be initialized with an array');
97
98
        $placesCollector = new PlacesCollector();
99
        $placesCollector->addBasePlaceTypes();
100
101
        $breadcrumbBuilder = new BreadthFirstBreadcrumb($placesCollector);
102
103
        $wm = new TreeParser($param, $placesCollector);
104
        $placesCollector->setPlaces($wm->parse());
105
106
        $instance = new self($placesCollector, $wm, $breadcrumbBuilder);
107
108
        return $instance;
109
    }
110
111
    /**
112
     * Main algorithm to find the shortest path.
113
     *
114
     * @todo: nel futuro quando ci sarà un magazzino grande, spezzare il magazzino prendendo solo il quadrato contenente i vari punti
115
     *
116
     * @param Place $startPlace
117
     * @param Place $endPlace if not null do early exit
118
     */
119
    public function getPath(Place $startPlace, Place $endPlace = null)
120
    {
121
        $this->breadcrumbBuilder->createBreadcrumb($startPlace, $endPlace);
122
    }
123
124
    /**
125
     * For every place i create the path
126
     *
127
     * @param Place[] $places
128
     * @return array
129
     */
130
    public function getMultiplePath(array $places)
131
    {
132
        return $this->breadcrumbBuilder->createMultipleBreadcrumb($places);
133
    }
134
135
    /**
136
     * Create the matrix for development purpose.
137
     * If you want to print the whole wharehouse
138
     *
139
     * @return Entity\Place[][]
140
     * @throws \Exception
141
     */
142
    public function createMatrix()
143
    {
144
        /** @var Place[] $places */
145
        $places = $this->getPlacesCollector()->getPlaces();
146
147
        /** @var Place[][] $resultMatrix */
148
        $resultMatrix = array();
149
150
        if ( empty($places) )
151
            throw new \Exception('First add the places');
152
153
        /** @var Place $startingPlace */
154
        $startingPlace = reset($places);
155
156
        while ( $newPlace = $startingPlace->getTopRef() ) {
157
            $startingPlace = $newPlace;
158
        }
159
160
        while ( $newPlace = $startingPlace->getLeftRef() ) {
161
            $startingPlace = $newPlace;
162
        }
163
164
        /** @var Place $rowPlace */
165
        $rowPlace = $startingPlace;
166
167
        do {
168
            $tempRow = array();
169
170
            /** @var Place $columnPlace */
171
            $columnPlace = $rowPlace;
172
173
            do {
174
                $tempRow[] = $columnPlace;
175
            } while ($columnPlace = $columnPlace->getRightRef());
176
177
            $resultMatrix[] = $tempRow;
178
        } while ($rowPlace = $rowPlace->getBottomRef());
179
180
        return $resultMatrix;
181
    }
182
183
    /**
184
     * @param $arrayNodes
185
     * @param $matrix
186
     * @return Place[]
187
     */
188
    public function calculate($arrayNodes, $matrix)
189
    {
190
        return $this->pathCalculator->calculate($arrayNodes, $matrix);
191
    }
192
193
    /**
194
     * @param CalculatorInterface $pathCalculator
195
     * @return Warehouse
196
     */
197
    public function setPathCalculator($pathCalculator)
198
    {
199
        $this->pathCalculator = $pathCalculator;
200
        return $this;
201
    }
202
203
    /**
204
     * @param PlacesCollector $placesCollector
205
     * @return Warehouse
206
     */
207
    public function setPlacesCollector($placesCollector)
208
    {
209
        $this->placesCollector = $placesCollector;
210
        return $this;
211
    }
212
213
    /**
214
     * @return ParserInterface
215
     */
216
    public function getParser(): ParserInterface
217
    {
218
        return $this->parser;
219
    }
220
221
    /**
222
     * @return PlacesCollector
223
     */
224
    public function getPlacesCollector()
225
    {
226
        return $this->placesCollector;
227
    }
228
}