Bimba.git

commit 3fd199e39af254d3a12f370f92762e9660efd889

Author: Adam Pioterek <adam.pioterek@protonmail.ch>

left icons in suggestions & prepare for other suggestions

%!v(PANIC=String method: strings: negative Repeat count)


diff --git a/.idea/misc.xml b/.idea/misc.xml
index 635999df1e86791ad3787e455b4524e4d8879b93..ba7052b8197ddf8ba8756022d905d03055c7ad60 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -24,7 +24,7 @@         
       </value>
     </option>
   </component>
-  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
+  <component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
     <output url="file://$PROJECT_DIR$/build/classes" />
   </component>
   <component name="ProjectType">




diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt
index 95d223cddcf4b3c1ab52227267f8e07c214d86b2..c81e53dcb5b80eed4e7dceefd4bab4e8bbd0c000 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/activities/DashActivity.kt
@@ -22,6 +22,8 @@ import android.util.Log
 import kotlinx.android.synthetic.main.activity_dash.*
 import ml.adamsprogs.bimba.datasources.TimetableDownloader
 import ml.adamsprogs.bimba.datasources.VmClient
+import ml.adamsprogs.bimba.models.suggestions.GtfsSuggestion
+import ml.adamsprogs.bimba.models.suggestions.StopSuggestion
 
 //todo cards
 class DashActivity : AppCompatActivity(), MessageReceiver.OnTimetableDownloadListener,
@@ -29,7 +31,7 @@         FavouritesAdapter.OnMenuItemClickListener, Favourite.OnVmPreparedListener {
     val context: Context = this
     private val receiver = MessageReceiver.getMessageReceiver()
     lateinit var timetable: Timetable
-    var stops: List<StopSuggestion>? = null
+    var suggestions: List<GtfsSuggestion>? = null
     private lateinit var drawerLayout: DrawerLayout
     private lateinit var drawerView: NavigationView
     lateinit var favouritesList: RecyclerView
@@ -44,7 +46,7 @@         AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_AUTO)
         setSupportActionBar(toolbar)
         supportActionBar?.title = getString(R.string.merge_favourites)
 
-        getStops()
+        getSuggestions()
 
         prepareFavourites()
 
@@ -80,7 +82,7 @@         searchView.setOnFocusChangeListener(object : FloatingSearchView.OnFocusChangeListener {
             override fun onFocus() {
                 favouritesList.visibility = View.GONE
                 thread {
-                    val newStops = stops!!.filter { deAccent(it.body.split("\n")[0]).contains(deAccent(searchView.query), true) }
+                    val newStops = suggestions!!.filter { deAccent(it.name).contains(deAccent(searchView.query), true) }
                     runOnUiThread { searchView.swapSuggestions(newStops) }
                 }
             }
@@ -94,7 +96,7 @@         searchView.setOnQueryChangeListener({ oldQuery, newQuery ->
             if (oldQuery != "" && newQuery == "")
                 searchView.clearSuggestions()
             thread {
-                val newStops = stops!!.filter { deAccent(it.body.split("\n")[0]).contains(deAccent(newQuery), true) }
+                val newStops = suggestions!!.filter { deAccent(it.name).contains(deAccent(newQuery), true) }
                 runOnUiThread { searchView.swapSuggestions(newStops) }
             }
         })
@@ -107,33 +109,27 @@                 if (view == null) {
                     view = View(context)
                 }
                 imm.hideSoftInputFromWindow(view.windowToken, 0)
-                intent = Intent(context, StopSpecifyActivity::class.java)
-                searchSuggestion as StopSuggestion
-                intent.putExtra(StopSpecifyActivity.EXTRA_STOP_IDS, searchSuggestion.ids.joinToString(",") { it.id })
-                intent.putExtra(StopSpecifyActivity.EXTRA_STOP_NAME, searchSuggestion.name)
-                startActivity(intent)
+                if (searchSuggestion is StopSuggestion) {
+                    intent = Intent(context, StopSpecifyActivity::class.java)
+                    intent.putExtra(StopSpecifyActivity.EXTRA_STOP_IDS, searchSuggestion.ids.joinToString(",") { it.id })
+                    intent.putExtra(StopSpecifyActivity.EXTRA_STOP_NAME, searchSuggestion.name)
+                    startActivity(intent)
+                } //todo if line
             }
 
             override fun onSearchAction(query: String) {
             }
         })
 
