app/src/main/java/ch/epfl/sdp/appart/AdCreationActivity.java
package ch.epfl.sdp.appart;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.net.Uri;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Space;
import android.widget.Spinner;
import android.widget.TextView;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import ch.epfl.sdp.appart.location.place.address.Address;
import ch.epfl.sdp.appart.location.place.address.AddressFactory;
import com.bumptech.glide.Glide;
import com.google.android.material.snackbar.Snackbar;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import javax.inject.Inject;
import ch.epfl.sdp.appart.ad.AdCreationViewModel;
import ch.epfl.sdp.appart.database.DatabaseService;
import ch.epfl.sdp.appart.ad.PricePeriod;
import ch.epfl.sdp.appart.database.firebaselayout.FirebaseLayout;
import ch.epfl.sdp.appart.utils.ActivityCommunicationLayout;
import dagger.hilt.android.AndroidEntryPoint;
/**
* Activity for creating a new Ad.
* <p>
* It should be accessible only if the user is logged in.
*/
@AndroidEntryPoint
public class AdCreationActivity extends AppCompatActivity {
@Inject
DatabaseService database;
AdCreationViewModel mViewModel;
private final static int PICTURES_IMPORT_ACTIVITY_RESULT = 2;
private List<Uri> picturesUris;
private List<Uri> panoramaUris;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_adcreation);
mViewModel = new ViewModelProvider(this).get(AdCreationViewModel.class);
// init buttons
Button confirmButton = findViewById(R.id.confirm_AdCreation_button);
confirmButton.setOnClickListener((View view) -> createAd());
Button addPhotoButton = findViewById(R.id.addPhoto_AdCreation_button);
addPhotoButton.setOnClickListener((View view) -> takePhoto());
Button createPanoramaTourButton = findViewById(R.id.createVirtualTour_AdCreation_button);
createPanoramaTourButton.setOnClickListener((View view) -> {
Intent intent = new Intent(this, PicturesImportActivity.class);
startActivityForResult(intent, PICTURES_IMPORT_ACTIVITY_RESULT);
});
}
private void setTextView(TextView textView, String content) {
textView.setText(content);
}
/**
* Sets values to viewmodel and confirm creation. If some fields are not filled, it shows a
* snackbar message.
*/
private void createAd() {
// if some fields are not filled, show snackbar
if (!everyFieldFilled()) {
Snackbar.make(findViewById(R.id.horizontal_AdCreation_scrollView),
getResources().getText(R.string.snackbarNotFilled_AdCreation),
Snackbar.LENGTH_SHORT).show();
return;
}
if (picturesUris == null || picturesUris.size() == 0) {
picturesUris = new ArrayList<>();
Resources resources = getApplicationContext().getResources();
picturesUris.add(Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" +
resources.getResourcePackageName(R.drawable.blank_ad) + FirebaseLayout.SEPARATOR +
resources.getResourceTypeName(R.drawable.blank_ad) + FirebaseLayout.SEPARATOR +
resources.getResourceEntryName(R.drawable.blank_ad)));
}
// set values to viewmodel
if(setVMValues()) {
findViewById(R.id.confirm_AdCreation_button).setEnabled(false);
// confirm creation and elaborate result
CompletableFuture<Void> result = mViewModel.confirmCreation();
result.thenAccept(r -> {
Intent intent = new Intent(this, ScrollingActivity.class);
startActivity(intent);
});
result.exceptionally(e -> {
e.printStackTrace();
Snackbar.make(findViewById(R.id.horizontal_AdCreation_scrollView),
getResources().getText(R.string.snackbarFailed_AdCreation),
Snackbar.LENGTH_LONG).show();
findViewById(R.id.confirm_AdCreation_button).setEnabled(true);
return null;
});
} else {
Snackbar.make(findViewById(R.id.horizontal_AdCreation_scrollView),
getResources().getText(R.string.snackbarFailedLocation_AdCreation),
Snackbar.LENGTH_LONG).show();
}
}
/**
* Takes the values from the EditTexts of the activity and sets the values in the ViewModel
*/
private boolean setVMValues() {
try{
AddressFactory.makeAddress(
joinStrings(
R.id.street_AdCreation_editText, R.id.number_AdCreation_ediText),
getContentOfEditText(R.id.npa_AdCreation_editText),
getContentOfEditText(R.id.city_AdCreation_editText)
);
} catch (Exception e){
return false;
}
mViewModel.setTitle(getContentOfEditText(R.id.title_AdCreation_editText));
mViewModel.setStreet(joinStrings(
R.id.street_AdCreation_editText, R.id.number_AdCreation_ediText));
mViewModel.setCity(joinStrings(
R.id.npa_AdCreation_editText, R.id.city_AdCreation_editText));
mViewModel.setPrice(Long.parseLong(getContentOfEditText(R.id.price_AdCreation_editText)));
mViewModel.setPricePeriod(
PricePeriod.ALL.get(
((Spinner) findViewById(R.id.period_AdCreation_spinner))
.getSelectedItemPosition())
);
mViewModel.setDescription(getContentOfEditText(R.id.description_AdCreation_editText));
// TODO modify when logic for adding vrtour is added
mViewModel.setVRTourEnable(false);
mViewModel.setUri(picturesUris);
return true;
}
private String joinStrings(int id1, int id2) {
return getContentOfEditText(id1) + " " + getContentOfEditText(id2);
}
/**
* Checks that every text field is has been filled
*
* @return true if every string is valid, false otherwise
*/
private boolean everyFieldFilled() {
if (stringIsInvalid(getContentOfEditText(R.id.title_AdCreation_editText)) ||
stringIsInvalid(getContentOfEditText(R.id.street_AdCreation_editText)) ||
stringIsInvalid(getContentOfEditText(R.id.number_AdCreation_ediText)) ||
stringIsInvalid(getContentOfEditText(R.id.npa_AdCreation_editText)) ||
stringIsInvalid(getContentOfEditText(R.id.city_AdCreation_editText)) ||
stringIsInvalid(getContentOfEditText(R.id.price_AdCreation_editText)) ||
stringIsInvalid(getContentOfEditText(R.id.description_AdCreation_editText)))
return false;
return true;
}
/**
* Gets the content of the EditText.
*
* @param id the id of the view
* @return the string content of the EditText
*/
private String getContentOfEditText(int id) {
return ((EditText) findViewById(id)).getText().toString();
}
/**
* Checks whether the string is null or empty.
*
* @param s the string to check
* @return true if the string is null or empty, false otherwise
*/
private boolean stringIsInvalid(String s) {
return s == null || s.equals("");
}
/**
* Opens camera activity to take/select images to add to the ad
*/
@SuppressWarnings("deprecation")
private void takePhoto() {
Intent intent = new Intent(this, CameraActivity.class);
intent.putExtra(ActivityCommunicationLayout.PROVIDING_ACTIVITY_NAME,
ActivityCommunicationLayout.AD_CREATION_ACTIVITY);
startActivityForResult(intent, 1);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == 1) {
if (resultCode == RESULT_OK) {
int size = data.getIntExtra(ActivityCommunicationLayout.PROVIDING_SIZE, 0);
List<Uri> listUri = new ArrayList<>();
for (int i = 0; i < size; i++) {
listUri.add(data.getParcelableExtra(ActivityCommunicationLayout.PROVIDING_IMAGE_URI + i));
}
picturesUris = listUri;
fillHorizontalViewWithPictures(findViewById(R.id.pictures_AdCreation_linearLayout), listUri);
}
} else if (requestCode == PICTURES_IMPORT_ACTIVITY_RESULT) {
if (resultCode == RESULT_OK) {
ArrayList<Uri> uris = data.getParcelableArrayListExtra("uris");
if (uris == null) {
throw new IllegalStateException("uris cannot be null");
}
mViewModel.setPanoramaUri(uris);
fillHorizontalViewWithPictures(findViewById(R.id.panorama_AdCreation_linearLayout), uris);
}
}
}
protected void fillHorizontalViewWithPictures(LinearLayout horizontalLayout, List<Uri> uris) {
if (uris == null || uris.isEmpty()) {
return;
}
horizontalLayout.removeAllViews();
for (int i = 0; i < uris.size(); i++) {
LayoutInflater inflater =
(LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View myView = inflater.inflate(R.layout.photo_layout, (ViewGroup) null);
ImageView photo = myView.findViewById(R.id.photo_Photo_imageView);
Glide.with(this).load(uris.get(i)).into(photo);
horizontalLayout.addView(myView);
}
}
}