package org.codefirex.cfxweather;
import android.app.ActionBar;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.preference.Preference;
import android.preference.ListPreference;
import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.PreferenceScreen;
import android.text.Html;
import android.text.method.LinkMovementMethod;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.Switch;
import android.widget.TextView;
import org.codefirex.cfxweather.R;
import org.codefirex.cfxweather.WeatherService.WeatherBinder;
import org.codefirex.utils.WeatherAdapter;
import org.codefirex.utils.WeatherAdapter.WeatherListener;
public class WeatherActivity extends PreferenceActivity implements
Preference.OnPreferenceChangeListener {
static final String TAG = "CFXWeatherActivity";
static final String TITLE = "Weather";
static final String SETTINGS_CATEGORY = "settings_category";
static final String CALLING_PACKAGE = "calling_package";
static final String NEEDS_BACK_ON_HOME = "needs_back_on_home";
MenuItem mRefreshItem;
PreferenceCategory mSettings;
ListPreference mLocation;
ListPreference mInterval;
ListPreference mTempScale;
ForecastPreference mForecast;
Preference mCredits;
WeatherBinder mBinder;
WeatherAdapter mWeatherAdapter;
WeatherListener mWeatherListener = new WeatherListener() {
@Override
public void onServiceStateChanged(int state) {
switch (state) {
case WeatherAdapter.STATE_ON:
toggleForecast(true);
enablePrefs(true);
invalidateOptionsMenu();
break;
case WeatherAdapter.STATE_OFF:
toggleForecast(false);
enablePrefs(false);
invalidateOptionsMenu();
break;
case WeatherAdapter.STATE_REFRESHING:
if (mRefreshItem != null) {
mRefreshItem.setActionView(R.layout.progress_spinner);
mRefreshItem.expandActionView();
enablePrefs(false);
new Handler().postDelayed(mCheckTimeout, TIMEOUT);
}
break;
case WeatherAdapter.STATE_SCALE:
mForecast.setWeatherInfo(mWeatherAdapter.getLastKnownWeather());
mForecast.invalidate();
break;
case WeatherAdapter.STATE_UPDATED:
if (mRefreshItem != null) {
new Handler().removeCallbacks(mCheckTimeout);
mRefreshItem.collapseActionView();
mRefreshItem.setActionView(null);
}
mForecast.setWeatherInfo(mWeatherAdapter.getLatestWeather());
mForecast.invalidate();
enablePrefs(WeatherPrefs.getEnabled(WeatherActivity.this));
break;
}
}
};
ServiceConnection mWeatherConn = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
mBinder = (WeatherBinder) service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
if (mBinder != null) mBinder = null;
}
};
static final long TIMEOUT = 1000 * 10;
@SuppressWarnings("deprecation")
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.weather_prefs);
Intent intent = getIntent();
boolean setBackOnHome = false;
if (null != intent.getStringExtra(NEEDS_BACK_ON_HOME)
&& "true".equals(intent.getStringExtra(NEEDS_BACK_ON_HOME))) {
setBackOnHome = true;
}
ActionBar actionBar = getActionBar();
actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_HOME
| ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM);
actionBar.setTitle(TITLE);
actionBar.setDisplayHomeAsUpEnabled(true);
mSettings = (PreferenceCategory) findPreference(SETTINGS_CATEGORY);
Boolean isEnabled = WeatherPrefs.getEnabled(this);
mLocation = (ListPreference) findPreference("weather_location_mode");
mInterval = (ListPreference) findPreference("weather_interval");
mTempScale = (ListPreference) findPreference("weather_temp_scale");
mCredits = findPreference("credits_pref");
mCredits.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() {
@Override
public boolean onPreferenceClick(Preference preference) {
showCreditDialog();
return true;
}
});
mForecast = (ForecastPreference) findPreference("weather_forecast");
mForecast.setSelectable(false);
mLocation.setValue(String.valueOf(WeatherPrefs.getLocationMode(this)));
mInterval.setValue(String.valueOf(WeatherPrefs.getInterval(this)));
mTempScale.setValue(String.valueOf(WeatherPrefs.getDegreeType(this)));
updateSummary(
mLocation,
getResources().getStringArray(R.array.weather_location_entries),
getResources().getStringArray(R.array.weather_location_values));
updateSummary(
mInterval,
getResources().getStringArray(R.array.weather_interval_entries),
getResources().getStringArray(R.array.weather_interval_values));
updateSummary(
mTempScale,
getResources().getStringArray(
R.array.weather_temp_scale_entries), getResources()
.getStringArray(R.array.weather_temp_scale_values));
mLocation.setOnPreferenceChangeListener(this);
mInterval.setOnPreferenceChangeListener(this);
mTempScale.setOnPreferenceChangeListener(this);
mWeatherAdapter = new WeatherAdapter(this, mWeatherListener);
mForecast.setWeatherInfo(mWeatherAdapter.getLatestWeather());
// initial state, we don't want a bunch of "unknown" showing
toggleForecast(isEnabled && !mWeatherAdapter.getLastKnownWeather().getCurrentText().equals("unknown"));
enablePrefs(isEnabled);
}
private void sendMessageToService(int msg) {
if (mBinder != null) {
Message m = mBinder.getService().getMessage();
m.what = msg;
mBinder.getService().sendMessage(m);
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
Boolean isEnabled = WeatherPrefs.getEnabled(this);
getMenuInflater().inflate(R.menu.weather_menu, menu);
mRefreshItem = menu.findItem(R.id.action_refresh);
mRefreshItem.setEnabled(isEnabled);
mRefreshItem.setVisible(isEnabled);
MenuItem mSwitchItem = menu.findItem(R.id.action_switch);
Switch s = (Switch) mSwitchItem.getActionView().findViewById(
R.id.switchForActionBar);
s.setChecked(isEnabled);
s.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if (mRefreshItem != null) {
mRefreshItem.setEnabled(isChecked);
mRefreshItem.setVisible(isChecked);
}
WeatherPrefs.setEnabled(WeatherActivity.this, isChecked);
sendMessageToService(isChecked ? WeatherService.RESUME_SERVICE : WeatherService.PAUSE_SERVICE);
}
});
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_refresh:
mRefreshItem = item;
sendMessageToService(WeatherService.REFRESH_NOW);
break;
case android.R.id.home:
finish();
break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onResume() {
super.onResume();
mForecast.setWeatherInfo(mWeatherAdapter.getLastKnownWeather());
mForecast.invalidate();
}
@Override
public void onStart() {
super.onStart();
bindService(new Intent(this, WeatherService.class), mWeatherConn, Context.BIND_AUTO_CREATE);
mWeatherAdapter.startUpdates();
}
@Override
public void onStop() {
super.onStop();
unbindService(mWeatherConn);
mWeatherAdapter.stopUpdates();
}
@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
if (preference.equals(mLocation)) {
String val = ((String) newValue).toString();
WeatherPrefs.setLocationMode(this, val);
sendMessageToService(WeatherService.LOCATION_MODE_CHANGED);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
updateSummary(
mLocation,
getResources().getStringArray(
R.array.weather_location_entries),
getResources().getStringArray(
R.array.weather_location_values));
}
}, 100);
return true;
} else if (preference.equals(mInterval)) {
String val = ((String) newValue).toString();
WeatherPrefs.setInterval(this, val);
sendMessageToService(WeatherService.INTERVAL_CHANGED);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
updateSummary(
mInterval,
getResources().getStringArray(
R.array.weather_interval_entries),
getResources().getStringArray(
R.array.weather_interval_values));
}
}, 100);
return true;
} else if (preference.equals(mTempScale)) {
int val = Integer.parseInt(((String) newValue).toString());
WeatherPrefs.setDegreeType(this, val);
sendMessageToService(WeatherService.SCALE_CHANGED);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
updateSummary(
mTempScale,
getResources().getStringArray(
R.array.weather_temp_scale_entries),
getResources().getStringArray(
R.array.weather_temp_scale_values));
}
}, 100);
return true;
}
return false;
}
private void updateSummary(ListPreference pref, String[] entries,
String[] values) {
String currentVal = pref.getValue();
String newEntry = "";
for (int i = 0; i < values.length; i++) {
if (values[i].equals(currentVal)) {
newEntry = entries[i];
break;
}
}
pref.setSummary(newEntry);
}
private void toggleForecast(boolean enabled) {
PreferenceScreen screen = getPreferenceScreen();
if (enabled) {
screen.addPreference(mForecast);
} else {
screen.removePreference(mForecast);
}
}
private void enablePrefs(boolean enabled) {
mLocation.setEnabled(enabled);
mInterval.setEnabled(enabled);
mTempScale.setEnabled(enabled);
}
private Runnable mCheckTimeout = new Runnable() {
@Override
public void run() {
mRefreshItem.collapseActionView();
mRefreshItem.setActionView(null);
mForecast.invalidate();
enablePrefs(WeatherPrefs.getEnabled(WeatherActivity.this));
}
};
private void showCreditDialog() {
AlertDialog.Builder b = new AlertDialog.Builder(this);
b.setTitle(R.string.credits);
final AlertDialog dialog = b.create();
View v = getLayoutInflater().inflate(R.layout.credits_view, null);
// this could all be xml but got wonk in compiling the string
TextView linkView = (TextView) v.findViewById(R.id.weather_icon_url);
String str_links = "Icon set on DeviantART";
linkView.setLinksClickable(true);
linkView.setMovementMethod(LinkMovementMethod.getInstance());
linkView.setText(Html.fromHtml(str_links));
TextView xmlCredit = (TextView) v.findViewById(R.id.credit_xml_github);
String github_link = "YWeatherGetter4a on Github";
xmlCredit.setLinksClickable(true);
xmlCredit.setMovementMethod(LinkMovementMethod.getInstance());
xmlCredit.setText(Html.fromHtml(github_link));
// have to maunally create buttons when AlertDialog has a custom view
Button ok = (Button) v.findViewById(R.id.button_ok);
ok.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.setView(v);
dialog.show();
}
}