Misc bugfixes.
[rock.divinelegy.git] / Services / SimfileParser.php
1 <?php
2
3 namespace Services;
4
5 use Services\ISimfileParser;
6 use Exception;
7
8 class SimfileParser implements ISimfileParser
9 {
10
11 // 'light' => 'Novice',
12 // 'beginner' => 'Novice',
13 // 'easy' => 'Easy',
14 // 'medium' => 'Medium',
15 // 'hard' => 'Hard',
16 // 'challenge' => 'Expert',
17 // 'edit' => 'Edit'
18
19 private $_smFileLines;
20
21 public function parse($simfileData)
22 {
23 $this->_smFileLines = explode(";", $simfileData);
24 }
25
26 public function banner()
27 {
28 return $this->extractKey('BANNER') ?: null;
29 }
30
31 public function title()
32 {
33 $title = $this->extractKey('TITLE');
34 if(!$title) throw new Exception ('Invalid SM file. TITLE missing');
35
36 return $title;
37 }
38
39 public function artist()
40 {
41 $artist = $this->extractKey('ARTIST');
42 if(!$artist) throw new Exception ('Invalid SM file. ARTIST missing');
43
44 return new \Domain\VOs\StepMania\Artist($artist);
45 }
46
47 public function stops()
48 {
49 $stops = $this->extractKey('STOPS') ? 'Yes' : 'No';
50 if(!$stops) throw new Exception ('Invalid SM file. STOPS missing');
51
52 return $stops;
53 }
54
55 public function fgChanges()
56 {
57 $fgChanges = $this->extractKey('FGCHANGES') ? 'Yes' : 'No';
58 if(!$fgChanges) throw new Exception ('Invalid SM file. FGCHANGES missing');
59
60 return $fgChanges;
61 }
62
63 public function bpm()
64 {
65 $displayBpm = $this->extractKey('DISPLAYBPM');
66
67 if($displayBpm)
68 {
69 $bpmRange = explode(":",$displayBpm);
70 $bpmRange[1] = @$bpmRange[1] ?: $bpmRange[0];
71 } else {
72 $bpms = $this->extractKey('BPMS');
73 $bpmRange = $this->parseBpms($bpms);
74 }
75
76 //I have nfi why I made the BPM VO high-low instead of low-high in the constructor but yolo
77 return new \Domain\VOs\StepMania\BPM($bpmRange[1], $bpmRange[0]);
78 }
79
80 public function bgChanges()
81 {
82 $bgChanges = $this->extractKey('BGCHANGES') ? 'Yes' : 'No';
83 if(!$bgChanges) throw new Exception ('Invalid SM file. BGCHANGES missing');
84
85 return $bgChanges;
86 }
87
88 public function bpmChanges()
89 {
90 $bpmChanges = $this->extractKey('BPMS') ? 'Yes' : 'No';
91 if(!$bpmChanges) throw new Exception ('Invalid SM file. BPMS missing');
92
93 return $bpmChanges;
94 }
95
96 public function subtitle()
97 {
98 $subtitle = $this->extractKey('SUBTITLE');
99 if(!$subtitle) throw new Exception ('Invalid SM file. SUBTITLE missing');
100
101 return $subtitle;
102 }
103
104 function steps()
105 {
106 if(empty($this->_smFileLines)) throw new Exception('SM file data not set.');
107 $allSteps = array();
108
109 foreach ($this->_smFileLines as $line)
110 {
111 $pos = strpos($line, '#NOTES:');
112 if ($pos !== false)
113 {
114 $noteData = trim(substr($line, $pos + 9));
115 $allSteps[] = $this->stepchartFromNoteData($noteData);
116 }
117 }
118
119 if(empty($allSteps)) throw new Exception('Invalid Sm file. NOTES missing');
120 return $allSteps;
121 }
122
123 private function stepchartFromNoteData($noteData)
124 {
125 $stepData = array_map('trim', explode(':', $noteData));
126 return new \Domain\VOs\StepMania\StepChart(
127 new \Domain\VOs\StepMania\DanceMode($stepData[0]),
128 new \Domain\VOs\StepMania\Difficulty($stepData[2]),
129 empty($stepData[1]) ? null : new \Domain\VOs\StepMania\StepArtist($stepData[1]),
130 $stepData[3]
131 );
132 }
133
134 private function extractKey($key)
135 {
136 if(empty($this->_smFileLines)) throw new Exception('SM file data not set.');
137
138 foreach ($this->_smFileLines as $line)
139 {
140 $pos = strpos($line, '#' . $key . ':');
141 if ($pos !== false) return trim(substr($line, $pos + strlen($key) + 2));
142 }
143 }
144
145 private function parseBpms($bpms)
146 {
147 $bpms = explode(",", $bpms);
148 $bpmRange = array('high' => null, 'low' => null);
149
150 foreach($bpms as $bpm)
151 {
152 $bpmMeasure = explode('=', $bpm);
153 $bpmValue = floatval($bpmMeasure[1]);
154
155 if(empty($bpmRange['low'])) $bpmRange['low'] = $bpmRange['high'] = $bpmValue;
156
157 $bpmRange['high'] = ($bpmValue > $bpmRange['high']) ? $bpmValue : $bpmRange['high'];
158 $bpmRange['low'] = ($bpmValue < $bpmRange['low']) ? $bpmValue : $bpmRange['low'];
159 }
160
161 return array($bpmRange['low'], $bpmRange['high']);
162 }
163 }