/*
* Geopaparazzi - Digital field mapping on Android based devices
* Copyright (C) 2016 HydroloGIS (www.hydrologis.com)
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.geopaparazzi.library.forms;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.SparseArray;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.LinearLayout;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import eu.geopaparazzi.library.R;
import eu.geopaparazzi.library.core.ResourcesManager;
import eu.geopaparazzi.library.database.DefaultHelperClasses;
import eu.geopaparazzi.library.database.GPLog;
import eu.geopaparazzi.library.database.IImagesDbHelper;
import eu.geopaparazzi.library.forms.constraints.Constraints;
import eu.geopaparazzi.library.forms.views.GMapView;
import eu.geopaparazzi.library.forms.views.GNfcUidView;
import eu.geopaparazzi.library.forms.views.GView;
import eu.geopaparazzi.library.images.ImageUtilities;
import eu.geopaparazzi.library.util.GPDialogs;
import eu.geopaparazzi.library.util.LibraryConstants;
import static eu.geopaparazzi.library.forms.FormUtilities.TAG_KEY;
import static eu.geopaparazzi.library.forms.FormUtilities.TAG_LABEL;
import static eu.geopaparazzi.library.forms.FormUtilities.TAG_READONLY;
import static eu.geopaparazzi.library.forms.FormUtilities.TAG_SIZE;
import static eu.geopaparazzi.library.forms.FormUtilities.TAG_TYPE;
import static eu.geopaparazzi.library.forms.FormUtilities.TAG_URL;
import static eu.geopaparazzi.library.forms.FormUtilities.TAG_VALUE;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_BOOLEAN;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_CONNECTEDSTRINGCOMBO;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_DATE;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_DOUBLE;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_DYNAMICSTRING;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_INTEGER;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_LABEL;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_LABELWITHLINE;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_MAP;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_NFCUID;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_PICTURES;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_SKETCH;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_STRING;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_STRINGAREA;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_STRINGCOMBO;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_STRINGMULTIPLECHOICE;
import static eu.geopaparazzi.library.forms.FormUtilities.TYPE_TIME;
/**
* The fragment detail view.
*
* @author Andrea Antonello (www.hydrologis.com)
*/
public class FormDetailFragment extends android.support.v4.app.Fragment {
public static final String ARGS_FORMINFO = "args_forminfo";
private HashMap<String, GView> key2WidgetMap = new HashMap<>();
private SparseArray<GView> requestCodes2WidgetMap = new SparseArray<>();
private HashMap<String, Constraints> key2ConstraintsMap = new HashMap<>();
private List<String> keyList = new ArrayList<>();
private String selectedFormName;
private JSONObject sectionObject;
private FormInfoHolder mFormInfoHolder;
private LinearLayout mainView;
public static FormDetailFragment newInstance(FormInfoHolder formInfoHolder) {
FormDetailFragment f = new FormDetailFragment();
Bundle args = new Bundle();
args.putSerializable(ARGS_FORMINFO, formInfoHolder);
f.setArguments(args);
return f;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Bundle arguments = getArguments();
if (arguments != null)
mFormInfoHolder = (FormInfoHolder) arguments.getSerializable(ARGS_FORMINFO);
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = null;
try {
view = inflater.inflate(R.layout.fragment_form_detail, container, false);
mainView = (LinearLayout) view.findViewById(R.id.form_linear);
refreshView(mFormInfoHolder);
} catch (Exception e) {
GPLog.error(this, null, e);
}
return view;
}
public void refreshView(FormInfoHolder formInfoHolder) throws Exception {
if (mainView == null) return;
mFormInfoHolder = formInfoHolder;
long noteId = -1;
double longitude;
double latitude;
if (mFormInfoHolder != null) {
selectedFormName = mFormInfoHolder.formName;
sectionObject = new JSONObject(mFormInfoHolder.sectionObjectString);
noteId = mFormInfoHolder.noteId;
longitude = mFormInfoHolder.longitude;
latitude = mFormInfoHolder.latitude;
} else {
return;
}
mainView.removeAllViews();
if (selectedFormName != null) {
Activity activity = getActivity();
JSONObject formObject = TagsManager.getForm4Name(selectedFormName, sectionObject);
key2WidgetMap.clear();
requestCodes2WidgetMap.clear();
int requestCode = 666;
keyList.clear();
key2ConstraintsMap.clear();
JSONArray formItemsArray = TagsManager.getFormItems(formObject);
int length = formItemsArray.length();
for (int i = 0; i < length; i++) {
JSONObject jsonObject = formItemsArray.getJSONObject(i);
String key = "-"; //$NON-NLS-1$
if (jsonObject.has(TAG_KEY))
key = jsonObject.getString(TAG_KEY).trim();
String label = key;
if (jsonObject.has(TAG_LABEL))
label = jsonObject.getString(TAG_LABEL).trim();
String value = ""; //$NON-NLS-1$
if (jsonObject.has(TAG_VALUE)) {
value = jsonObject.getString(TAG_VALUE).trim();
}
String type = FormUtilities.TYPE_STRING;
if (jsonObject.has(TAG_TYPE)) {
type = jsonObject.getString(TAG_TYPE).trim();
}
boolean readonly = false;
if (jsonObject.has(TAG_READONLY)) {
String readonlyStr = jsonObject.getString(TAG_READONLY).trim();
readonly = Boolean.parseBoolean(readonlyStr);
}
Constraints constraints = new Constraints();
FormUtilities.handleConstraints(jsonObject, constraints);
key2ConstraintsMap.put(key, constraints);
String constraintDescription = constraints.getDescription();
GView addedView = null;
switch (type) {
case TYPE_STRING:
addedView = FormUtilities.addEditText(activity, mainView, label, value, 0, 0, constraintDescription,
readonly);
break;
case TYPE_DYNAMICSTRING:
addedView = FormUtilities.addDynamicEditText(activity, mainView, label, value, 0, constraintDescription,
readonly);
break;
case TYPE_STRINGAREA:
addedView = FormUtilities.addEditText(activity, mainView, label, value, 0, 7, constraintDescription,
readonly);
break;
case TYPE_DOUBLE:
addedView = FormUtilities.addEditText(activity, mainView, label, value, 1, 0, constraintDescription,
readonly);
break;
case TYPE_INTEGER:
addedView = FormUtilities.addEditText(activity, mainView, label, value, 4, 0, constraintDescription,
readonly);
break;
case TYPE_DATE:
addedView = FormUtilities.addDateView(FormDetailFragment.this, mainView, label, value, constraintDescription,
readonly);
break;
case TYPE_TIME:
addedView = FormUtilities.addTimeView(FormDetailFragment.this, mainView, label, value, constraintDescription,
readonly);
break;
case TYPE_LABEL: {
String size = "20"; //$NON-NLS-1$
if (jsonObject.has(TAG_SIZE))
size = jsonObject.getString(TAG_SIZE);
String url = null;
if (jsonObject.has(TAG_URL))
url = jsonObject.getString(TAG_URL);
addedView = FormUtilities.addTextView(activity, mainView, value, size, false, url);
break;
}
case TYPE_LABELWITHLINE: {
String size = "20"; //$NON-NLS-1$
if (jsonObject.has(TAG_SIZE))
size = jsonObject.getString(TAG_SIZE);
String url = null;
if (jsonObject.has(TAG_URL))
url = jsonObject.getString(TAG_URL);
addedView = FormUtilities.addTextView(activity, mainView, value, size, true, url);
break;
}
case TYPE_BOOLEAN:
addedView = FormUtilities.addBooleanView(activity, mainView, label, value, constraintDescription, readonly);
break;
case TYPE_STRINGCOMBO: {
JSONArray comboItems = TagsManager.getComboItems(jsonObject);
String[] itemsArray = TagsManager.comboItems2StringArray(comboItems);
addedView = FormUtilities.addComboView(activity, mainView, label, value, itemsArray, constraintDescription);
break;
}
case TYPE_CONNECTEDSTRINGCOMBO:
LinkedHashMap<String, List<String>> valuesMap = TagsManager.extractComboValuesMap(jsonObject);
addedView = FormUtilities.addConnectedComboView(activity, mainView, label, value, valuesMap,
constraintDescription);
break;
case TYPE_STRINGMULTIPLECHOICE: {
JSONArray comboItems = TagsManager.getComboItems(jsonObject);
String[] itemsArray = TagsManager.comboItems2StringArray(comboItems);
addedView = FormUtilities.addMultiSelectionView(activity, mainView, label, value, itemsArray,
constraintDescription);
break;
}
case TYPE_PICTURES:
addedView = FormUtilities.addPictureView(noteId, this, requestCode, mainView, label, value, constraintDescription);
break;
case TYPE_SKETCH:
addedView = FormUtilities.addSketchView(noteId, this, requestCode, mainView, label, value, constraintDescription);
break;
case TYPE_MAP:
if (value.length() <= 0) {
// need to read image
File tempDir = ResourcesManager.getInstance(activity).getTempDir();
File tmpImage = new File(tempDir, LibraryConstants.TMPPNGIMAGENAME);
if (tmpImage.exists()) {
byte[][] imageAndThumbnailFromPath = ImageUtilities.getImageAndThumbnailFromPath(tmpImage.getAbsolutePath(), 1);
Date date = new Date();
String mapImageName = ImageUtilities.getMapImageName(date);
IImagesDbHelper imageHelper = DefaultHelperClasses.getDefaulfImageHelper();
long imageId = imageHelper.addImage(longitude, latitude, -1.0, -1.0, date.getTime(), mapImageName, imageAndThumbnailFromPath[0], imageAndThumbnailFromPath[1], noteId);
value = "" + imageId;
}
}
addedView = FormUtilities.addMapView(activity, mainView, label, value, constraintDescription);
break;
case TYPE_NFCUID:
addedView = new GNfcUidView(this, null, requestCode, mainView, label, value, constraintDescription);
break;
default:
GPLog.addLogEntry(this, null, null, "Type non implemented yet: " + type);
break;
}
key2WidgetMap.put(key, addedView);
keyList.add(key);
requestCodes2WidgetMap.put(requestCode, addedView);
requestCode++;
}
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
GView gView = requestCodes2WidgetMap.get(requestCode);
if (gView != null) {
gView.setOnActivityResult(data);
}
}
}
@Override
public void onResume() {
super.onResume();
for (int i = 0; i < requestCodes2WidgetMap.size(); i++) {
int key = requestCodes2WidgetMap.keyAt(i);
// get the object by the key.
GView view = requestCodes2WidgetMap.get(key);
if (view instanceof GMapView) {
try {
view.refresh(((GMapView) view).getContext());
} catch (Exception e) {
GPLog.error(this, null, e);
}
}
}
}
/**
* @return the updated form info.
*/
public FormInfoHolder getFormInfoHolder() {
mFormInfoHolder.sectionObjectString = sectionObject.toString();
return mFormInfoHolder;
}
/**
* Store the form items the widgets.
*
* @param doConstraintsCheck if <code>true</code>, a check on all constraints is performed.
* @return <code>null</code>, if everything was saved properly, the key of the items
* that didn't pass the constraint check.
* @throws Exception if something goes wrong.
*/
public String storeFormItems(boolean doConstraintsCheck) throws Exception {
if (selectedFormName == null) {
return null;
}
JSONObject form4Name = TagsManager.getForm4Name(selectedFormName, sectionObject);
JSONArray formItems = TagsManager.getFormItems(form4Name);
// update the items
for (String key : keyList) {
Constraints constraints = key2ConstraintsMap.get(key);
GView view = key2WidgetMap.get(key);
if (view != null) {
String text = view.getValue();
if (doConstraintsCheck && !constraints.isValid(text)) {
return key;
}
try {
if (text != null)
FormUtilities.update(formItems, key, text);
} catch (JSONException e) {
GPLog.error(this, e.getLocalizedMessage(), e);
e.printStackTrace();
}
}
}
FormUtilities.updateExtras(formItems, mFormInfoHolder.latitude, mFormInfoHolder.longitude, null);
return null;
}
}