/*
 * Copyright 2018 Google Inc.
 *
 * 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
 *
 * http://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.sps.data;

// Imports the Google Cloud client library
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.maps.GeoApiContext;
import com.google.maps.GeocodingApi;
import com.google.maps.TimeZoneApi;
import com.google.maps.errors.ApiException;
import com.google.maps.model.GeocodingResult;
import com.google.maps.model.LatLng;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.TimeZone;

/* Location object */
public class Location {

  private String address;
  private double latCoord;
  private double lngCoord;
  private LatLng coords;
  private TimeZone timeZoneObj;
  private String timeZoneID;
  private String timeZoneName;
  private String formattedAddress;

  public Location(String address) {
    this.address = address;
    setProperties();
  }

  public void setProperties() {
    try {
      String apiKey =
          new String(
              Files.readAllBytes(Paths.get(getClass().getResource("/files/apikey.txt").getFile())));
      GeoApiContext context = new GeoApiContext.Builder().apiKey(apiKey).build();
      setCoordinates(context, address);
    } catch (IOException e) {
      System.out.println("API key for maps not found.");
    }
  }

  public void setCoordinates(GeoApiContext context, String address) {
    try {
      GeocodingResult[] results = GeocodingApi.geocode(context, address).await();
      Gson gson = new GsonBuilder().setPrettyPrinting().create();
      this.latCoord = results[0].geometry.location.lat;
      this.lngCoord = results[0].geometry.location.lng;
      this.coords = new LatLng(latCoord, lngCoord);
      this.formattedAddress = results[0].formattedAddress;
      setTimeZone(context, coords);
    } catch (ApiException | IOException | InterruptedException | ArrayIndexOutOfBoundsException e) {
      System.out.println("Error in setting coordinates from Geocoding API.");
      return;
    }
  }

  public void setTimeZone(GeoApiContext context, LatLng location) {
    try {
      TimeZone results = TimeZoneApi.getTimeZone(context, location).await();
      Gson gson = new GsonBuilder().setPrettyPrinting().create();
      this.timeZoneObj = results;
      this.timeZoneID = results.getID();
      this.timeZoneName = results.getDisplayName();
    } catch (ApiException | IOException | InterruptedException | ArrayIndexOutOfBoundsException e) {
      System.out.println("Error in setting timezone from TimeZone API.");
      return;
    }
  }

  public String getAddress() {
    return this.address;
  }

  public String getAddressFormatted() {
    return this.formattedAddress;
  }

  public Double getLat() {
    return this.latCoord;
  }

  public Double getLng() {
    return this.lngCoord;
  }

  public LatLng getCoords() {
    return this.coords;
  }

  public String getTimeZoneID() {
    return this.timeZoneID;
  }

  public String getTimeZoneName() {
    return this.timeZoneName;
  }

  public TimeZone getTimeZone() {
    return this.timeZoneObj;
  }
}

@@ -680,2415 +680,1653 @@
 gle.
