ffdbc66179afa49418ac7b38e2f5294550d7495f
[shipsimu.git] / application / ship-simu / main / class_BaseSimulator.php
1 <?php
2 /**
3  * The general simulator class
4  *
5  * @author              Roland Haeder <webmaster@ship-simu.org>
6  * @version             0.0.0
7  * @copyright   Copyright(c) 2007, 2008 Roland Haeder, this is free software
8  * @license             GNU GPL 3.0 or any newer version
9  * @link                http://www.ship-simu.org
10  *
11  * This program is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation, either version 3 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program. If not, see <http://www.gnu.org/licenses/>.
23  */
24 class BaseSimulator extends BaseFrameworkSystem {
25         // Schiffsteilinstanz
26         private $partInstance = null;
27
28         // Abmasse (Breite/Hoehe/Laenge)
29         private $width  = 0;
30         private $height = 0;
31         private $length = 0;
32
33         // Aktuelles Schiff und Schiffsteil
34         private $currShip = null;
35         private $currPart = null;
36
37         // Faktoren zur Erweiterung der Masse. Beispielsweise soll der Maschinenraum groesser wie der Motor sein
38         private $resizeFactorArray = array(
39                 'width'  => 1,
40                 'height' => 1,
41                 'length' => 1
42         );
43
44         // Konstruktor
45         protected function __construct ($className) {
46                 // Call highest constructor
47                 parent::__construct($className);
48
49                 // Set part description and class name
50                 $this->setObjectDescription("Simulator-Basis-Einheit");
51
52                 // Clean up a little, dies sollte ganz zum Schluss erfolgen!
53                 $this->removeResizeFactorArray();
54                 $this->removeCurrPart();
55                 $this->removeCurrShip();
56         }
57
58         // Setter-Methode fuer Laenge
59         public final function setLength ($length) {
60                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%dm</strong> L&auml;nge gesetzt.<br />\n",
61                         $this->__toString(),
62                         $length
63                 ));
64                 $this->length = (float) $length;
65         }
66
67         // Setter-Methode fuer Breite
68         public final function setWidth ($width) {
69                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%dm</strong> Breite gesetzt.<br />\n",
70                         $this->__toString(),
71                         $width
72                 ));
73                 $this->width = (float) $width;
74         }
75
76         // Setter-Methode fuer Hoehe
77         public final function setHeight ($height) {
78                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] <strong>%dm</strong> H&ouml;he gesetzt.<br />\n",
79                         $this->__toString(),
80                         $height
81                 ));
82                 $this->height = (float) $height;
83         }
84
85         // Getter-Methode fuer Laenge
86         public final function getLength () {
87                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] L&auml;nge angefordert.<br />\n",
88                         $this->__toString()
89                 ));
90                 return $this->length;
91         }
92
93         // Getter-Methode fuer Breite
94         public final function getWidth () {
95                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] L&auml;nge angefordert.<br />\n",
96                         $this->__toString()
97                 ));
98                 return $this->width;
99         }
100
101         // Getter-Methode fuer Hoehe
102         public final function getHeight () {
103                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] H&ouml;he angefordert.<br />\n",
104                         $this->__toString()
105                 ));
106                 return $this->height;
107         }
108
109         // Setter-Methode fuer Teil-Instanz
110         public final function setPartInstance (ConstructableShipPart $partInstance) {
111                 $this->partInstance = $partInstance;
112         }
113
114         // Getter-Methode fuer Teil-Instanz
115         public final function getPartInstance () {
116                 if (!isset($this->partInstance)) {
117                         return null;
118                 }
119                 return $this->partInstance;
120         }
121
122         // Remover-Methode fuer die Teil-Instanz
123         public final function removePartInstance () {
124                 if ($this->getPartInstance() !== null) {
125                         // Warnung ausgeben
126                         if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] partInstance ist nicht null! Instanz-Attribut wird nicht entfernt.<br />\n",
127                                 $this->__toString()
128                         ));
129                 } else {
130                         // Leere Instanz kann entfernt werden
131                         if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] partInstance wurde entfernt.<br />\n",
132                                 $this->__toString()
133                         ));
134                         unset($this->partInstance);
135                 }
136         }
137
138         // Prueft ob all Umberechnungsfaktoren gesetzt sind
139         private function isResizeFactorValid () {
140                 return (($this->getResizeFactorElement('width')  > 1)
141                         || ($this->getResizeFactorElement('height') > 1)
142                         || ($this->getResizeFactorElement('length') > 1)
143                 );
144         }
145
146         // Baut einen Motor in das Schiff ein
147         public function addShipPartToShip (ConstructableShip $shipInstance, ConstructableShipPart $partInstance) {
148                 // Schiff/-steil merken
149                 $this->currShip = $shipInstance;
150                 $this->currPart = $partInstance;
151
152                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Maschinenraum mit Motor <strong>%s</strong> wird fuer das Schiff <strong>%s</strong> konstruiert.<br />\n",
153                         $this->__toString(),
154                         $this->getCurrPart()->getObjectDescription(),
155                         $this->currShip->getShipName()
156                 ));
157
158                 // Passt ueberhaupt das Schiffsteil in's Schiff?
159                 if ($this->isShipPartSizeValid()) {
160                         // Berechnungen fuer umliegendes Objekt anpassen
161                         if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Das Schiffsteil <strong>%s</strong> vom Typ <strong>%s</strong> passt in das Schiff <strong>%s</strong> hinein.<br />\n",
162                                 $this->__toString(),
163                                 $this->getCurrPart()->getObjectDescription(),
164                                 $this->getCurrPart()->__toString(),
165                                 $this->currShip->getShipName()
166                         ));
167
168                         // Muessen die Masse angepasst werden?
169                         if ($this->isResizeFactorValid()) {
170                                 // Neue Angaben berechnen (wir lassen etwas Lust fuer Kabelbaeume, Roehren, Maschinisten, etc.)
171                                 $this->newWidth  = (float) $this->getCurrPart()->getWidth()  * $this->resizeFactorArray['width'];
172                                 $this->newHeight = (float) $this->getCurrPart()->getHeight() * $this->resizeFactorArray['height'];
173                                 $this->newLength = (float) $this->getCurrPart()->getLength() * $this->resizeFactorArray['length'];
174
175                                 // Passt dies nun immer noch?
176                                 if ($this->isNewSizeValid()) {
177                                         // Das passt auch, dann Werte setzen und Motor-Instanz merken
178                                         if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Das Schiffsteil <strong>%s</strong> passt in das Schiff <strong>%s</strong> hinein.<br />\n",
179                                                 $this->__toString(),
180                                                 $this->getObjectDescription(),
181                                                 $this->currShip->getShipName()
182                                         ));
183                                         $this->setWidth($this->newWidth);
184                                         $this->setHeight($this->newHeight);
185                                         $this->setLength($this->newLength);
186
187                                         // Einige Dinge entfernen...
188                                         $this->removeAllNewAttr();
189                                 } else {
190                                         // Passt nicht! Also wieder Exception werfen...
191                                         throw new StructureShipMismatchException(sprintf("[%s:] Das Schiffsteil <strong>%s</strong> vom Typ <strong>%s</strong> ist zu gross f&uuml;r das Schiff!",
192                                                 $this->getCurrPart()->__toString(),
193                                                 $this->getCurrPart()->getObjectDescription(),
194                                                 $this->getCurrPart()->__toString()
195                                         ), 2);
196                                 }
197                         } elseif ($this->currPart != null) {
198                                 // Aktuelle Masse setzen
199                                 $this->setWidth($this->getCurrPart()->getWidth());
200                                 $this->setHeight($this->getCurrPart()->getHeight());
201                                 $this->setLength($this->getCurrPart()->getLength());
202                         }
203
204                         // Existiert ein Schiffsteil?
205                         if (!is_null($this->currPart)) {
206                                 // Debug-Meldung ausgeben
207                                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Schiffsteil <strong>%s</strong> gefunden.<br />\n",
208                                         $this->getCurrPart()->realClass,
209                                         $this->getCurrPart()->getObjectDescription()
210                                 ));
211
212                                 // Schiffsteil-Instanz setzen
213                                 $this->setPartInstance($this->currPart);
214
215                                 // Instanzen entfernen
216                                 $this->getCurrPart()->removeCurrShip();
217                                 $this->getCurrPart()->removeCurrPart();
218                                 $this->getCurrPart()->removePartInstance();
219                                 $this->getCurrPart()->removeResizeFactorArray();
220                         }
221                 } else {
222                         // Exception werfen!
223                         throw new StructureShipMismatchException(sprintf("[%s:] Das Schiffsteil <u>%s</u> vom Typ <u>%s</u> passt nicht in das Schiff!",
224                                 $this->getCurrPart()->realClass,
225                                 $this->getCurrPart()->getObjectDescription(),
226                                 $this->getCurrPart()->__toString()
227                         ), 1);
228                 }
229
230                 // Nochmals Clean up a little
231                 $this->removeResizeFactorArray();
232                 $this->removeCurrShip();
233                 $this->removeCurrPart();
234         }
235
236         // Array fuer Umrechnungstabelle entfernen
237         public final function removeResizeFactorArray () {
238                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] removeResizeFactor erreicht.<br />\n",
239                         $this->__toString()
240                 ));
241                 unset($this->resizeFactorArray);
242         }
243
244         /**
245          * Remove all new*** attributes
246          *
247          * @return      void
248          */
249         public final function removeAllNewAttr () {
250                 unset($this->newWidth);
251                 unset($this->newHeight);
252                 unset($this->newLength);
253         }
254
255         /**
256          * Remove current ship instance
257          *
258          * @return      void
259          */
260         public final function removeCurrShip () {
261                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] removeCurrShip erreicht.<br />\n",
262                         $this->__toString()
263                 ));
264                 unset($this->currShip);
265         }
266
267         // Aktuelle Schiffsteil-Instanz entfernen
268         public final function removeCurrPart () {
269                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] removeCurrPart erreicht.<br />\n",
270                         $this->__toString()
271                 ));
272                 unset($this->currPart);
273         }
274
275         // Breite entfernen
276         public final function removeWidth () {
277                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Breite entfernt.<br />\n",
278                         $this->__toString()
279                 ));
280                 unset($this->width);
281         }
282
283         // Hoehe entfernen
284         public final function removeHeight () {
285                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] H&ouml;he entfernt.<br />\n",
286                         $this->__toString()
287                 ));
288                 unset($this->height);
289         }
290
291         // Laenge entfernen
292         public final function removeLength () {
293                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] L&auml;nge entfernt.<br />\n",
294                         $this->__toString()
295                 ));
296                 unset($this->length);
297         }
298
299         // Tiefgang entfernen
300         public final function removeDraught () {
301                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Tiefgang entfernt.<br />\n",
302                         $this->__toString()
303                 ));
304                 unset($this->draught);
305         }
306
307         // Getter-Methode fuer Element aus resizeFactor
308         public final function getResizeFactorElement ($el) {
309                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] getResizeFactorElement erreicht. (element=%s)<br />\n",
310                         $this->__toString(),
311                         $el
312                 ));
313                 if (isset($this->resizeFactorArray[$el])) {
314                         // Element gefunden
315                         return $this->resizeFactorArray[$el];
316                 } else {
317                         // Element nicht gefunden!
318                         return 0;
319                 }
320         }
321
322         // Setter-Methode fuer Element in resizeFactor
323         public final function setResizeFactorElement ($el, $value) {
324                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] Umberechnungsfaktor <strong>%s</strong>=<strong>%s</strong> gesetzt.<br />\n",
325                         $this->__toString(),
326                         $el,
327                         $value
328                 ));
329                 $this->resizeFactorArray[$el] = (float) $value;
330         }
331
332         // Kontrolliert, ob die Abmasse Schiffsteil->Schiff stimmen
333         public function isShipPartSizeValid () {
334                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] isShipPartSizeValid erreicht.<br />\n",
335                         $this->__toString()
336                 ));
337                 return (
338                         (
339                                 ( // Already defined ship messurings
340                                                  ($this->getCurrPart()->getWidth()  < $this->currShip->getWidth())
341                                         && ($this->getCurrPart()->getHeight() < $this->currShip->getDraught())
342                                         && ($this->getCurrPart()->getLength() < $this->currShip->getLength())
343                                 ) || ( // Ship messurings shall be calculated
344                                                  ($this->currShip->getWidth()  == 0)
345                                         && ($this->currShip->getHeight() == 0)
346                                         && ($this->currShip->getLength() == 0)
347                                 )
348                         // The inserted part must be messured!
349                         ) && ($this->getCurrPart()->getWidth()  > 0)
350                                 && ($this->getCurrPart()->getHeight() > 0)
351                                 && ($this->getCurrPart()->getLength() > 0)
352                 );
353         }
354
355         // Kontrolliert, ob die Abmasse Maschinenraum->Schiff stimmen
356         public function isNewSizeValid () {
357                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] isNewSizeValid erreicht.<br />\n",
358                         $this->__toString()
359                 ));
360                 return (
361                         ( // Already defined ship messurings
362                                          ($this->newWidth  < $this->currShip->getWidth())
363                                 && ($this->newHeight < $this->currShip->getDraught())
364                                 && ($this->newLength < $this->currShip->getLength())
365                         ) || ( // Ship messurings shall be calculated
366                                          ($this->currShip->getWidth()  == 0)
367                                 && ($this->currShip->getHeight() == 0)
368                                 && ($this->currShip->getLength() == 0)
369                         )
370                 );
371         }
372
373         // Masse extrahieren
374         public function extractDimensions ($dim) {
375                 if (defined('DEBUG_CORE')) $this->getDebugInstance()->output(sprintf("[%s:] extractDimensions erreicht f&uuml;r <strong>%s</strong>.<br />\n",
376                         $this->__toString(),
377                         $this->getObjectDescription()
378                 ));
379
380                 // Abmasse setzen
381                 if ((isset($dim)) && (is_array($dim)) && (count($dim) == 3)) {
382                         // Abmasse aus Array holen
383                         $this->setWidth($dim[0]);
384                         $this->setHeight($dim[1]);
385                         $this->setLength($dim[2]);
386                 } else {
387                         // Nicht gefundene Abmasse!
388                         throw new DimNotFoundInArrayException($this, self::EXCEPTION_DIMENSION_ARRAY_INVALID);
389                 }
390         }
391
392         /**
393          * Getter for current part instance
394          *
395          * @return              $currPart       Instance of the current ship part object
396          */
397         public final function getCurrPart () {
398                 return $this->currPart;
399         }
400 }
401
402 // [EOF]
403 ?>