 
 import Foundation
 
+/**
+Instances of conforming types have a `city` property which
+ can be used to uniquely idenfify them in the context of Pandemic.
+*/
 public protocol HasCity {
     var city:City { get }
 }
 
-public struct City : Equatable, Hashable {
+/**
+ Represents a city in the game of Pandemic, and as such has a
+ name, and a color
+*/
+public class City : Equatable, Hashable {
+    /// The name of the city
     public let name:String
+
+    /// The color of the city
     public let color:Color
 
     public var hashValue:Int {

    public static let baghdad = City(name: "Baghdad", color: .Black)
    public static let bangkok = City(name: "Bangkok", color: .Red)
    public static let beijing = City(name: "Beijing", color: .Red)

    /**
     An alias for City.bogotá for convenience. It returns the exact same
     instance of City
     */
    public static let bogota = City(name: "Bogotá", color: .Yellow)
    public static let bogotá = bogota
    public static let buenosaires = City(name: "Buenos Aires", color: .Yellow)
    public static let cairo = City(name: "Cairo", color: .Black)
    public static let chennai = City(name: "Chennai", color: .Black)

    public static let tokyo = City(name: "Tokyo", color: .Red)
    public static let washington = City(name: "Washington", color: .Blue)

    public static var allCards:Set<City> = [algiers, atlanta, baghdad, bangkok, beijing, bogotá, buenosaires, cairo, chennai, chicago, delhi, essen, hochiminhcity, hongkong, istanbul, jakarta, johannesburg, karachi, khartoum, kinshasa, kolkata, lagos, lima, london, losangeles, madrid, manila, mexicocity, miami, milan, montreal, moscow, mumbai, newyork, osaka, paris, riyadh, sanfrancisco, santiago, sãopaulo, seoul, shanghai, stpetersburg, sydney, taipei, tehran, tokyo, washington]

    /**
     Finds all cards with names that contain the specified portion of a name.
     
     - returns: All cities whose names contain the string `portionOfName` anywhere
     in their name.

     - remark: It is sufficient to pass just the first 4 characters of any name
     to ensure uniquenss and to return only one City. For example the following
     will code will ensure `myCity` gets the value `City.sanfrancisco`.
     
     ````
     let myCity = City.findByName("san ").first!
     ````
    */
    public static func findByName(portionOfName:String) -> [City] {
        return allCards.findByName(portionOfName)
    }

}
