/*
 * Copyright 2020 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.android.gnd.ui.editobservation;

import androidx.lifecycle.LiveData;
import androidx.lifecycle.LiveDataReactiveStreams;
import androidx.lifecycle.MutableLiveData;
import com.google.android.gnd.model.form.Field;
import com.google.android.gnd.model.observation.Response;
import com.google.android.gnd.ui.common.AbstractViewModel;
import io.reactivex.Single;
import io.reactivex.processors.BehaviorProcessor;
import java8.util.Optional;

public class AbstractFieldViewModel extends AbstractViewModel {

  private final LiveData<Optional<Response>> response;
  private final LiveData<String> responseText;
  private final MutableLiveData<String> error = new MutableLiveData<>();
  private final BehaviorProcessor<Optional<Response>> responseSubject = BehaviorProcessor.create();

  private Field field;

  AbstractFieldViewModel() {
    responseText =
        LiveDataReactiveStreams.fromPublisher(
            responseSubject.distinctUntilChanged().switchMapSingle(this::getDetailsText));
    response = LiveDataReactiveStreams.fromPublisher(responseSubject.distinctUntilChanged());
  }

  void init(Field field, Optional<Response> response) {
    this.field = field;
    setResponse(response);
  }

  private Single<String> getDetailsText(Optional<Response> responseOptional) {
    return Single.just(responseOptional.map(response -> response.getDetailsText(field)).orElse(""));
  }

  public Field getField() {
    return field;
  }

  public LiveData<String> getResponseText() {
    return responseText;
  }

  public LiveData<String> getError() {
    return error;
  }

  public void setError(String value) {
    error.setValue(value);
  }

  LiveData<Optional<Response>> getResponse() {
    return response;
  }

  public void setResponse(Optional<Response> response) {
    responseSubject.onNext(response);
  }
}

@@ -1043,16 +1043,91 @@
 ional;%0A%0A
+/** Defines the state of an inflated %7B@link Field%7D and controls its UI. */%0A
 public c
@@ -1183,16 +1183,40 @@
 odel %7B%0A%0A
+  /** Current value. */%0A
   privat
@@ -1266,54 +1266,250 @@
 se;%0A
-  private final LiveData%3CString%3E responseText;
+%0A  /** Transcoded text to be displayed for the current %7B@link AbstractFieldViewModel#response%7D. */%0A  private final LiveData%3CString%3E responseText;%0A%0A  /** Error message to be displayed for the current %7B@link AbstractFieldViewModel#response%7D. */
 %0A  p
@@ -1578,16 +1578,17 @@
 ta%3C%3E();%0A
+%0A
   privat
@@ -1989,16 +1989,84 @@
 );%0A  %7D%0A%0A
+  // TODO: Add a reference of Field in Response for simplification.%0A
   void i

Add javadocs and comments