Merge branch 'master' of https://vcs.maemo.org/git/ptas
[ptas] / zouba / src / route_p.cpp
1 #include "route_p.h"
2 #include "location.h"
3
4 #include <QXmlStreamReader>
5 #include <QDebug>
6 #include <QList>
7 #include <QFile>
8 #include <QStringList>
9
10 RoutePrivate::RoutePrivate( QObject *parent ) :
11     m_fromValid(false),
12     m_toValid(false),
13     m_fromLocation(0),
14     m_toLocation(0)
15 {
16   Q_UNUSED( parent )
17 }
18
19 RoutePrivate::~RoutePrivate()
20 {
21 }
22
23 QList<RouteData> RoutePrivate::parseReply( const QByteArray &reply )
24 {
25   qDebug() << "parsing route";
26
27   QList<RouteData> retVal;
28   RouteData routeData;
29   LegData legData;
30
31   QXmlStreamReader xml( reply );
32
33   QHash<QString, bool> in;
34   QHash<QString, bool> have;
35
36   QStringList haveKeys;
37   QStringList inKeys;
38
39   haveKeys
40     << "LINE"
41     << "TIME"
42     << "TRIP"
43     << "DEPARTURE"
44     << "ARRIVAL"
45     ;
46
47   inKeys
48     << "ROUTE"
49     << "LINE"
50     << "STOP"
51     << "WALK"
52     << "POINT"
53     ;
54
55   foreach( QString key, haveKeys ) {
56     have[ key ] = false;
57   }
58
59   foreach( QString key, inKeys ) {
60     in[ key ] = false;
61   }
62
63   while ( !xml.atEnd() ) {
64     xml.readNext();
65
66     QString xmlName = xml.name().toString();
67
68     if ( xml.isStartElement() ) {
69       if ( inKeys.contains( xmlName ) ) {
70         in[ xmlName ] = true;
71         //qDebug() << "in[" << xmlName << "] = true";
72       }
73
74       if ( xmlName == "ROUTE" ) {
75         foreach( QString key, haveKeys ) {
76           have[ key ] = false;
77         }
78       }
79
80       if ( xmlName == "WALK" ) {
81         legData.m_how = "WALK";
82         have[ "DEPARTURE" ] = false;
83         have[ "ARRIVAL" ]   = false;
84         have[ "LENGTH" ]    = false;
85       }
86
87       if ( xmlName == "LINE" ) {
88         legData.m_how = "LINE";
89         QString lineCode( xml.attributes().value("code").toString() );
90         legData.m_lineCode = parseJORECode( lineCode );
91         have[ "DEPARTURE" ] = false;
92         have[ "ARRIVAL" ]   = false;
93         have[ "LENGTH" ]    = false;
94       }
95     }
96
97     if ( xml.isEndElement() ) {
98       if ( inKeys.contains( xmlName ) ) {
99         in[ xmlName ] = false;
100         //qDebug() << "in[" << xmlName << "] = false";
101       }
102
103       if ( xmlName == "ROUTE" ) {
104         retVal.append( routeData );
105         routeData.clear();
106       }
107
108       if ( xmlName == "WALK" || xmlName == "LINE" ) {
109         routeData.m_legData.append( legData );
110         legData.clear();
111         have[ "LENGTH" ] = false;
112       }
113     }
114
115     if ( !have[ "ARRIVAL" ] && ( in[ "WALK" ] || in[ "LINE" ] ) && ( in[ "STOP" ] || in[ "POINT" ] ) && xml.isStartElement() && xmlName == "ARRIVAL" ) {
116       QString arrivalTime( xml.attributes().value("time").toString() );
117       legData.m_arrivalTime = arrivalTime.rightJustified(4).insert(2,":");
118
119       // don't set have[ "ARRIVAL" ] since we want the last one of many STOPs
120     }
121
122     if ( !have[ "DEPARTURE" ] && in[ "LINE" ] && in[ "STOP" ] && xml.isStartElement() && xmlName == "DEPARTURE" ) {
123       QString departureTime( xml.attributes().value("time").toString() );
124       legData.m_departureTime = departureTime.rightJustified(4).insert(2,":");
125
126       have[ "DEPARTURE" ] = true;
127     }
128
129     if ( !have[ "DEPARTURE" ] && in[ "WALK" ] && ( in[ "POINT" ] || in[ "STOP" ] ) && xml.isStartElement() && xmlName == "DEPARTURE" ) {
130       QString departureTime( xml.attributes().value("time").toString() );
131       legData.m_departureTime = departureTime.rightJustified(4).insert(2,":");
132
133       have[ "DEPARTURE" ] = true;
134     }
135
136     if ( !have[ "LENGTH" ] && ( in[ "WALK" ] || in[ "LINE" ] ) && xml.isStartElement() && xmlName == "LENGTH" ) {
137       legData.m_tripTime     = xml.attributes().value("time").toString();
138       legData.m_tripDistance = xml.attributes().value("dist").toString();
139
140       have[ "LENGTH" ] = true;
141     }
142
143     if ( !have[ "TRIP" ] && in[ "ROUTE" ] && xml.isStartElement() && xmlName == "LENGTH" ) {
144       routeData.m_tripTime     = xml.attributes().value("time").toString();
145       routeData.m_tripDistance = xml.attributes().value("dist").toString();
146
147       have[ "TRIP" ] = true;
148     }
149
150     if ( !have[ "LINE" ] && in[ "ROUTE" ] && xml.isStartElement() && xmlName == "LINE" ) {
151       QString lineCode( xml.attributes().value("code").toString() );
152
153       routeData.m_lineCode = parseJORECode( lineCode );
154       have[ "LINE" ] = true;
155     }
156
157     if ( !have[ "TIME" ] && in[ "ROUTE" ] && in[ "LINE" ] && in[ "STOP" ] && xmlName == "DEPARTURE" ) {
158       QString departureTime( xml.attributes().value("time").toString() );
159
160       routeData.m_departureTime = departureTime.rightJustified(4).insert(2,":");
161       have[ "TIME" ] = true;
162     }
163
164   }
165
166   if ( xml.hasError() ) {
167     qDebug() << "xml error:" << xml.errorString();
168   }
169
170   if ( retVal.isEmpty() ) {
171     qDebug() << "no routes found";
172   }
173
174   return retVal;
175 }
176
177 void RoutePrivate::setFromLocation( Location *location )
178 {
179   m_fromLocation = location;
180   m_fromValid = true;
181 }
182
183 Location *RoutePrivate::fromLocation() const
184 {
185   return m_fromLocation;
186 }
187
188 void RoutePrivate::setToLocation( Location *toLocation )
189 {
190   m_toLocation = toLocation;
191   m_toValid = true;
192 }
193
194 QString RoutePrivate::parseJORECode( const QString &joreCode ) const
195 {
196   QString retVal;
197
198   QString areaTransportTypeCode( joreCode.mid(0,1) );
199   QString lineCode( joreCode.mid(1,3) );
200   QString letterVariant( joreCode.mid(4,1) );
201   QString letterNumberVariant( joreCode.mid(5,1) );
202   QString direction( joreCode.mid(6,1) );
203
204   lineCode.setNum( lineCode.toInt() );
205
206   retVal = lineCode;
207
208   if ( letterVariant != " " ) {
209     retVal += letterVariant;
210   }
211
212   return retVal;
213 }
214
215 Location *RoutePrivate::toLocation() const
216 {
217   return m_toLocation;
218 }
219
220 bool RoutePrivate::fromValid()
221 {
222   return m_fromValid;
223 }
224
225 bool RoutePrivate::toValid()
226 {
227   return m_toValid;
228 }