---
# System prepended metadata

title: Untitled

---

```swift=

// MARK: - Itinerary

public let ItineraryPlaceSearchConfigurationStream: PlaceSearchConfigurationStreaming {
    init(waypointManager: WaypointManaging) {
        fields = waypointManager.waypoints.enumerate().map { (index, value) in        
            // Value
            var value: Place?
            switch value.storage {
                case .place(let place): value = place
                default: value = nil
            }
            
            return Field(
                value: value
                context: index == 0 ? .origin : .destination
            )
        }
        
        focusingIndex = 
    }
}

public final class ItineraryStepComponent {
    
    public var searchConfigurationStream: PlaceSearchConfigurationStreaming {
        shared { ItineraryPlaceSearchConfigurationStream(waypointManager: waypointManager) }
    }
    
}

public final class ItineraryStepRouter {
    
    func routeToPlaceSearch() {
        let router = placeSearchBuilder.build(
            listener: interactor,
            configuration: searchConfigurationStream
        )
        ...
    }
}

public final class ItineraryStepInteractor: PlaceSearchListener {
    
    let configuration: PlaceSearchConfigurationStreaming

    // PlaceSearchListener

    func didSelect(result: Place) {
        let index = currentIndex
        
        let waypoint = Waypoint(storage: .place(place))
        waypointManager.update(waypoint: waypoint, at: index)
    }
    
    func didSelect(coordinate: Coordinate2D) {
        let index = currentIndex
        
        let waypoint = Waypoint(storage: .coordinate(coordinate))
        waypointManager.update(waypoint: waypoint, at: index)
    }
}

// MARK: - PlaceSearch

public protocol PlaceSearchListener {
    func didSelect(result: Place)
    func didSelect(coordinate: Coordinate2D)
}

public protocol PlaceMapInteractorListener {
    func mapDidChange(location: Coordinate2D)
}

public protocol PlaceSearchConfigurationStreaming {
    public struct Field {
        public let value: Place?
        // public let isFocused: Bool
        public let context: LocationSearchContext 
    }
    
    let fields: Observable<[Field]>
    let focusingIndex: Observable<Int> // ??? 
}


public class PlaceSearchInteractor {
    
    let configuration: PlaceSearchConfigurationStreaming
    
    func mapDidChange(location: Coordinate2D) {
        listener.didSelect(coordinate: location)
    }
    
}


public struct PlacesSearchDependency {
    let waypointStream: Observable<Waypoint>
}

// MARK: - TextSearch

public protocol TextSearchDependency {
    var searchConfigurationStream: PlaceSearchConfigurationStreaming { get }
}

public final class TextSearchComponent: Component<TextSearchDependency>{
    
    let dynamicDependency: PlacesSearchDependency
}

protocol TextSearchInteractorListener: PlacesSearchListener {
    func didSelect(result: Place, at index: Int)
    
    // inherited
    // func goToViewMode(_ viewMode: ViewMode)
}

class TextSearchRouter {
    
}

class TextSearchInteractor {
    
    weak var listener: TextSearchInteractorListener?
    
    init(configuration: PlaceSearchConfigurationStreaming)
    
    override func didBecomeActive() {
        super.didBecomeActive()
        setupObservers()
    }
    
    private func setupObservers() {
        setupTextFieldObservers()
        setupResultObservers()
    }
    
    private func setupTextFieldObservers() {
        // listen to configuration and set/focus text field accordingly
        let fieldValues = configuration.fields.map(\.value)
        
        for index in 0..<fieldValues.count {
            fieldValues[index]
                .subscribe(
                    onNext: { [weak self] value in
                        self?.presenter.setFieldResult(searchResult, at: index)
                        self?.whatsTheNextStep()    // go to next empty index? 
                    }
                )
                .disposeOnDeactivate(interactor: self)
        }
    }
    
    private func setupResultObservers() {
        // Observe text field change from presenter/VC and update result collection view
    }
    
    // View listener
    
    private func didSelect(result: Place, at index: Int) {
        listner?.didSelect(result: result, at: index)
    }
}



```