// ConverterType
enum ConverterType : Int, CustomStringConvertible {
   case FA_TO_CE = 1
   case CE_TO_FA = 2
   init(_ name: String) {
     switch name {
        case “FA_TO_CE”, “1”: self = .FA_TO_CE
        case “CE_TO_FA”, “2”: self = .CE_TO_FA
        default: self = .CE_TO_FA
     }
   }
   var description: String {
      switch self {
        case .FA_TO_CE: return “FA_TO_CE”
        case .CE_TO_FA: return “CE_TO_FA”
      }
   }
   static func enumerate() -> AnyGenerator {
      var nextIndex = FA_TO_CE.rawValue
      return anyGenerator { ConverterType(rawVale: nextIndex++) }
   }
}
// Converter
protocol Converter : CustomStringConvertible {
   var description : String { get }
   var type : ConverterType { get }
   var fahrenheit : Double { get }
   var celsius : Double { get }
}
// FahrenheitToCelsius
class FahrenheitToCelsius : Converter {
   var temperature = 0.0
   convenience init() {
      self.init(temperature: 0.0)
   }
   init(temperature: Double) {
      self.temperature = temperature
   }
   var description : String {
      return “Converter=\(type.description) F=\(fahrenheit) => C=\(celsius)”
   }
   var type : ConverterType {
      return ConverterType.FA_TO_CE
   }
   var fahrenheit : Double {
      return self.temperature
   }
   var celsius : Double {
      return (temperature – 32.0) * (5.0 / 9.0)
   }
}
// CelsiusToFahrenheit
class CelsiusToFahrenheit : Converter {
   var temperature = 0.0
   convenience init() {
      self.init(temperature: 0.0)
   }
   init(temperature: Double) {
      self.temperature = temperature
   }
   var description : String {
      return “Converter=\(type.description) C=\(celsius) => F=\(fahrenheit)”
   }
   var type : ConverterType {
      return ConverterType.CE_TO_FA
   }
   var fahrenheit : Double {
      return ((9.0/5.0) * temperature + 32.0)
   }
   var celsius : Double {
      return self.temperature
   }
}
// TemperatureConverter
class TemperatureConverter {
   func getUserInputDouble() -> Double {
      var value : Double
      while true {
         if let inputSeting = readLine() {
            if let inputNumber = Double(inputString) {
               value = inputNumber
               return value
            }
            else {
               print(“Error! Please re-enter Double value”)
            }
         }
      }
   }
   func convert(mode: ConverterType) {
      if (mode == ConverterType.FA_TO_CE) {
         print(“Please enter temperature (F) : “)
         let converter = FahrenheitToCelsius(temperature: getUserInputDouble())
         print(converter.description)
      }
      else if (mode == ConverterType.CE_TO_FA) {
         print(“Please enter temperature (C) : “)
         let converter = CelsiusToFahrenheit(temperature: getUserInputDouble())
         print(converter.description)
      }
   }
   func getUserInputConverterType() -> ConverterType {
       var i = 0
       let g = ConvertType.FA_TO_CE
       repeat {
          print(“Please select converter type (1 or 2):”)
          if let inputString = readLine() {
             if let inputNumber = Int(inputString) {
                i = inputNumber
                if let c = ConverterType(rawValue: i) {
                   return c
                }
             }
          }
       } while i < 1 || i > 2
       return g
   }
   func calculateAll() {
      for i in 1…2 {
         convert(ConverterType(rawValue: i)!)
      }
      for c in ConverterType.enumerate() {
         convert(c)
      }
      var convertList = [Converter]()
      convertList.append(FahrenheitToCelsius(temperature: 75.5))
      convertList.append(CelsiusToFahrenheit(temperature: 25.5))
      for c in convertList {
         print(c.description)
      }
      convert(getUserInputConverterType())
   }
}