/*
* Copyright 2012 GitHub 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.github.mobile.gauges.ui.airtraffic;
import static android.os.Build.VERSION.SDK_INT;
import static android.view.View.STATUS_BAR_HIDDEN;
import static com.github.mobile.gauges.IntentConstants.GAUGES;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.support.v4.app.LoaderManager.LoaderCallbacks;
import android.support.v4.content.Loader;
import android.widget.ImageView;
import android.widget.TextView;
import com.emorym.android_pusher.Pusher;
import com.github.kevinsawicki.wishlist.Toaster;
import com.github.mobile.gauges.GaugesServiceProvider;
import com.github.mobile.gauges.R.id;
import com.github.mobile.gauges.R.layout;
import com.github.mobile.gauges.R.string;
import com.github.mobile.gauges.core.Gauge;
import com.github.mobile.gauges.ui.GaugeListLoader;
import com.github.mobile.gauges.ui.ThrowableLoader;
import com.github.rtyley.android.sherlock.roboguice.activity.RoboSherlockFragmentActivity;
import com.google.inject.Inject;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import roboguice.inject.InjectView;
/**
* Activity to display list of gauge summaries
*/
public class AirTrafficActivity extends RoboSherlockFragmentActivity implements
LoaderCallbacks<List<Gauge>> {
private static final String CHANNEL_PREFIX = "private-";
@Inject
private GaugesServiceProvider serviceProvider;
@InjectView(id.air_traffic)
private AirTrafficView airTrafficView;
@InjectView(id.iv_pin)
private ImageView pinImage;
@InjectView(id.tv_gauge_name)
private TextView gaugeText;
@InjectView(id.tv_gauge_location)
private TextView gaugeLocation;
private Map<String, String> gaugeTitles = new HashMap<String, String>();
private final Executor backgroundThread = Executors.newFixedThreadPool(1);
private Pusher pusher;
private AirTrafficResourceProvider resourceProvider;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(layout.airtraffic_activity);
pusher = new GaugesPusher(serviceProvider);
resourceProvider = new AirTrafficResourceProvider(getResources());
airTrafficView.setResourceProvider(resourceProvider).setLabelHeight(
gaugeText.getTextSize() * 3 / 2);
getSupportActionBar().hide();
updateSystemUi();
@SuppressWarnings("unchecked")
Collection<Gauge> intentGauges = (Collection<Gauge>) getIntent()
.getSerializableExtra(GAUGES);
if (intentGauges != null && !intentGauges.isEmpty())
loadGauges(intentGauges);
else
getSupportLoaderManager().initLoader(0, null, this);
}
@SuppressWarnings("deprecation")
private void updateSystemUi() {
if (SDK_INT >= 14)
// On ICS this equivalent to SYSTEM_UI_FLAG_LOW_PROFILE - the
// dimmed-menu-buttons mode
getWindow().getDecorView().setSystemUiVisibility(STATUS_BAR_HIDDEN);
}
@Override
protected void onPause() {
super.onPause();
unsubscribeFromGaugeChannels(gaugeTitles.keySet());
airTrafficView.pause();
}
@Override
protected void onResume() {
super.onResume();
airTrafficView.resume();
subscribeToGaugeChannels(gaugeTitles.keySet());
}
@Override
public Loader<List<Gauge>> onCreateLoader(int id, Bundle args) {
return new GaugeListLoader(this, Collections.<Gauge> emptyList(),
serviceProvider);
}
@Override
public void onLoadFinished(Loader<List<Gauge>> listLoader,
List<Gauge> gauges) {
if (listLoader instanceof ThrowableLoader) {
Exception exception = ((ThrowableLoader<?>) listLoader)
.clearException();
if (exception != null)
Toaster.showLong(this, string.error_loading_gauges);
}
unsubscribeFromGaugeChannels(gaugeTitles.keySet());
loadGauges(gauges);
subscribeToGaugeChannels(gaugeTitles.keySet());
}
private void loadGauges(Collection<Gauge> gauges) {
Map<String, String> newGauges = new HashMap<String, String>();
for (Gauge gauge : gauges)
newGauges.put(gauge.getId(), gauge.getTitle());
gaugeTitles = newGauges;
resourceProvider.setGauges(gauges);
}
/**
* Get geographic location label for hit
*
* @param hit
* @return label
*/
protected String getLocation(final Hit hit) {
String country = hit.country != null ? hit.country : "";
if (country.length() == 0)
return "";
String city = hit.city != null ? hit.city : "";
String region = hit.region != null ? hit.region : "";
String location;
if (region.length() > 0
&& ("United States".equals(country) || "Canada".equals(country)))
location = region;
else
location = country;
if (city.length() > 0)
return city + ", " + location;
else
return location;
}
/**
* Get page title of hit
*
* @param hit
* @return title
*/
protected String getTitle(final Hit hit) {
if (hit.title != null && hit.title.length() > 0) {
int separator = hit.title.indexOf(" // ");
if (separator == -1)
separator = hit.title.indexOf(" - ");
if (separator > 0)
return hit.title.substring(0, separator);
else
return hit.title;
} else
return "";
}
@Override
public void onLoaderReset(Loader<List<Gauge>> listLoader) {
}
private void subscribeToGaugeChannels(final Collection<String> subscribeIds) {
if (subscribeIds.isEmpty())
return;
backgroundThread.execute(new Runnable() {
public void run() {
final AirTrafficPusherCallback callback = new AirTrafficPusherCallback() {
@Override
protected void onHit(final Hit hit) {
airTrafficView.addHit(hit);
gaugeText.post(new Runnable() {
@SuppressWarnings("deprecation")
public void run() {
String gaugeTitle = gaugeTitles.get(hit.siteId);
if (gaugeTitle == null)
return;
Bitmap bitmap = resourceProvider
.getPin(hit.siteId);
if (bitmap != null)
pinImage.setBackgroundDrawable(new BitmapDrawable(
getResources(), bitmap));
else
pinImage.setBackgroundDrawable(null);
gaugeLocation.setText(getLocation(hit));
String title = getTitle(hit);
if (title.length() > 0)
gaugeText
.setText(gaugeTitle + ": " + title);
else
gaugeText.setText(gaugeTitle);
}
});
}
};
for (String gaugeId : subscribeIds)
pusher.subscribe(CHANNEL_PREFIX + gaugeId).bind("hit",
callback);
}
});
}
private void unsubscribeFromGaugeChannels(
final Collection<String> unsubscribeIds) {
if (unsubscribeIds.isEmpty())
return;
backgroundThread.execute(new Runnable() {
public void run() {
for (String gaugeId : unsubscribeIds)
pusher.unsubscribe(CHANNEL_PREFIX + gaugeId);
}
});
}
}