//*****************************************************************************
// This file is part of CheckIn4Me. Copyright � 2010 David Ivins
//
// CheckIn4Me 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.
//
// CheckIn4Me 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 CheckIn4Me. If not, see <http://www.gnu.org/licenses/>.
//*****************************************************************************
package com.davidivins.checkin4me.activities;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.*;
import android.view.View.OnClickListener;
import android.widget.*;
import com.davidivins.checkin4me.adapters.ServiceCheckListAdapter;
import com.davidivins.checkin4me.core.*;
import com.davidivins.checkin4me.core.Locale;
import com.davidivins.checkin4me.interfaces.ServiceInterface;
import com.davidivins.checkin4me.listeners.implementations.CheckInMessageOnClickListener;
import com.davidivins.checkin4me.listeners.interfaces.CheckInRequesterListener;
import com.davidivins.checkin4me.listeners.interfaces.CleanableProgressDialogListener;
import com.davidivins.checkin4me.threads.CheckInRequester;
import com.davidivins.checkin4me.util.CleanableProgressDialog;
import com.davidivins.checkin4me.util.LocationOverlay;
import com.google.android.maps.*;
import java.io.InputStream;
import java.util.*;
/**
* LocationDetails
*
* displays location details to the user, prompts for check-in services and message.
*
* @author david ivins
*/
public class LocationDetails
extends MapActivity
implements OnClickListener, DialogInterface.OnClickListener, CleanableProgressDialogListener, CheckInRequesterListener
{
private static final String TAG = LocationDetails.class.getName();
private static Properties config = null;
private static ProgressDialog checking_in_dialog = null;
private CheckInRequester checkin_requester = null;
private Locale current_location = new Locale();
/**
* onCreate
*
* called at the creation of the activity
*
* @param saved_instance_state
*/
@Override
public void onCreate(Bundle saved_instance_state)
{
super.onCreate(saved_instance_state);
GeneratedResources.generate(this);
setContentView(GeneratedResources.getLayout("location_details"));
// display ad if this is not the pro version
Ad ad = new Ad(this);
ad.refreshAd();
// get map config file if necessary
if (config == null)
{
config = new Properties();
try
{
InputStream config_file = getResources().openRawResource(GeneratedResources.getRaw("google_maps"));
config.load(config_file);
}
catch (Exception e)
{
Log.e(TAG, "Failed to open config file");
}
}
//
// list stuff
//
ListView list_view = (ListView)findViewById(GeneratedResources.getId("location_service_list"));
list_view.setTextFilterEnabled(true);
list_view.setBackgroundColor(Color.WHITE);
list_view.setCacheColorHint(Color.WHITE);
//
// button stuff
//
Button button = (Button)findViewById(GeneratedResources.getId("check_in_button"));
button.setOnClickListener(this);
//
// display any location details
//
displayLocationDetails();
}
/**
* onStop
*
* called when the activity stops
*/
@Override
public void onStop()
{
super.onStop();
cleanUp();
}
/**
* onDialogInterruptedByBackButton
*
* called when a cleanable dialog box displayed by this activity is cancelled by the back button
*/
public void onDialogInterruptedByBackButton()
{
cleanUp();
}
/**
* onDialogInterruptedBySearchButton
*
* called when a cleanable dialog box displayed by this activity is cancelled by the search button
*/
public void onDialogInterruptedBySearchButton()
{
cleanUp();
}
/**
* cleanUp
*
* cancels any running checkins and removes and visible dialog or progress boxes
*/
private void cleanUp()
{
// cancel check-in requester if running
if (null != checkin_requester)
checkin_requester.cancel(true);
// cancel any dialogs showing
if (checking_in_dialog != null && checking_in_dialog.isShowing())
checking_in_dialog.cancel();
}
/**
* onClick
*
* processes a check-in button click.
*
* @param view
*/
public void onClick(View view)
{
// inflate the alert view
LayoutInflater factory = LayoutInflater.from(this);
final View alert_view = factory.inflate(GeneratedResources.getLayout("checkin_message"), null);
// build alert box, input box, and onclick listener
AlertDialog.Builder alert = new AlertDialog.Builder(this);
EditText input = (EditText)alert_view.findViewById(GeneratedResources.getId("checkin_message_text_entry"));
CheckInMessageOnClickListener listener = new CheckInMessageOnClickListener(this, input);
// set alert options
alert.setView(alert_view);
alert.setMessage("Check-In Message:");
alert.setPositiveButton("Check-In", listener);
alert.setNegativeButton("Cancel", listener);
alert.show();
}
/**
* checkIn
*
* performs a check-in given a message and the latest location data
*
* @param message
*/
public void checkIn(String message)
{
// cancel acquiring location dialog
if (null != checking_in_dialog && checking_in_dialog.isShowing())
checking_in_dialog.cancel();
// get list and adapter
ListView list_view = (ListView)findViewById(GeneratedResources.getId("location_service_list"));
ServiceCheckListAdapter adapter = (ServiceCheckListAdapter)list_view.getAdapter();
// retrieve services that were checked
Map<Integer, Boolean> services_checked = adapter.getServicesChecked();
List<Integer> service_ids = new ArrayList<Integer>();
// pull out services checked
Set<Integer> keys = services_checked.keySet();
for(int key : keys)
{
Log.i(TAG, "service connected id = " + key + " and checked state = " + services_checked.get(key));
if (services_checked.get(key))
service_ids.add(key);
}
// if there are no services ids checked, do not check-in, alert the user
if (service_ids.isEmpty())
{
Toast.makeText(this, "No services checked", Toast.LENGTH_SHORT).show();
}
else
{
// display progress dialog to user
checking_in_dialog = new CleanableProgressDialog(this, this, "", "Checking in...", true);
checking_in_dialog.show();
// create and start check-in thread
SharedPreferences persistent_storage = PreferenceManager.getDefaultSharedPreferences(this);
// start check-in thread
checkin_requester = new CheckInRequester(this, this, service_ids, current_location, message, persistent_storage);
checkin_requester.execute();
}
}
/**
* checkInComplete
*
* called at the completion of a check-in. cleans up and displays status of check-in.
*
* @param checkin_statuses
*/
public void checkInComplete(Map<Integer, Boolean> checkin_statuses)
{
Log.i(TAG, "received check-in completed.");
// clean up
cleanUp();
// display check in dialog
displayCheckInStatus(checkin_statuses);
}
/**
* displayLocationDetails
*
* displays the latest location details to the user
*/
public void displayLocationDetails()
{
// load current location from preferences
SharedPreferences persistent_storage = PreferenceManager.getDefaultSharedPreferences(this);
current_location.load(persistent_storage);
// load current longitude and latitude from preferences
Double current_longitude = new Double(persistent_storage.getString("current_longitude", "0"));
Double current_latitude = new Double(persistent_storage.getString("current_latitude", "0"));
//
// location name and address
//
TextView location_name = (TextView)findViewById(GeneratedResources.getId("location_name"));
location_name.setText(current_location.getName());
location_name.setTextSize(20);
TextView location_description = (TextView)findViewById(GeneratedResources.getId("location_description"));
location_description.setText(current_location.getAddress());
//
// map stuff
//
MapView location_map = new MapView(
this, config.getProperty(MetaData.getInstance(this).getString("VERSION") + "_api_key"));
location_map.setClickable(true);
List<Overlay> map_overlays = location_map.getOverlays();
Drawable drawable = this.getResources().getDrawable(android.R.drawable.star_on);
LocationOverlay location_overlay1 = new LocationOverlay(drawable, this);
LocationOverlay location_overlay2 = new LocationOverlay(drawable, this);
GeoPoint location_point = current_location.getCoordinatesAsGeoPoint();
GeoPoint user_point = new GeoPoint((int)(current_latitude.doubleValue() * 1E6), (int)(current_longitude.doubleValue() * 1E6));
OverlayItem overlayitem1 = new OverlayItem(location_point, current_location.getName(), current_location.getAddress());
OverlayItem overlayitem2 = new OverlayItem(user_point, "You Are Here.", "Lat: " + current_latitude + "\nLong: " + current_longitude);
location_overlay1.addOverlay(overlayitem1);
location_overlay2.addOverlay(overlayitem2);
map_overlays.add(location_overlay1);
map_overlays.add(location_overlay2);
MapController map_controller = location_map.getController();
map_controller.setCenter(location_point);
map_controller.setZoom(15);
LinearLayout map_layout = (LinearLayout)findViewById(GeneratedResources.getId("location_map"));
map_layout.addView(location_map);
//
// service list stuff
//
Map<Integer, String> service_id_location_id_xref = current_location.getServiceIdToLocationIdMap();
List<ServiceInterface> services = new ArrayList<ServiceInterface>();
Set<Integer> service_ids = service_id_location_id_xref.keySet();
for(int service_id : service_ids)
{
services.add(Services.getInstance(this).getServiceById(service_id));
}
ServiceCheckListAdapter adapter = new ServiceCheckListAdapter(this, GeneratedResources.getLayout("location_details_row"), services);
ListView list_view = (ListView)findViewById(GeneratedResources.getId("location_service_list"));
list_view.setAdapter(adapter);
}
/**
* displayCheckInStatus
*
* displayes the check-in status to the user.
*
* @param checkin_statuses
*/
public void displayCheckInStatus(Map<Integer, Boolean> checkin_statuses)
{
boolean some_succeeded = false;
boolean some_failed = false;
// retrieve layout inflater
LayoutInflater inflater = (LayoutInflater) this.getSystemService(LAYOUT_INFLATER_SERVICE);
View layout = inflater.inflate(GeneratedResources.getLayout("checkin_dialog"),
(ViewGroup)findViewById(GeneratedResources.getId("checkin_root")));
LinearLayout checkin_root_dialog = (LinearLayout)layout.findViewById(GeneratedResources.getId("checkin_root"));
// add service icons to layout
LinearLayout successful_images = new LinearLayout(this);
LinearLayout failure_images = new LinearLayout(this);
// center icons
successful_images.setGravity(0x11);
failure_images.setGravity(0x11);
// get icons for successful and failed check-ins
Set<Integer> keys = checkin_statuses.keySet();
for (int key : keys)
{
ImageView image = new ImageView(this);
image.setImageResource(Services.getInstance(this).getServiceById(key).getIconDrawable());
image.setPadding(0, 5, 5, 0);
// if the check-in for this particular service was successful
if (checkin_statuses.get(key))
{
successful_images.addView(image);
some_succeeded= true;
}
else
{
failure_images.addView(image);
some_failed = true;
}
}
// successful checkins
if (some_succeeded)
{
TextView successful_text = new TextView(this);
successful_text.setText("We have you at " + current_location.getName() + " on:");
successful_text.setGravity(0x11); // center text
checkin_root_dialog.addView(successful_text);
checkin_root_dialog.addView(successful_images);
}
// failed check-ins
if (some_failed)
{
TextView failure_text = new TextView(this);
failure_text.setText("Check-in failed at " + current_location.getName() + " on:");
failure_text.setGravity(0x11); // center text
if (some_succeeded) // spread them out
failure_text.setPadding(0, 10, 0, 0);
checkin_root_dialog.addView(failure_text);
checkin_root_dialog.addView(failure_images);
}
// create alert dialog builder
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setView(layout);
builder.setPositiveButton("OK", this);
// create alert dialog
AlertDialog alertDialog = builder.create();
// set title/icon based on success or failure
if (some_succeeded && some_failed) // some check-ins failed and some check-ins succeeded
{
alertDialog.setIcon(GeneratedResources.getDrawable("warning"));
alertDialog.setTitle("Check-in Results Mixed!");
}
else if (some_failed) // all check-ins failed
{
alertDialog.setIcon(GeneratedResources.getDrawable("x"));
alertDialog.setTitle("Check-in Failed!");
}
else // all check-ins succeeded
{
alertDialog.setIcon(GeneratedResources.getDrawable("check"));
alertDialog.setTitle("Check-in Successful!");
}
// show check-in dialog box
alertDialog.show();
}
/**
* onClick
*
* returns the user to the location list when the ok button is hit in the check-in status dialog
*
* @param dialog
* @param which
*/
public void onClick(DialogInterface dialog, int which)
{
// return to nearby places
finish();
}
/**
* isRouteDisplayed
*
* override for isRouteDisplayed.
*
* @return boolean
*/
@Override
protected boolean isRouteDisplayed()
{
return false;
}
/**
* onCreateOptionsMenu
*
* displays the options menu when the options button is selected.
*
* @param menu
*/
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
MenuInflater inflater = getMenuInflater();
inflater.inflate(GeneratedResources.getMenu("feedback_only"), menu);
return true;
}
/**
* onOptionsItemSelected
*
* performs option selected by the user.
*
* @param item
*/
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
boolean result = false;
int id = item.getItemId();
// load feedback option
if (GeneratedResources.getId("feedback") == id)
{
startActivity(new Intent(this, Feedback.class));
result = true;
}
return result;
}
}