package akechi.projectl;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.content.BroadcastReceiver;
import android.content.ContentValues;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.app.DialogFragment;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentStatePagerAdapter;
import android.support.v4.content.Loader;
import android.support.v4.content.LocalBroadcastManager;
import android.support.v4.view.ViewPager;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SubMenu;
import android.widget.ImageView;
import android.widget.Toast;
import com.google.api.client.repackaged.com.google.common.base.Strings;
import com.google.common.base.Optional;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import java.util.List;
import java.util.Map;
import akechi.projectl.async.GyazoUploader;
import jp.michikusa.chitose.lingr.Events;
public class HomeActivity
extends AppCompatActivity
implements CometService.OnCometEventListener
{
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_home);
final AccountManager manager= AccountManager.get(this);
Account[] accounts= manager.getAccountsByType("com.lingr");
if(accounts.length <= 0)
{
manager.addAccount("com.lingr", "", null, null, this, null, null);
this.finish();
return;
}
final AppContext appContext= (AppContext)this.getApplicationContext();
// restore state
{
final SharedPreferences prefs= this.getSharedPreferences("prefs", Context.MODE_PRIVATE);
final String name= prefs.getString("account.name", "");
final String type= prefs.getString("account.type", "");
if(!Strings.isNullOrEmpty(name) && !Strings.isNullOrEmpty(type))
{
final Account account= new Account(name, type);
appContext.setAccount(account);
}
}
if(savedInstanceState != null)
{
final Account account = savedInstanceState.getParcelable("account");
if(account != null)
{
appContext.setAccount(account);
}
}
final Account account= appContext.getAccount();
final ViewPager pager= (ViewPager)this.findViewById(R.id.pager);
pager.setAdapter(new SwipeSwitcher(this.getSupportFragmentManager()));
if(account != null && !Strings.isNullOrEmpty(appContext.getRoomId(account)))
{
pager.setCurrentItem(SwipeSwitcher.POS_ROOM);
}
else
{
pager.setCurrentItem(SwipeSwitcher.POS_ROOM_LIST);
}
// Setup ActionBar
appContext.getActionBarMode().applyActionBar(appContext, this.getSupportActionBar());
final LocalBroadcastManager lbMan= LocalBroadcastManager.getInstance(this.getApplicationContext());
{
final IntentFilter ifilter= new IntentFilter(CometService.class.getCanonicalName());
final BroadcastReceiver receiver= new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent)
{
final Events events= (Events)intent.getSerializableExtra("events");
HomeActivity.this.onCometEvent(events);
}
};
lbMan.registerReceiver(receiver, ifilter);
this.receivers.add(receiver);
}
{
final IntentFilter ifilter= new IntentFilter(Event.RoomChange.ACTION);
final BroadcastReceiver receiver= new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent)
{
final String roomId= intent.getStringExtra(Event.RoomChange.KEY_ROOM_ID);
HomeActivity.this.onRoomSelected(roomId);
}
};
lbMan.registerReceiver(receiver, ifilter);
this.receivers.add(receiver);
}
{
final IntentFilter ifilter= new IntentFilter(Event.PreferenceChange.ACTION);
final BroadcastReceiver receiver= new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent)
{
final AppContext appContext= (AppContext)HomeActivity.this.getApplicationContext();
appContext.getActionBarMode().applyActionBar(appContext, HomeActivity.this.getSupportActionBar());
}
};
lbMan.registerReceiver(receiver, ifilter);
this.receivers.add(receiver);
}
final Intent service= new Intent(this, CometService.class);
this.startService(service);
// handle explicit intent
if(Event.OnNotificationTapped.ACTION.equals(this.getIntent().getAction()))
{
this.onNotificationTapped(this.getIntent());
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
switch(keyCode)
{
// swipe to room list when back button press in the room
case KeyEvent.KEYCODE_BACK:{
final ViewPager pager= (ViewPager)this.findViewById(R.id.pager);
if(pager.getCurrentItem() == SwipeSwitcher.POS_ROOM)
{
pager.setCurrentItem(SwipeSwitcher.POS_ROOM_LIST, true);
return true;
}
// fallthrough
}
default:
return super.onKeyDown(keyCode, event);
}
}
@Override
protected void onSaveInstanceState(Bundle outState)
{
super.onSaveInstanceState(outState);
Log.i("HomeActivity", "onSaveInstanceState()");
final AppContext appContext= (AppContext)this.getApplicationContext();
outState.putParcelable("account", appContext.getAccount());
}
@Override
protected void onPause()
{
super.onPause();
final AppContext appContext= (AppContext)this.getApplicationContext();
final SharedPreferences prefs= this.getSharedPreferences("prefs", Context.MODE_PRIVATE);
final SharedPreferences.Editor editor= prefs.edit();
final Account account= appContext.getAccount();
if(account != null)
{
editor.putString("account.name", account.name);
editor.putString("account.type", account.type);
}
editor.commit();
// this.unbindService(this.serviceConnection);
// this.serviceConnection= null;
}
@Override
protected void onDestroy()
{
super.onDestroy();
final AppContext appContext= (AppContext)this.getApplicationContext();
if(!appContext.isBackgroundServiceEnabled())
{
Log.i("HomeActivity", "stopService");
final Intent intent= new Intent(this, CometService.class);
this.stopService(intent);
}
final LocalBroadcastManager lbMan= LocalBroadcastManager.getInstance(this.getApplicationContext());
for(final BroadcastReceiver receiver : this.receivers)
{
lbMan.unregisterReceiver(receiver);
}
this.receivers.clear();
}
@Override
public boolean onCreateOptionsMenu(Menu menu)
{
menu.add(Menu.NONE, MENU_ITEM_RELOAD, Menu.NONE, "Reload");
menu.add(Menu.NONE, MENU_ITEM_PHOTO, Menu.NONE, "Post a photo(s)");
menu.add(Menu.NONE, MENU_ITEM_PREFERENCE, Menu.NONE, "Settings");
menu.add(Menu.NONE, MENU_ITEM_APP_INFO, Menu.NONE, "App Info");
// Switch account
final AppContext appContext= (AppContext)this.getApplicationContext();
final Iterable<Account> accounts= appContext.getAccounts();
if(Iterables.size(accounts) > 1)
{
final SubMenu subMenu= menu.addSubMenu(Menu.NONE, Menu.NONE, Menu.NONE, "Switch account");
for(final Account account : accounts)
{
subMenu.add(Menu.NONE, MENU_ITEM_ACCOUNT, Menu.NONE, account.name);
}
}
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item)
{
switch(item.getItemId())
{
case MENU_ITEM_RELOAD:{
final Intent intent= new Intent(Event.Reload.ACTION);
final LocalBroadcastManager lbMan= LocalBroadcastManager.getInstance(this.getApplicationContext());
lbMan.sendBroadcast(intent);
return true;
}
case MENU_ITEM_PREFERENCE:{
final Intent intent= new Intent(this, SettingsActivity.class);
this.startActivity(intent);
return true;
}
case MENU_ITEM_APP_INFO:{
final DialogFragment dialog= new AppInfoFragment();
dialog.show(this.getSupportFragmentManager(), "dialog");
return true;
}
case MENU_ITEM_PHOTO:{
final HomeActivity that= this;
new AlertDialog.Builder(this)
.setItems(new CharSequence[]{"Take a photo", "Pick a photo"}, new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which)
{
switch(which)
{
// Take a photo
case 0:{
final Intent intent= new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// same rule for standard camera app
{
final String filename= System.currentTimeMillis() + ".jpg";
final ContentValues values= new ContentValues();
values.put(MediaStore.Images.Media.TITLE, filename);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
that.temporaryCameraStoreUri= that.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
intent.putExtra(MediaStore.EXTRA_OUTPUT, that.temporaryCameraStoreUri);
HomeActivity.this.startActivityForResult(intent, REQUEST_CODE_TAKE_PHOTO);
break;
}
// Pick a photo
case 1:{
final Intent intent= new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
HomeActivity.this.startActivityForResult(intent, REQUEST_CODE_CHOOSE_PHOTO);
break;
}
}
}
})
.show()
;
return true;
}
case MENU_ITEM_ACCOUNT:{
final AppContext appContext= (AppContext)this.getApplicationContext();
final Optional<Account> account= Iterables.tryFind(appContext.getAccounts(), new AccountNameEquals(item.getTitle().toString()));
if(!account.isPresent())
{
Toast.makeText(this, "Did you remove an account? Try again", Toast.LENGTH_SHORT).show();
return true;
}
appContext.setAccount(account.get());
// choose current page
{
final ViewPager pager= (ViewPager)this.findViewById(R.id.pager);
if(Strings.isNullOrEmpty(appContext.getRoomId(account.get())))
{
pager.setCurrentItem(SwipeSwitcher.POS_ROOM_LIST);
}
else
{
pager.setCurrentItem(SwipeSwitcher.POS_ROOM);
}
}
// apply ActionBar
{
appContext.getActionBarMode().applyActionBar(appContext, this.getSupportActionBar());
}
// trigger event
{
final Intent intent= new Intent(Event.AccountChange.ACTION);
intent.putExtra(Event.AccountChange.KEY_ACCOUNT, account.get());
final LocalBroadcastManager lbMan= LocalBroadcastManager.getInstance(this.getApplicationContext());
lbMan.sendBroadcast(intent);
}
return true;
}
}
return false;
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(RESULT_OK != resultCode)
{
return;
}
switch(requestCode)
{
case REQUEST_CODE_TAKE_PHOTO:
// For xperia 2.1
if(data.getData() == null)
{
data.setData(this.temporaryCameraStoreUri);
}
// fallthrough
case REQUEST_CODE_CHOOSE_PHOTO:{
Log.i("gyazo", String.format("data=%s, extras=%s", data.getData(), data.getExtras()));
final ImageView view= new ImageView(this);
view.setImageURI(data.getData());
view.setAdjustViewBounds(true);
final Uri dataUri= data.getData();
new AlertDialog.Builder(this)
.setView(view)
.setPositiveButton("OK", new DialogInterface.OnClickListener(){
@Override
public void onClick(DialogInterface dialog, int which)
{
final GyazoUploader loader= new GyazoUploader(HomeActivity.this, dataUri);
loader.registerListener(0, new Loader.OnLoadCompleteListener<Uri>(){
@Override
public void onLoadComplete(Loader<Uri> loader, Uri data)
{
HomeActivity.this.onGyazoUploaded(data);
}
});
loader.forceLoad();
}
})
.setNegativeButton("Cancel", null)
.show()
;
break;
}
case REQUEST_CODE_GYAZO_UPLOAD:{
break;
}
}
}
private void onGyazoUploaded(Uri uri)
{
if(uri == null)
{
Toast.makeText(this, "Oops, failed to upload image to gyazo", Toast.LENGTH_SHORT).show();
return;
}
final LocalBroadcastManager lbMan= LocalBroadcastManager.getInstance(this.getApplicationContext());
final Intent intent= new Intent(Event.PostMessage.ACTION);
intent.putExtra(Event.PostMessage.KEY_TEXT, uri.toString());
lbMan.sendBroadcast(intent);
}
private void onRoomSelected(CharSequence roomId)
{
final AppContext appContext= (AppContext)this.getApplicationContext();
appContext.setRoomId(appContext.getAccount(), roomId);
final ViewPager pager= (ViewPager)this.findViewById(R.id.pager);
pager.setCurrentItem(SwipeSwitcher.POS_ROOM, true);
appContext.getActionBarMode().applyActionBar(appContext, this.getSupportActionBar());
}
@Override
public void onCometEvent(Events events)
{
Log.i("HomeActivity", "events = " + events);
final ViewPager pager= (ViewPager)this.findViewById(R.id.pager);
final SwipeSwitcher adapter= (SwipeSwitcher)pager.getAdapter();
final Fragment[] fragments= new Fragment[]{
adapter.getFragment(SwipeSwitcher.POS_ROOM_LIST),
adapter.getFragment(SwipeSwitcher.POS_ROOM),
};
for(final Fragment fragment : fragments)
{
if(fragment instanceof CometService.OnCometEventListener)
{
((CometService.OnCometEventListener)fragment).onCometEvent(events);
}
}
}
private void onNotificationTapped(Intent intent)
{
final String accountName= intent.getStringExtra(Event.OnNotificationTapped.KEY_ACCOUNT_NAME);
final String roomId= intent.getStringExtra(Event.OnNotificationTapped.KEY_ROOM_ID);
final String messageId= intent.getStringExtra(Event.OnNotificationTapped.KEY_MESSAGE_ID);
Log.i("notification tapped", "account name is " + accountName);
Log.i("notification tapped", "room id is " + roomId);
Log.i("notification tapped", "message id is " + messageId);
final AppContext appContext= (AppContext)this.getApplicationContext();
if(!appContext.getAccount().name.equals(accountName))
{
final Account account= Iterables.find(appContext.getAccounts(), new AccountNameEquals(accountName), null);
if(account == null)
{
Toast.makeText(this, "Sorry, cannot find a message", Toast.LENGTH_SHORT);
return;
}
Log.i("notification tapped", "change account");
appContext.setAccount(account);
final Intent event= new Intent(Event.AccountChange.ACTION);
event.putExtra(Event.AccountChange.KEY_ACCOUNT, accountName);
LocalBroadcastManager.getInstance(appContext).sendBroadcastSync(event);
}
final Account account= appContext.getAccount();
if(!roomId.equals(appContext.getRoomId(account)))
{
Log.i("notification tapped", "change room");
appContext.setRoomId(account, roomId);
final Intent event= new Intent(Event.RoomChange.ACTION);
event.putExtra(Event.RoomChange.KEY_ROOM_ID, roomId);
LocalBroadcastManager.getInstance(appContext).sendBroadcastSync(event);
}
{
Log.i("notification tapped", "find a message");
final Intent event= new Intent(Event.FindMessage.ACTION);
event.putExtra(Event.FindMessage.KEY_MESSAGE_ID, messageId);
LocalBroadcastManager.getInstance(appContext).sendBroadcast(event);
}
}
public static final class SwipeSwitcher
extends FragmentStatePagerAdapter
{
public static final int POS_ROOM_LIST= 0;
public static final int POS_ROOM= 1;
public static final int NPAGES= 2;
public SwipeSwitcher(FragmentManager fm)
{
super(fm);
}
public Fragment getFragment(int position)
{
return this.getItem(position);
}
@Override
public Fragment getItem(int position)
{
if(this.fragments.containsKey(position))
{
return this.fragments.get(position);
}
switch(position)
{
case POS_ROOM_LIST:{
final Fragment fragment= new RoomListFragment();
this.fragments.put(position, fragment);
return fragment;
}
case POS_ROOM:{
final Fragment fragment= new RoomFragment();
this.fragments.put(position, fragment);
return fragment;
}
default:
throw new AssertionError();
}
}
@Override
public int getCount()
{
return NPAGES;
}
private final Map<Integer, Fragment> fragments= Maps.newHashMap();
}
private static final class AccountNameEquals
implements Predicate<Account>
{
public AccountNameEquals(CharSequence expects)
{
this.expects= expects.toString();
}
@Override
public boolean apply(Account input)
{
return this.expects.equals(input.name);
}
private final String expects;
}
private static final int MENU_ITEM_RELOAD= 1;
private static final int MENU_ITEM_PREFERENCE= 2;
private static final int MENU_ITEM_APP_INFO= 3;
private static final int MENU_ITEM_ACCOUNT= 4;
private static final int MENU_ITEM_PHOTO= 5;
private static final int REQUEST_CODE_TAKE_PHOTO= 1;
private static final int REQUEST_CODE_CHOOSE_PHOTO= 2;
private static final int REQUEST_CODE_GYAZO_UPLOAD= 3;
private Uri temporaryCameraStoreUri;
private List<BroadcastReceiver> receivers= Lists.newLinkedList();
}