-gson.Gson;%0Aimport com.google.gson.GsonBuilder;%0Aimport com.google.maps.GeoApiContext;%0Aimport com.google.maps.GeocodingApi;%0Aimport com.google.maps.TimeZoneApi;%0Aimport com.google.maps.errors.ApiException;%0Aimport com.google.maps.model.GeocodingResult;%0Aimport com.google.maps.model.LatLng;%0Aimport java.io.IOException;%0Aimport java.nio.file.Files;%0Aimport java.nio.file.Paths;%0Aimport java.util.TimeZone;%0A%0A/* Location object */%0Apublic class Location %7B%0A%0A  private String address;%0A  private double latCoord;%0A  private double lngCoord;%0A  private LatLng coords;%0A  private TimeZone timeZoneObj;%0A  private String timeZoneID;%0A  private String timeZoneName;%0A  private String formattedAddress;%0A%0A  public Location(String address) %7B%0A    this.address = address;%0A    setProperties();%0A  %7D%0A%0A  public void setProperties() %7B%0A    try %7B%0A      String apiKey =%0A          new String(%0A              Files.readAllBytes(Paths.get(getClass().getResource(%22/files/apikey.txt%22).getFile())));%0A      GeoApiContext context = new GeoApiContext.Builder().apiKey(apiKey).build();%0A      setCoordinates(context, address);%0A    %7D catch (IOException e) %7B%0A      System.out.println(%22API key for maps not found.%22);%0A    %7D%0A  %7D%0A%0A  public void setCoordinates(GeoApiContext context, String address) %7B%0A    try %7B%0A      GeocodingResult%5B%5D results = GeocodingApi.geocode(context, address).await();%0A      Gson gson = new GsonBuilder().setPrettyPrinting().create();%0A      this.latCoord = results%5B0%5D.geometry.location.lat;%0A      this.lngCoord = results%5B0%5D.geometry.location.lng;%0A      this.coords = new LatLng(latCoord, lngCoord);%0A      this.formattedAddress = results%5B0%5D.formattedAddress;%0A      setTimeZone(context, coords);%0A    %7D catch (ApiException %7C IOException %7C InterruptedException %7C ArrayIndexOutOfBoundsException e) %7B%0A      System.out.println(%22Error in setting coordinates from Geocoding API.%22);%0A      return;%0A    %7D%0A  %7D%0A%0A  public void setTimeZone(GeoApiContext context, LatLng location) %7B%0A    try %7B%0A      TimeZone results = TimeZoneApi.getTimeZone(context, location).await();%0A      Gson gson = new GsonBuilder().setPrettyPrinting().create();%0A      this.timeZoneObj = results;%0A      this.timeZoneID = results.getID();%0A      this.timeZoneName = results.getDisplayName();%0A    %7D catch (ApiException %7C IOException %7C InterruptedException %7C ArrayIndexOutOfBoundsException e) %7B%0A      System.out.println(%22Error in setting timezone from TimeZone API.%22);%0A      return;%0A    %7D
+maps.model.LatLng;%0Aimport java.util.TimeZone;%0A%0A/**%0A * A Location object contains the following properties: address: user-inputted location coords:%0A * coordinates for user-inputted address latCoord: latitude coordinate for location lngCoord:%0A * longitude coordinate for location formattedAddress: user-inputted location formatted by Geocoding%0A * API timeZoneObj: TimeZone object for corresponding LatLng coords timeZoneID: timezone ID for the%0A * location (%22America/Los_Angeles%22) timeZoneName: Standard time zone name for location (%22Pacific%0A * Standard Time%22)%0A *%0A * %3Cp%3EA Location object is only created by LocationUtils.getLocationObject(), ensuring that an%0A * Location object is only created with valid parameters:%0A *%0A * @param address user-inputted location%0A * @param coords coordinates for user-inputted address from Geocoding API%0A * @param formattedAddress user-inputted location formatted by Geocoding API%0A * @param timezone TimeZone object for corresponding LatLng coords from TimeZone API%0A */%0Apublic class Location %7B%0A%0A  private String address;%0A  private double latCoord;%0A  private double lngCoord;%0A  private LatLng coords;%0A  private TimeZone timeZoneObj;%0A  private String timeZoneID;%0A  private String timeZoneName;%0A  private String formattedAddress;%0A%0A  public Location(String address, LatLng coords, String formattedAddress, TimeZone timezone) %7B%0A    this.address = address;%0A    this.coords = coords;%0A    this.formattedAddress = formattedAddress;%0A    this.timeZoneObj = timezone;%0A%0A    this.latCoord = coords.lat;%0A    this.lngCoord = coords.lng;%0A    this.timeZoneName = timeZoneObj.getDisplayName();%0A    this.timeZoneID = timeZoneObj.getID();
 %0A  %7D

Change contract to determine if Location is valid outside of class