-        searchView.setOnBindSuggestionCallback { _, _, textView, item, _ ->
-            val suggestion = item as StopSuggestion
-            val text = suggestion.body.split("\n")
-            val colour = when (text[1]) {
-                "A" -> "#${getColour(R.color.zoneA, context).toString(16)}"
-                "B" -> "#${getColour(R.color.zoneB, context).toString(16)}"
-                "C" -> "#${getColour(R.color.zoneC, context).toString(16)}"
-                else -> "#000000"
-            }
-            val t = "<small><font color=\"$colour\">" + text[1] + "</font></small>"
+        searchView.setOnBindSuggestionCallback { _, iconView, textView, item, _ ->
+            val suggestion = item as GtfsSuggestion
             if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
-                textView.text = Html.fromHtml("${text[0]} $t", Html.FROM_HTML_MODE_LEGACY)
+                textView.text = Html.fromHtml(item.body, Html.FROM_HTML_MODE_LEGACY)
             } else {
                 @Suppress("DEPRECATION")
-                textView.text = Html.fromHtml(text[0] + "<br/>" + t)
+                textView.text = Html.fromHtml(item.body)
             }
+            iconView.setImageDrawable(getDrawable(suggestion.getIcon(), context))
         }
 
         searchView.attachNavigationDrawerToMenuButton(drawer_layout as DrawerLayout)
@@ -152,9 +148,9 @@         Log.i("VM", "DataSetChange")
         favouritesList.adapter.notifyDataSetChanged()
     }
 
