/**
* ORcycle, Copyright 2014, 2015, PSU Transportation, Technology, and People Lab.
*
* ORcycle 2.2.0 has introduced new app features: safety focus with new buttons
* to report safety issues and crashes (new questionnaires), expanded trip
* questionnaire (adding questions besides trip purpose), app utilization
* reminders, app tutorial, and updated font and color schemes.
*
* @author Bryan.Blanc <bryanpblanc@gmail.com> (code)
* @author Miguel Figliozzi <figliozzi@pdx.edu> and ORcycle team (general app
* design and features, report questionnaires and new ORcycle features)
*
* For more information on the project, go to
* http://www.pdx.edu/transportation-lab/orcycle and http://www.pdx.edu/transportation-lab/app-development
*
* Updated/modified for Oregon pilot study and app deployment.
*
* ORcycle 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 any later version.
* ORcycle 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
* ORcycle. If not, see <http://www.gnu.org/licenses/>.
*
*************************************************************************************
*
* Cycle Altanta, Copyright 2012 Georgia Institute of Technology
* Atlanta, GA. USA
*
* @author Christopher Le Dantec <ledantec@gatech.edu>
* @author Anhong Guo <guoanhong15@gmail.com>
*
* Updated/Modified for Atlanta's app deployment. Based on the
* CycleTracks codebase for SFCTA.
*
* CycleTracks, Copyright 2009,2010 San Francisco County Transportation Authority
* San Francisco, CA, USA
*
* @author Billy Charlton <billy.charlton@sfcta.org>
*
* This file is part of CycleTracks.
*
* CycleTracks 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.
*
* CycleTracks 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 CycleTracks. If not, see <http://www.gnu.org/licenses/>.
*/
package edu.pdx.cecs.orcycle;
import android.content.Context;
import android.database.Cursor;
import android.location.Location;
public class NoteData {
public static final String MODULE_TAG = "NoteData";
public static int STATUS_INCOMPLETE = 0;
public static int STATUS_COMPLETE = 1;
public static int STATUS_SENT = 2;
private final DbAdapter mDb;
private long noteId;
private double recorded = 0;
private int severity;
private String fancyStart;
private String details;
private byte[] image;
private int noteStatus;
private long reportDate;
private boolean emailSent;
private int isSafetyIssue;
private int isAccident;
private int latitude;
private int longitude;
private float accuracy;
private float speed;
private double altitude;
private String imageFileName;
public long getNoteId() {
return noteId;
}
public int getNoteStatus() {
return noteStatus;
}
public String getNotedetails() {
return details;
}
public double getRecorded() {
return recorded;
}
public long getReportDate() {
return reportDate;
}
public int getLatitude() {
return latitude;
}
public int getLongitude() {
return longitude;
}
public int getNoteSeverity() {
return severity;
}
public float getAccuracy() {
return accuracy;
}
public float getSpeed() {
return speed;
}
public double getAltitude() {
return altitude;
}
public String getFancyStart() {
return fancyStart;
}
public byte[] getImage() {
return image;
}
public boolean isEmailSent() {
return emailSent;
}
public static NoteData createNote(Context context, long tripId) {
NoteData noteData = new NoteData(context.getApplicationContext(), 0);
long recorded = System.currentTimeMillis();
noteData.createNoteInDatabase(tripId, recorded);
noteData.initializeData(recorded);
return noteData;
}
public static NoteData fetchNote(Context context, long noteId) {
NoteData noteData = new NoteData(context.getApplicationContext(), noteId);
noteData.populateDetails();
return noteData;
}
private NoteData(Context ctx, long noteid) {
Context context = ctx.getApplicationContext();
this.noteId = noteid;
mDb = new DbAdapter(context);
}
private void initializeData(long recorded) {
this.recorded = recorded;
severity = -1;
fancyStart = details = "";
latitude = 0;
longitude = 0;
accuracy = 0;
altitude = 0;
speed = 0;
reportDate = 0;
isSafetyIssue = -1;
isAccident = -1;
}
public boolean hasImage() {
return !imageFileName.equals("") && (image != null);
}
public String getImageFileName() {
return imageFileName;
}
/**
* load values from database using global noteId
*/
private void populateDetails() {
mDb.openReadOnly();
try {
Cursor noteDetails = mDb.fetchNote(noteId);
try {
recorded = noteDetails.getDouble(noteDetails.getColumnIndex(DbAdapter.K_NOTE_RECORDED ));
fancyStart = noteDetails.getString(noteDetails.getColumnIndex(DbAdapter.K_NOTE_FANCYSTART ));
latitude = noteDetails.getInt (noteDetails.getColumnIndex(DbAdapter.K_NOTE_LAT ));
longitude = noteDetails.getInt (noteDetails.getColumnIndex(DbAdapter.K_NOTE_LGT ));
accuracy = noteDetails.getFloat (noteDetails.getColumnIndex(DbAdapter.K_NOTE_ACC ));
altitude = noteDetails.getDouble(noteDetails.getColumnIndex(DbAdapter.K_NOTE_ALT ));
speed = noteDetails.getFloat (noteDetails.getColumnIndex(DbAdapter.K_NOTE_SPEED ));
severity = noteDetails.getInt (noteDetails.getColumnIndex(DbAdapter.K_NOTE_SEVERITY ));
details = noteDetails.getString(noteDetails.getColumnIndex(DbAdapter.K_NOTE_DETAILS ));
noteStatus = noteDetails.getInt (noteDetails.getColumnIndex(DbAdapter.K_NOTE_STATUS ));
imageFileName = noteDetails.getString(noteDetails.getColumnIndex(DbAdapter.K_NOTE_IMGURL ));
reportDate = noteDetails.getLong (noteDetails.getColumnIndex(DbAdapter.K_NOTE_REPORT_DATE));
emailSent = (noteDetails.getInt (noteDetails.getColumnIndex(DbAdapter.K_NOTE_EMAIL_SENT)) == 1 ? true : false);
if ((null != imageFileName) && (!imageFileName.equals("")))
image = mDb.getNoteImageData(noteId);
else
image = null;
if (DbAnswers.isAccidentSeverity(severity)) {
isAccident = 1; // true
isSafetyIssue = 0; // false
}
else if (DbAnswers.isSafetyUrgency(severity)) {
isAccident = 0; // false
isSafetyIssue = 1; // true
}
}
finally {
noteDetails.close();
}
}
finally {
mDb.close();
}
}
/**
* Create a note in the local database
* @param tripId
* @param recorded
*/
private void createNoteInDatabase(long tripId, long recorded) {
mDb.open();
try {
noteId = mDb.createNote(tripId, recorded);
}
finally {
mDb.close();
}
}
/**
* Add location point
* @param loc
* @return
*/
public boolean setLocation(Location loc) {
boolean rtn;
int lat = (int) (loc.getLatitude() * 1E6);
int lgt = (int) (loc.getLongitude() * 1E6);
float accuracy = loc.getAccuracy();
double altitude = loc.getAltitude();
float speed = loc.getSpeed();
mDb.open();
try {
rtn = mDb.updateNote(noteId, lat, lgt, accuracy, altitude, speed);
}
finally {
mDb.close();
}
return rtn;
}
public boolean updateNoteStatus(int noteStatus) {
boolean rtn;
mDb.open();
try {
rtn = mDb.updateNoteStatus(noteId, noteStatus);
}
finally {
mDb.close();
}
return rtn;
}
public void updateNoteLatLng(float latitude, float longitude) {
this.latitude = (int) (latitude * 1E6);
this.longitude = (int) (longitude * 1E6);
mDb.open();
try {
mDb.updateNote(noteId, this.latitude, this.longitude, 0, 0, 0);
}
finally {
mDb.close();
}
}
/**
* Pushes the following note data to the database
* @param noteFancyStart
* @param noteDetails
* @param image
*/
public void updateNote(String noteDetails, byte[] image) {
mDb.open();
try {
mDb.updateNote(noteId, noteDetails, image);
this.details = noteDetails;
this.imageFileName = (null == image) ? "" : mDb.getNoteImageFileName(noteId);
}
finally {
mDb.close();
}
}
public void updateEmailSent(boolean value) {
mDb.open();
try {
mDb.updateNoteEmailSent(noteId, value);
this.emailSent = value;
}
finally {
mDb.close();
}
}
/**
* Returns true if the report data is from a safety issue
* @return true if safety issue, false otherwise
* @throws IllegalStateException if the value was not set from the database
*/
public boolean isSafetyIssue() throws IllegalStateException {
if (0 == this.isSafetyIssue)
return false;
else if (1 == this.isSafetyIssue)
return true;
throw new IllegalStateException(MODULE_TAG + ": isSafetyIssue value not set");
}
/**
* Returns true if the report data is from an accident
* @return true if accident, false otherwise
* @throws IllegalStateException if the value was not set from the database
*/
public boolean isAccident() throws IllegalStateException {
if (0 == this.isAccident)
return false;
else if (1 == this.isAccident)
return true;
throw new IllegalStateException(MODULE_TAG + ": isAccident value not set");
}
}