-    private fun getStops() {
+    private fun getSuggestions() {
         timetable = Timetable.getTimetable(this)
-        stops = timetable.getStops()
+        suggestions = timetable.getStopSuggestions(context) //todo get lines, bike stations
     }
 
     private fun prepareListeners() {
@@ -239,7 +235,7 @@             else -> getString(R.string.error_try_later)
         }
         Snackbar.make(findViewById(R.id.drawer_layout), message, Snackbar.LENGTH_LONG).show()
         if (result == TimetableDownloader.RESULT_FINISHED) {
-            stops = timetable.getStops()
+            getSuggestions()
 
             drawerView.menu.findItem(R.id.drawer_validity_since).title = getString(R.string.valid_since, timetable.getValidSince())
             drawerView.menu.findItem(R.id.drawer_validity_till).title = getString(R.string.valid_since, timetable.getValidTill())




diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt
index 6ebab7a4cf100215983971ffc6d4a0caef984d81..379fdcf5eabdc2bae0b4e879e65d338ac42f69c8 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/activities/StopActivity.kt
@@ -28,7 +28,7 @@ import ml.adamsprogs.bimba.R
 import ml.adamsprogs.bimba.datasources.TimetableDownloader
 import ml.adamsprogs.bimba.datasources.VmClient
 import ml.adamsprogs.bimba.getMode
-import ml.adamsprogs.bimba.gtfs.AgencyAndId
+import ml.adamsprogs.bimba.models.gtfs.AgencyAndId
 import ml.adamsprogs.bimba.models.*
 import java.util.*
 import kotlin.concurrent.thread




diff --git a/app/src/main/java/ml/adamsprogs/bimba/activities/StopSpecifyActivity.kt b/app/src/main/java/ml/adamsprogs/bimba/activities/StopSpecifyActivity.kt
index 2e72955d6dc31befe602c2bd85c587c98c4281e4..1c74037fc464c9680a7f5b748a2af5c89e00c328 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/activities/StopSpecifyActivity.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/activities/StopSpecifyActivity.kt
@@ -7,7 +7,7 @@ import android.view.View
 import android.view.ViewGroup
 import kotlinx.android.synthetic.main.activity_stop_specify.*
 import ml.adamsprogs.bimba.R
-import ml.adamsprogs.bimba.gtfs.AgencyAndId
+import ml.adamsprogs.bimba.models.gtfs.AgencyAndId
 import ml.adamsprogs.bimba.models.Timetable
 import android.content.Context
 import android.widget.TextView




diff --git a/app/src/main/java/ml/adamsprogs/bimba/datasources/CacheManager.kt b/app/src/main/java/ml/adamsprogs/bimba/datasources/CacheManager.kt
index f1bfa2a009a5b0ca6704a4ed1b39178c1748cbfd..71130764f796ebe17e68897bd6ec9899accfe5b1 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/datasources/CacheManager.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/datasources/CacheManager.kt
@@ -3,7 +3,7 @@
 import android.content.Context
 import android.content.SharedPreferences
 import ml.adamsprogs.bimba.models.Plate
-import ml.adamsprogs.bimba.gtfs.AgencyAndId
+import ml.adamsprogs.bimba.models.gtfs.AgencyAndId
 
 class CacheManager private constructor(context: Context) {
     companion object {




diff --git a/app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt b/app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt
index 0bd7aabfb4cc0d0e29efa6888c121c73b577f397..bca95c8095ea42c1ee18018bb09d082fba1f8a28 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/datasources/VmClient.kt
@@ -13,7 +13,7 @@ import ml.adamsprogs.bimba.calendarFromIso
 import ml.adamsprogs.bimba.models.*
 import okhttp3.FormBody
 import okhttp3.OkHttpClient
-import ml.adamsprogs.bimba.gtfs.AgencyAndId
+import ml.adamsprogs.bimba.models.gtfs.AgencyAndId
 import ml.adamsprogs.bimba.secondsAfterMidnight
 import java.io.IOException
 import java.util.*




diff --git a/app/src/main/java/ml/adamsprogs/bimba/extensions.kt b/app/src/main/java/ml/adamsprogs/bimba/extensions.kt
index c0c65137d2a374a988d325f51c17017b09e82339..b2b0ef86114e2a778919fb717f06658e43fc48f5 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/extensions.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/extensions.kt
@@ -1,6 +1,7 @@
 package ml.adamsprogs.bimba
 
 import android.content.Context
+import android.graphics.drawable.Drawable
 import android.os.Build
 import ml.adamsprogs.bimba.activities.StopActivity
 import java.text.SimpleDateFormat
@@ -55,6 +56,14 @@     (return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
         context.resources.getColor(id, null)
     else
         context.resources.getColor(id))
+}
+
+fun getDrawable(id: Int, context: Context): Drawable {
+    @Suppress("DEPRECATION")
+    (return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
+        context.resources.getDrawable(id, null)
+    else
+        context.resources.getDrawable(id))
 }
 
 internal fun Calendar.getMode(): Int {




diff --git a/app/src/main/java/ml/adamsprogs/bimba/gtfs/AgencyAndId.kt b/app/src/main/java/ml/adamsprogs/bimba/gtfs/AgencyAndId.kt
deleted file mode 100644
index f54736463c26017c29e5aff321a69dbd3b0ae99a..0000000000000000000000000000000000000000
--- a/app/src/main/java/ml/adamsprogs/bimba/gtfs/AgencyAndId.kt
+++ /dev/null
@@ -1,19 +0,0 @@
-package ml.adamsprogs.bimba.gtfs
-
-import java.io.Serializable
-
-data class AgencyAndId(val id: String) : Serializable, Comparable<AgencyAndId> {
-    override fun compareTo(other: AgencyAndId): Int {
-        return this.toString().compareTo(other.toString())
-    }
-
-    companion object {
-        fun convertFromString(str: String): AgencyAndId {
-            return AgencyAndId(str)
-        }
-    }
-
-    override fun toString(): String {
-        return id
-    }
-}
\ No newline at end of file




diff --git a/app/src/main/java/ml/adamsprogs/bimba/gtfs/Calendar.kt b/app/src/main/java/ml/adamsprogs/bimba/gtfs/Calendar.kt
deleted file mode 100644
index f1a7cd31e0c9b143e3d887a60718e5df0aec5ce8..0000000000000000000000000000000000000000
--- a/app/src/main/java/ml/adamsprogs/bimba/gtfs/Calendar.kt
+++ /dev/null
@@ -1,4 +0,0 @@
-package ml.adamsprogs.bimba.gtfs
-
-data class Calendar(val monday: Boolean, val tuesday: Boolean, val wednesday: Boolean, val thursday: Boolean,
-                    val friday: Boolean, val saturday: Boolean, val sunday: Boolean)
\ No newline at end of file




diff --git a/app/src/main/java/ml/adamsprogs/bimba/gtfs/Route.kt b/app/src/main/java/ml/adamsprogs/bimba/gtfs/Route.kt
deleted file mode 100644
index ceda3870de13383663d0007bb352599094f1b465..0000000000000000000000000000000000000000
--- a/app/src/main/java/ml/adamsprogs/bimba/gtfs/Route.kt
+++ /dev/null
@@ -1,6 +0,0 @@
-package ml.adamsprogs.bimba.gtfs
-
-
-data class Route(val id:AgencyAndId, val agency: AgencyAndId, val shortName: String,
-                 val longName: String, val description: String, val type: Int, val colour: Int,
-                 val textColour: Int, val modifications: HashMap<String, String>)
\ No newline at end of file




diff --git a/app/src/main/java/ml/adamsprogs/bimba/gtfs/Trip.kt b/app/src/main/java/ml/adamsprogs/bimba/gtfs/Trip.kt
deleted file mode 100644
index 528c6cfd5afa4a35a9a1b6d4759a99e5584e3146..0000000000000000000000000000000000000000
--- a/app/src/main/java/ml/adamsprogs/bimba/gtfs/Trip.kt
+++ /dev/null
@@ -1,9 +0,0 @@
-package ml.adamsprogs.bimba.gtfs
-
-data class Trip(val routeId: AgencyAndId, val serviceId: AgencyAndId, val id: ID,
-                val headsign: String, val direction: Int, val shapeId: AgencyAndId,
-                val wheelchairAccessible: Boolean) {
-    data class ID(val rawId:String, val id: AgencyAndId, val modification: Set<Modification>, val isMain: Boolean) {
-        data class Modification(val id: AgencyAndId, val stopRange: IntRange?)
-    }
-}
\ No newline at end of file




diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt b/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt
index 86a52ddb1ff8c1ce1983ab602a96a72e7c7041b2..04c6d02d8918c85da101628c7e61308c1a96037d 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/models/Departure.kt
@@ -1,7 +1,7 @@
 package ml.adamsprogs.bimba.models
 
 import ml.adamsprogs.bimba.rollTime
-import ml.adamsprogs.bimba.gtfs.AgencyAndId
+import ml.adamsprogs.bimba.models.gtfs.AgencyAndId
 import ml.adamsprogs.bimba.safeSplit
 import java.io.Serializable
 import java.util.*




diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt b/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt
index 54880ff5ae53f5698aef244c4a2827c8fd8e3e89..eb0766cbe163d61bf37d2779ec7c1f5f39c7ae64 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/models/Favourite.kt
@@ -6,7 +6,7 @@ import android.os.Parcel
 import android.os.Parcelable
 import ml.adamsprogs.bimba.MessageReceiver
 import ml.adamsprogs.bimba.datasources.VmClient
-import ml.adamsprogs.bimba.gtfs.AgencyAndId
+import ml.adamsprogs.bimba.models.gtfs.AgencyAndId
 import java.util.*
 import kotlin.collections.ArrayList
 import kotlin.collections.HashMap




diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/FavouriteStorage.kt b/app/src/main/java/ml/adamsprogs/bimba/models/FavouriteStorage.kt
index a1aa99bf98a5d35ea57fe985c9d62645885644aa..f2df3265ab1547b79f57a69f691cca4c137254bf 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/models/FavouriteStorage.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/models/FavouriteStorage.kt
@@ -5,7 +5,7 @@ import android.content.SharedPreferences
 import com.google.gson.Gson
 import com.google.gson.JsonArray
 import com.google.gson.JsonObject
-import ml.adamsprogs.bimba.gtfs.AgencyAndId
+import ml.adamsprogs.bimba.models.gtfs.AgencyAndId
 
 
 class FavouriteStorage private constructor(context: Context) : Iterable<Favourite> {




diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/Plate.kt b/app/src/main/java/ml/adamsprogs/bimba/models/Plate.kt
index 74de88e77e2cde41b56eb12ab07204a0b81a28a2..43ff657d166e562c108df2eeacc2aa2031be0cd1 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/models/Plate.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/models/Plate.kt
@@ -1,6 +1,6 @@
 package ml.adamsprogs.bimba.models
 
-import ml.adamsprogs.bimba.gtfs.AgencyAndId
+import ml.adamsprogs.bimba.models.gtfs.AgencyAndId
 import java.io.Serializable
 
 data class Plate(val id: ID, val departures: HashMap<AgencyAndId, HashSet<Departure>>?) {




diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/StopSegment.kt b/app/src/main/java/ml/adamsprogs/bimba/models/StopSegment.kt
index 39d6ebd24628bd690314b6159ac0b46d8f580bb1..c982aa67348bc8e1eab7f62988ea1eba4e1f2088 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/models/StopSegment.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/models/StopSegment.kt
@@ -2,7 +2,7 @@ package ml.adamsprogs.bimba.models
 
 import android.os.Parcel
 import android.os.Parcelable
-import ml.adamsprogs.bimba.gtfs.AgencyAndId
+import ml.adamsprogs.bimba.models.gtfs.AgencyAndId
 
 data class StopSegment(val stop: AgencyAndId, var plates: Set<Plate.ID>?) : Parcelable {
     constructor(parcel: Parcel) : this(




diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/StopSuggestion.kt b/app/src/main/java/ml/adamsprogs/bimba/models/StopSuggestion.kt
deleted file mode 100644
index 834be2d0c8ac3597c63979d1f775941b511c5465..0000000000000000000000000000000000000000
--- a/app/src/main/java/ml/adamsprogs/bimba/models/StopSuggestion.kt
+++ /dev/null
@@ -1,40 +0,0 @@
-package ml.adamsprogs.bimba.models
-
-import android.os.Parcel
-import android.os.Parcelable
-import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion
-import ml.adamsprogs.bimba.gtfs.AgencyAndId
-
-class StopSuggestion(val name: String, val ids: Set<AgencyAndId>, val zone: String) : SearchSuggestion, Comparable<StopSuggestion> {
-
-    @Suppress("UNCHECKED_CAST")
-    constructor(parcel: Parcel) : this(parcel.readString(), parcel.readString().split(",").map { AgencyAndId(it) }.toSet(), parcel.readString())
-
-    override fun describeContents(): Int {
-        return Parcelable.CONTENTS_FILE_DESCRIPTOR
-    }
-
-    override fun writeToParcel(dest: Parcel?, flags: Int) {
-        dest?.writeString(name)
-        dest?.writeString(ids.joinToString(",") { it.toString() })
-        dest?.writeString(zone)
-    }
-
-    override fun getBody(): String {
-        return "$name\n$zone"
-    }
-
-    override fun compareTo(other: StopSuggestion): Int {
-        return name.compareTo(other.name)
-    }
-
-    companion object CREATOR : Parcelable.Creator<StopSuggestion> {
-        override fun createFromParcel(parcel: Parcel): StopSuggestion {
-            return StopSuggestion(parcel)
-        }
-
-        override fun newArray(size: Int): Array<StopSuggestion?> {
-            return arrayOfNulls(size)
-        }
-    }
-}
\ No newline at end of file




diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/Timetable.kt b/app/src/main/java/ml/adamsprogs/bimba/models/Timetable.kt
index 4abed4644acf22a83679d9416b9c61299ce1719f..03e2eab9477450a925066438b53977be6d01c4cd 100644
--- a/app/src/main/java/ml/adamsprogs/bimba/models/Timetable.kt
+++ b/app/src/main/java/ml/adamsprogs/bimba/models/Timetable.kt
@@ -3,10 +3,13 @@
 import android.content.Context
 import com.univocity.parsers.csv.CsvParser
 import com.univocity.parsers.csv.CsvParserSettings
-import ml.adamsprogs.bimba.gtfs.AgencyAndId
-import ml.adamsprogs.bimba.gtfs.Route
-import ml.adamsprogs.bimba.gtfs.Trip
-import ml.adamsprogs.bimba.gtfs.Calendar
+import ml.adamsprogs.bimba.R
+import ml.adamsprogs.bimba.getColour
+import ml.adamsprogs.bimba.models.gtfs.AgencyAndId
+import ml.adamsprogs.bimba.models.gtfs.Route
+import ml.adamsprogs.bimba.models.gtfs.Trip
+import ml.adamsprogs.bimba.models.gtfs.Calendar
+import ml.adamsprogs.bimba.models.suggestions.StopSuggestion
 import ml.adamsprogs.bimba.secondsAfterMidnight
 import org.supercsv.cellprocessor.ift.CellProcessor
 import org.supercsv.io.CsvMapReader
@@ -44,10 +47,10 @@
     fun refresh() {
         //cacheManager.recreate(getStopDeparturesByPlates(cacheManager.keys().toSet()))
 
-        //getStops(true)
+        //getStopSuggestions(true)
     }
 
-    fun getStops(force: Boolean = false): List<StopSuggestion> {
+    fun getStopSuggestions(context: Context, force: Boolean = false): List<StopSuggestion> {
         if (_stops != null && !force)
             return _stops!!
 
@@ -67,7 +70,16 @@             ids[it[2]]!!.add(AgencyAndId(it[0]))
             zones[it[2]] = it[5]
         }
 
-        _stops = ids.map { StopSuggestion(it.key, it.value, zones[it.key]!!) }.sorted()
+
+        _stops = ids.map {
+            val colour = when (zones[it.key]) {
+                "A" -> "#${getColour(R.color.zoneA, context).toString(16)}"
+                "B" -> "#${getColour(R.color.zoneB, context).toString(16)}"
+                "C" -> "#${getColour(R.color.zoneC, context).toString(16)}"
+                else -> "#000000"
+            }
+            StopSuggestion(it.key, it.value, zones[it.key]!!, colour)
+        }.sorted()
         return _stops!!
     }
 




diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/AgencyAndId.kt b/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/AgencyAndId.kt
new file mode 100644
index 0000000000000000000000000000000000000000..66c8d620d3dfbcd85c3def1d14d5cfee300e878e
--- /dev/null
+++ b/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/AgencyAndId.kt
@@ -0,0 +1,19 @@
+package ml.adamsprogs.bimba.models.gtfs
+
+import java.io.Serializable
+
+data class AgencyAndId(val id: String) : Serializable, Comparable<AgencyAndId> {
+    override fun compareTo(other: AgencyAndId): Int {
+        return this.toString().compareTo(other.toString())
+    }
+
+    companion object {
+        fun convertFromString(str: String): AgencyAndId {
+            return AgencyAndId(str)
+        }
+    }
+
+    override fun toString(): String {
+        return id
+    }
+}
\ No newline at end of file




diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Calendar.kt b/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Calendar.kt
new file mode 100644
index 0000000000000000000000000000000000000000..aad6742b778ffe1dda196494e374adb46cc4550d
--- /dev/null
+++ b/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Calendar.kt
@@ -0,0 +1,4 @@
+package ml.adamsprogs.bimba.models.gtfs
+
+data class Calendar(val monday: Boolean, val tuesday: Boolean, val wednesday: Boolean, val thursday: Boolean,
+                    val friday: Boolean, val saturday: Boolean, val sunday: Boolean)
\ No newline at end of file




diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Route.kt b/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Route.kt
new file mode 100644
index 0000000000000000000000000000000000000000..a93eeec0cd52a162376220db166b5ad6d7ba8785
--- /dev/null
+++ b/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Route.kt
@@ -0,0 +1,50 @@
+package ml.adamsprogs.bimba.models.gtfs
+
+import android.os.Parcel
+import android.os.Parcelable
+
+
+data class Route(val id: AgencyAndId, val agency: AgencyAndId, val shortName: String,
+                 val longName: String, val description: String, val type: Int, val colour: Int,
+                 val textColour: Int, val modifications: HashMap<String, String>) : Parcelable {
+    companion object CREATOR : Parcelable.Creator<Route> {
+        const val TYPE_BUS = 3
+        const val TYPE_TRAM = 0
+
+        override fun createFromParcel(parcel: Parcel): Route {
+            return Route(parcel)
+        }
+
+        override fun newArray(size: Int): Array<Route?> {
+            return arrayOfNulls(size)
+        }
+    }
+
+    @Suppress("UNCHECKED_CAST")
+    constructor(parcel: Parcel) : this(
+            AgencyAndId(parcel.readString()),
+            AgencyAndId(parcel.readString()),
+            parcel.readString(),
+            parcel.readString(),
+            parcel.readString(),
+            parcel.readInt(),
+            parcel.readInt(),
+            parcel.readInt(),
+            parcel.readSerializable() as HashMap<String, String>)
+
+    override fun writeToParcel(parcel: Parcel, flags: Int) {
+        parcel.writeString(id.id)
+        parcel.writeString(agency.id)
+        parcel.writeString(shortName)
+        parcel.writeString(longName)
+        parcel.writeString(description)
+        parcel.writeInt(type)
+        parcel.writeInt(colour)
+        parcel.writeInt(textColour)
+        parcel.writeSerializable(modifications)
+    }
+
+    override fun describeContents(): Int {
+        return Parcelable.CONTENTS_FILE_DESCRIPTOR
+    }
+}
\ No newline at end of file




diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Trip.kt b/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Trip.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6e2de9c4c35d16fd71e0a31745ee277dc5947134
--- /dev/null
+++ b/app/src/main/java/ml/adamsprogs/bimba/models/gtfs/Trip.kt
@@ -0,0 +1,9 @@
+package ml.adamsprogs.bimba.models.gtfs
+
+data class Trip(val routeId: AgencyAndId, val serviceId: AgencyAndId, val id: ID,
+                val headsign: String, val direction: Int, val shapeId: AgencyAndId,
+                val wheelchairAccessible: Boolean) {
+    data class ID(val rawId:String, val id: AgencyAndId, val modification: Set<Modification>, val isMain: Boolean) {
+        data class Modification(val id: AgencyAndId, val stopRange: IntRange?)
+    }
+}
\ No newline at end of file




diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/GtfsSuggestion.kt b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/GtfsSuggestion.kt
new file mode 100644
index 0000000000000000000000000000000000000000..1fad7990dce4990d592b0cc17c9afec488b85a4d
--- /dev/null
+++ b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/GtfsSuggestion.kt
@@ -0,0 +1,7 @@
+package ml.adamsprogs.bimba.models.suggestions
+
+import com.arlib.floatingsearchview.suggestions.model.SearchSuggestion
+
+abstract class GtfsSuggestion(val name: String) : SearchSuggestion {
+    abstract fun getIcon(): Int
+}
\ No newline at end of file




diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/LineSuggestion.kt b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/LineSuggestion.kt
new file mode 100644
index 0000000000000000000000000000000000000000..6975aea52f83aa7a8a3b744b991369eff47fcc94
--- /dev/null
+++ b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/LineSuggestion.kt
@@ -0,0 +1,44 @@
+package ml.adamsprogs.bimba.models.suggestions
+
+import android.os.Parcel
+import android.os.Parcelable
+import ml.adamsprogs.bimba.R
+import ml.adamsprogs.bimba.models.gtfs.Route
+
+class LineSuggestion(name: String, private val route: Route) : GtfsSuggestion(name) {
+    constructor(parcel: Parcel) : this(
+            parcel.readString(),
+            parcel.readParcelable(Route::class.java.classLoader))
+
+    override fun writeToParcel(parcel: Parcel, flags: Int) {
+        parcel.writeString(name)
+        parcel.writeParcelable(route, flags)
+    }
+
+    override fun describeContents(): Int {
+        return 0
+    }
+
+    override fun getIcon(): Int {
+        return when (route.type) {
+            Route.TYPE_BUS -> R.drawable.ic_bus
+            Route.TYPE_TRAM -> R.drawable.ic_tram
+            else -> R.drawable.ic_vehicle
+        }
+    }
+
+    override fun getBody(): String {
+        return name
+    }
+
+
+    companion object CREATOR : Parcelable.Creator<LineSuggestion> {
+        override fun createFromParcel(parcel: Parcel): LineSuggestion {
+            return LineSuggestion(parcel)
+        }
+
+        override fun newArray(size: Int): Array<LineSuggestion?> {
+            return arrayOfNulls(size)
+        }
+    }
+}
\ No newline at end of file




diff --git a/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/StopSuggestion.kt b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/StopSuggestion.kt
new file mode 100644
index 0000000000000000000000000000000000000000..4f2a5ceb3c32de379ed2cf45be05bfa8f5b9551e
--- /dev/null
+++ b/app/src/main/java/ml/adamsprogs/bimba/models/suggestions/StopSuggestion.kt
@@ -0,0 +1,44 @@
+package ml.adamsprogs.bimba.models.suggestions
+
+import android.os.Parcel
+import android.os.Parcelable
+import ml.adamsprogs.bimba.R
+import ml.adamsprogs.bimba.models.gtfs.AgencyAndId
+
+class StopSuggestion(name: String, val ids: Set<AgencyAndId>, private val zone: String, private val zoneColour: String) : GtfsSuggestion(name), Comparable<StopSuggestion> {
+    @Suppress("UNCHECKED_CAST")
+    constructor(parcel: Parcel) : this(parcel.readString(), parcel.readString().split(",").map { AgencyAndId(it) }.toSet(), parcel.readString(), parcel.readString())
+
+    override fun describeContents(): Int {
+        return Parcelable.CONTENTS_FILE_DESCRIPTOR
+    }
+
+    override fun writeToParcel(dest: Parcel?, flags: Int) {
+        dest?.writeString(name)
+        dest?.writeString(ids.joinToString(",") { it.toString() })
+        dest?.writeString(zone)
+        dest?.writeString(zoneColour)
+    }
+
+    override fun getBody(): String {
+        return "$name <small><font color=\"$zoneColour\">$zone</font></small>"
+    }
+
+    override fun getIcon(): Int {
+        return R.drawable.ic_stop
+    }
+
+    override fun compareTo(other: StopSuggestion): Int {
+        return name.compareTo(other.name)
+    }
+
+    companion object CREATOR : Parcelable.Creator<StopSuggestion> {
+        override fun createFromParcel(parcel: Parcel): StopSuggestion {
+            return StopSuggestion(parcel)
+        }
+
+        override fun newArray(size: Int): Array<StopSuggestion?> {
+            return arrayOfNulls(size)
+        }
+    }
+}
\ No newline at end of file




diff --git a/app/src/main/res/drawable/ic_bus.xml b/app/src/main/res/drawable/ic_bus.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e16e2597920506417f854cec25afe7cf0747dd15
--- /dev/null
+++ b/app/src/main/res/drawable/ic_bus.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M4,16c0,0.88 0.39,1.67 1,2.22L5,20c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1h8v1c0,0.55 0.45,1 1,1h1c0.55,0 1,-0.45 1,-1v-1.78c0.61,-0.55 1,-1.34 1,-2.22L20,6c0,-3.5 -3.58,-4 -8,-4s-8,0.5 -8,4v10zM7.5,17c-0.83,0 -1.5,-0.67 -1.5,-1.5S6.67,14 7.5,14s1.5,0.67 1.5,1.5S8.33,17 7.5,17zM16.5,17c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM18,11L6,11L6,6h12v5z"/>
+</vector>




diff --git a/app/src/main/res/drawable/ic_stop.xml b/app/src/main/res/drawable/ic_stop.xml
new file mode 100644
index 0000000000000000000000000000000000000000..eaf0afaf749baa0f6837f340a2d48419d69cd848
--- /dev/null
+++ b/app/src/main/res/drawable/ic_stop.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:pathData="M12,2C8.13,2 5,5.13 5,9C5,14.25 12,22 12,22C12,22 19,14.25 19,9C19,5.13 15.87,2 12,2zM12,5.758C13.547,5.758 14.799,5.933 14.799,7.158L14.799,10.656C14.799,10.964 14.663,11.241 14.449,11.434L14.449,12.057C14.449,12.249 14.292,12.406 14.1,12.406L13.75,12.406C13.558,12.406 13.4,12.249 13.4,12.057L13.4,11.707L10.6,11.707L10.6,12.057C10.6,12.249 10.442,12.406 10.25,12.406L9.9,12.406C9.708,12.406 9.551,12.249 9.551,12.057L9.551,11.434C9.337,11.241 9.201,10.964 9.201,10.656L9.201,7.158C9.201,5.933 10.453,5.758 12,5.758zM9.9,7.158L9.9,8.908L14.1,8.908L14.1,7.158L9.9,7.158zM10.426,9.957C10.135,9.957 9.9,10.192 9.9,10.482C9.9,10.773 10.135,11.008 10.426,11.008C10.716,11.008 10.951,10.773 10.951,10.482C10.951,10.192 10.716,9.957 10.426,9.957zM13.574,9.957C13.284,9.957 13.049,10.192 13.049,10.482C13.049,10.773 13.284,11.008 13.574,11.008C13.865,11.008 14.1,10.773 14.1,10.482C14.1,10.192 13.865,9.957 13.574,9.957z"
+        android:fillColor="#000000"/>
+</vector>




diff --git a/app/src/main/res/drawable/ic_tram.xml b/app/src/main/res/drawable/ic_tram.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ecef589606701c868fa9caa9a9576b57948efe58
--- /dev/null
+++ b/app/src/main/res/drawable/ic_tram.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M19,16.94L19,8.5c0,-2.79 -2.61,-3.4 -6.01,-3.49l0.76,-1.51L17,3.5L17,2L7,2v1.5h4.75l-0.76,1.52C7.86,5.11 5,5.73 5,8.5v8.44c0,1.45 1.19,2.66 2.59,2.97L6,21.5v0.5h2.23l2,-2L14,20l2,2h2v-0.5L16.5,20h-0.08c1.69,0 2.58,-1.37 2.58,-3.06zM12,18.5c-0.83,0 -1.5,-0.67 -1.5,-1.5s0.67,-1.5 1.5,-1.5 1.5,0.67 1.5,1.5 -0.67,1.5 -1.5,1.5zM17,14L7,14L7,9h10v5z"/>
+</vector>




diff --git a/app/src/main/res/drawable/ic_vehicle.xml b/app/src/main/res/drawable/ic_vehicle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ae6f37bcc062fe9cba244f5a8af0bc67bf16e3c6
--- /dev/null
+++ b/app/src/main/res/drawable/ic_vehicle.xml
@@ -0,0 +1,9 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+        android:width="24dp"
+        android:height="24dp"
+        android:viewportWidth="24.0"
+        android:viewportHeight="24.0">
+    <path
+        android:fillColor="#FF000000"
+        android:pathData="M4,15.5C4,17.43 5.57,19 7.5,19L6,20.5v0.5h12v-0.5L16.5,19c1.93,0 3.5,-1.57 3.5,-3.5L20,5c0,-3.5 -3.58,-4 -8,-4s-8,0.5 -8,4v10.5zM12,17c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2zM18,10L6,10L6,5h12v5z"/>
+</vector>